ExpectedException on TestMethod Visual Studio 2010 - unit-testing

Today I upgraded my solution with all the underlying projects from VS2008 to VS2010. Everything went well except for my unit tests.
First of all only the web projects had as target framework .NET 4. All the other projects still had .NET 3.5. I changed them all to .NET 4.
Now when I debug my unit tests it breaks on every exception. In 2008 it just wouldn't pass and tell me that an exception occurred. Even when I have the ExpectedException attribute defined it stops debugging on every exception.
And example of one of my tests:
[TestMethod]
[ExpectedException(typeof(EntityDoesNotExistException))]
public void ConstructorTest()
{
AddressType type = new AddressType(int.MaxValue);
}
The EntityDoesNotExistException is a custom exception and inherits Exception.
Edit
I looked at the Exceptions settings (ctrl+alt+e) in 2008 and 2010. In both versions the settings are the same. However in 2008 the debug doesn't break when I have the ExpectedException attribute. In 2010 it does break.

Gerrie pointed me in the right direction:
Press Ctrl-Alt-E
Open the Common Language Runtime Excepions Node
Click Add
Type Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException
Make sure that both checkboxes are unchecked.
This will get rid of the break on failed Asserts, but the test will still break when you have set an ExpectedException.
I was the one that set the 100 bonus for this, so some upvotes would be appreciated ;-)

According to Microsoft, this is not a bug, it's "by design":
http://connect.microsoft.com/VisualStudio/feedback/details/511897/expectedexception-still-causes-debugging-to-break-with-exception-was-unhandled-by-user-code

Press Ctrl+Alt+E and check the break on exception setting for CLR exceptions. If this is set to true then the behavior you described will occur.

A Microsoft support guy told me to use Ctrl-F5 (start without debugging) when running my unit tests, and that seems to work.
Another thing to try is to go to Tools|Options|Debugging
and un-check the "Enable Just My Code" option.

Make sure your reference to Microsoft.VisualStudio.QualityTools.UnitTestingFramework is Version 10.0.0.0.
If it is version 9.0.0.0 this problem will occur in Visual Studio 2010.
Hope this helps. If people still have this problem.

I second what rlandster said. Clearing the "Enable Just My Code" debugging option fixed this for me. It fixed both breaking on assers and breaking on expected exceptions. There's a little more detail on this at http://social.msdn.microsoft.com/Forums/en/vsdebug/thread/25bdf149-5133-4f47-bbf2-1d4ca638fee9.

I've had the same issue, but finally managed to get it working. Not really sure how but here's a list of things I did between it not working to when it started working again.
Converted the project being tested to .NET 4
Turned off CodeCoverage
Turned CodeCoverage back on again
Did a RebuildAll on the test project
Not sure which bit fixed it though. Anyway, hope this helps!

I ended up changing my tests to this form to avoid the breaking. Not ideal:
[TestMethod]
public void Guid()
{
try
{
Guid g = new Guid("myguid'123'");
}
catch( FormatException fe)
{
return; // expected exception - pass
}
Assert.Fail(); // exception not thrown - fail
}

Related

How can I catch an invalid fgetpos call as a C++ exception on Windows?

In Visual C++ 2008, I want to "catch" an exception generated as shown here:
try {
int foo = 20;
::fgetpos(0, (fpos_t*)&foo);
}
//...
Here are adjustments I've made to attempt a successful catch:
SEH is activated (/eha)
I've added a catch(...)
I've added a _set_se_translator vector.
I've added/adjusted to SEH syntax: __try / __except(EXCEPTION_EXECUTE_HANDLER)
In short, I've tried "everything in the book" and I still can't catch the exception. If I replace the call to ::fgetpos with int hey = foo / 0 then suddenly all of the above techniques work as expected. So the exception I'm dealing with from ::fgetpos is somehow "extra special."
Can someone explain why this ::fgetpos error seems uncatchable, and how to work around it?
update When executed in the VS IDE, the output window doesn't name an exception. All it says is this:
Microsoft Visual Studio C Runtime Library has detected a fatal error in MyProgram.exe.
Not very helpful. When I run the console app from the command line, I get a crash dialogue. The "problem details" section of the dialogue includes this information:
Problem Event Name: BEX
Exception Offset:0002fd30
Exception Code: c0000417
Exception Data: 00000000
Additional Information 1:69ad
Additional Information 2:69addfb19767b2221c8e3e7a5cd2f4ae
Additional Information 3:b1ff
Additional Information 4:b1ffca30cadddc78c19f19b6d150997f
Since the code in your dump corresponds to STATUS_INVALID_CRUNTIME_PARAMETER, try _set_invalid_parameter_handler
Most likely, the runtime catches it for you and issues a debug dialog without returning or propagating the exception- that is a CRT call and they may add whatever exception catching code in there they like. It's well within Visual Studio's rights to catch a hardware exception inside a library function, especially if you are running from within the IDE or in debug mode, then it is expected of the runtime.
Of course, when you divide by zero, then there is no library call here to write that extra catching code.

How to terminate a program when it crashes? (which should just fail a unit test instead of getting stuck forever)

Our unit tests fire off child processes, and sometimes these child processes crash. When this happens, a Windows Error Reporting dialog pops up, and the process stays alive until this is manually dismissed. This of course prevents the unit tests from ever terminating.
How can this be avoided?
Here's an example dialog in Win7 with the usual settings:
If I disable the AeDebug registry key, the JIT debugging option goes away:
If I disable checking for solutions (the only thing I seem to have control over via the control panel), it looks like this, but still appears and still stops the program from dying until the user presses something. WerAddExcludedApplication is documented to also have this effect.
A summary from the answers by jdehaan and Eric Brown, as well as this question (see also this question):
N.B. These solutions may affect other error reporting as well, e.g. failure to load a DLL or open a file.
Option 1: Disable globally
Works globally on the entire user account or machine, which can be both a benefit and a drawback.
Set [HKLM|HKCU]\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI to 1.
More info: WER settings.
Option 2: Disable for the application
Requires modification to the crashing program, described in documentation as best practice, unsuitable for a library function.
Call SetErrorMode: SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); (or with SEM_FAILCRITICALERRORS). More info: Disabling the program crash dialog (explains the odd arrangement of calls).
Option 2a: Disable for a function:
Requires modification to the crashing program, requires Windows 7/2008 R2 (desktop apps only) or higher, described in documenation as preferred to SetErrorMode, suitable for a thread-safe library function.
Call and reset SetThreadErrorMode:
DWORD OldThreadErrorMode = 0;
SetThreadErrorMode(SEM_FAILCRITICALERRORS,& OldThreadErrorMode);
…
SetThreadErrorMode (z_OldThreadErrorMode, NULL);
More info: not much available?
Option 3: Specify a handler
Requires modification to the crashing program.
Use SetUnhandledExceptionFilter to set your own structured exception handler that simply exits, probably with reporting and possibly an attempt at clean-up.
Option 4: Catch as an exception
Requires modification to the crashing program. For .NET applications only.
Wrap all code into a global try/catch block. Specify the HandleProcessCorruptedStateExceptionsAttribute and possibly also the SecurityCriticalAttribute on the method catching the exceptions. More info: Handling corrupted state exceptions
Note: this might not catch crashes caused by the Managed Debugging Assistants; if so, these also need to be disabled in the application.
Option 5: Stop the reporting process
Works globally on the entire user account, but only for a controlled duration.
Kill the Windows Error Reporting process whenever it shows up:
var werKiller = new Thread(() =>
{
while (true)
{
foreach (var proc in Process.GetProcessesByName("WerFault"))
proc.Kill();
Thread.Sleep(3000);
}
});
werKiller.IsBackground = true;
werKiller.Start();
This is still not completely bullet-proof though, because a console application may crash via a different error message, apparently displayed by an internal function called NtRaiseHardError:
The only solution is to catch all exceptions at a very high level (for each thread) and terminate the application properly (or perform another action).
This is the only way to prevent the exception from escaping your app and activating WER.
Addition:
If the exception is something you do not except to happen you can use an AssertNoThrow(NUnit) or alike in another Unit Test framework to enclose the code firing the child processes. This way you would also get it into your Unit test report. This is in my opinion the cleanest possible solution I can think of.
Addition2:
As the comments below show, I was mistaken: you cannot always catch the asynchronous exceptions, it depends on what the environment allows. In .NET some exceptions are prevented from being caught, what makes my idea worthless in this case...
For .NET: There are complicated workarounds involving the use of AppDomains, leading to an unload of an AppDomain instead of a crash of the whole application. Too bad...
http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx
http://www.develop.com/media/pdfs/developments_archive/AppDomains.pdf
EDIT:
I finally got it. With .NET 4.0 You can add the HandleProcessCorruptedStateExceptions attribute from System.Runtime.ExceptionServices to the method containing the try/catch block. This really worked! Maybe not recommended but works.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.ExceptionServices;
namespace ExceptionCatching
{
public class Test
{
public void StackOverflow()
{
StackOverflow();
}
public void CustomException()
{
throw new Exception();
}
public unsafe void AccessViolation()
{
byte b = *(byte*)(8762765876);
}
}
class Program
{
[HandleProcessCorruptedStateExceptions]
static void Main(string[] args)
{
Test test = new Test();
try {
//test.StackOverflow();
test.AccessViolation();
//test.CustomException();
}
catch
{
Console.WriteLine("Caught.");
}
Console.WriteLine("End of program");
}
}
}
Try setting
HKCU\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI
to 1. (You can also set the same key in HKLM, but you need admin privs to do that.)
This should prevent WER from showing any UI.

Weird .net 4.0 exception when running unit tests

I am receiving the following exception when trying to run my unit tests using .net 4.0 under VS2010 with moq 3.1.
Attempt by security transparent method
'SPPD.Backend.DataAccess.Test.Specs_for_Core.When_using_base.Can_create_mapper()'
to access security critical method
'Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(System.Object)'
failed.
Assembly
'SPPD.Backend.DataAccess.Test,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' is marked with
the
AllowPartiallyTrustedCallersAttribute,
and uses the level 2 security
transparency model. Level 2
transparency causes all methods in
AllowPartiallyTrustedCallers
assemblies to become security
transparent by default, which may be
the cause of this exception.
The test I am running is really straight forward and looks something like the following:
[TestMethod]
public void Can_create_mapper()
{
this.SetupTest();
var mockMapper = new Moq.Mock<IMapper>().Object;
this._Resolver.Setup(x => x.Resolve<IMapper>()).Returns(mockMapper).Verifiable();
var testBaseDa = new TestBaseDa();
var result = testBaseDa.TestCreateMapper<IMapper>();
Assert.IsNotNull(result); //<<< THROWS EXCEPTION HERE
Assert.AreSame(mockMapper, result);
this._Resolver.Verify();
}
I have no idea what this means and I have been looking around and have found very little on the topic. The closest reference I have found is this http://dotnetzip.codeplex.com/Thread/View.aspx?ThreadId=80274 but its not very clear on what they did to fix it...
Anyone got any ideas??
In the AssemblyInfo.cs of the referenced project add this following line
[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]
MSDN: "The .NET Framework version 4 introduces new security rules that affect the behavior of the AllowPartiallyTrustedCallersAttribute attribute (see Security-Transparent Code, Level 2). In the .NET Framework 4, all code defaults to security-transparent, that is, partially trusted. However, you can annotate individual types and members to assign them other transparency attributes."
Haven't come across this myself, but perhaps you have imported somehing from a 3.5 project.
Check out these links:
Security Changes in the .NET Framework 4
Security-Transparent Code, Level 2
AllowPartiallyTrustedCallersAttribute Class
This has been fixed in the latest version of Moq (it was a fix in DynamicProxy actually).
Please give the latest v4 Beta a try.
http://moq.me

All tests fail, Unable to get type, and FileNotFoundException if certain line of code in one test after adding fmod Visual C++ test

I've figured out what caused the problem but I still don't know why - it happened when I started using fmod, and it must have something to do with how the linker decides to bring in and execute static libraries and .dll's. My code under test is a static lib; it refers to fmodex_vc, another static lib, which at some point (though I know not when) decides to load in its fmodex.dll. (Which is in the same directory as everything else, so I don't know why it wouldn't find it.) As far as I know, the code under test absolutely does not call the fmod initialization functions, but maybe fmod has some static global initializers that initialize themselves and load in the dll? And that code only gets pulled in if code in a module that uses it gets...used?
I'm testing unmanaged C++ code using the Visual Studio test framework and when I started using fmod it stopped working: Every test, even "test" tests that do nothing, would report (wrapped for readability):
Unable to get type SlidersTest.UnitTest1, SlidersTest.
Error: System.IO.FileNotFoundException:
The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
After a lot of trial and error, excluding .cpp files and re-adding them, I discovered that only one of the test files elicits the problem; and it only does if this line is called:
EntityMgr::Init();
Interestingly, all the tests start failing with that message if that line is in the code. EntityMgr::Init() is a function that does very little:
EntityMgr* EntityMgr::instG = null;
and
void EntityMgr::Init()
{
instG = new EntityMgr;
}
and
class EntityMgr
{
private:
static EntityMgr* instG;
public:
EntityMgr() // does nothing beyond the default
{
}
static void Init();
static EntityMgr* Inst() { return instG; }
...
vector<Entity> entitiesG;
};
Entity, FWIW, is a pretty vanilla class with no pointers, just various floats for its fields.
No matter how I run the tests (from test view, run selected, run all, run from the command line, from the test menu) I get the error.
Attempting to step into the test with the debugger fails - the test fails before the debugger gets to step in. Setting the debugger to break on System exceptions did nothing as well.
The code under test is a static .lib. CLR support is /clr.
Oh, and this just in: if I call a static Entity member function, same deal. If I move said static function outside of the class, same deal. But, if I move that function to another module, it's fine.
If I set the debugger to break on any exception, I do get something interesting:
First-chance exception at 0x7c812aeb in vstesthost.exe: Microsoft C++ exception: HRException at memory location 0x05129890..
There's no source code at that location, of course. Here's the call stack:
kernel32.dll!7c812aeb()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
kernel32.dll!7c812aeb()
[External Code]
msvcr80.dll!78158ed7()
msvcr80.dll!78158e34()
msvcr80.dll!78158047()
msvcr80.dll!7815850e()
msvcr80.dll!78158872()
msvcr80.dll!78158a57()
msvcr80.dll!78158b11()
ntdll.dll!7c9032a8()
ntdll.dll!7c90327a()
ntdll.dll!7c92a9ef()
ntdll.dll!7c90e46a()
kernel32.dll!7c812aeb()
kernel32.dll!7c812aeb()
kernel32.dll!7c812aeb()
msvcr80.dll!78139c4d()
msvcr80.dll!781323ff()
msctf.dll!74755764()
msctf.dll!74721557()
ws2_32.dll!71ab12bb()
ntdll.dll!7c90118a()
ntdll.dll!7c91b084()
ntdll.dll!7c90de7c()
ntdll.dll!7c90d04c()
ntdll.dll!7c90e43f()
kernel32.dll!7c80b713()
And here's the stack trace that mstest reports - I don't get anything useful out of it.
Unable to get type SlidersTest.game_EntityMgr_test, SlidersTest. Error: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.GetType(UnitTestElement unitTest, String type)
at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.ResolveMethods().
Why is fmod doing this?
I suggest running your application under Dependency Walker's Profile mode (http://www.dependencywalker.com/). It can record all attempts to load DLLs and EXEs, along with the resulting error codes - it sounds likely that the File not Found error is coming from an indirect dependency - perhaps being pulled in from linking FMod.
If this is the case, profiling your application with Dependency Walker will show one or more failed attempts to load a library. One of them will be the one responsible for the error.
Maybe some property was modified for that file? Probably already looked at this, but make sure that all the settings are from "Inherit from parent" in Visual Studio.
Jay
My best guess, from what you've posted so-far is that the exception is being thrown somewhere inside the CLR type loader — it looks like an assembly that you're indirectly dependent on either isn't in the GAC, or isn't being copied to the test directory.
Is there an actual stack trace in the test results? That might help narrow down what type(s) its trying to load.
Since you say that this started happening all of a sudden, I assume that tests with this line of code were working just fine previously. This may be a radical choice, but in the absence of another solution, perhaps you would consider reinstalling visual studio (a long procedure to be sure)
Can you set Visual Studio to break on all exceptions, regardless of where they come from during debugging?
It sounds as if cosmic rays or a faulty hard drive have caused a test .dll to become corrupt, or the dll you're building is corrupt (consistently). Before re-installing all of Visual Studio, you may want to ask it to do a repair, which should check for inconsistencies between your current install and what's on your installation medium.
How is the FMod .dll getting into your test directory? Do you have it set up to copy it to wherever mstest wants the test to occur? Note that "Copy to Output Directory" doesn't actually accomplish this. There's some other method, though I can't remember quite what it is.
I'd run it in a debugger and check the run output - in particular the "loading path\fmodex.dll" line to see if it's loading the right dll.
I've seen similar errors when mixing dlls from different configurations.

C++, OLE, Excel Automation: EAccessviolation at 00000800

I am writing an background service application that has to automatically read data from Excel 2003 files. But no matter what I try, the method OlePropertyGet() always results in an EAccessViolation error while trying to read from address "00000800".
The error always occurs at the last line of this code snippet, and seems independent of what parameter the method receives:
Variant excel, workbooks;
try
{
excel = GetActiveOleObject("Excel.Application");
}
catch(...)
{
excel = CreateOleObject("Excel.Application");
}
workbooks = excel.OlePropertyGet("Workbooks");
I've done some extensive google search on this, but found nothing that's even remotely helpful, only this forum thread where someone has the same issue, but doesn't give any information about the cause or solution (it's somewhat funny that at one point the author mentions he knows the cause, but doesn't say what it is!).
I'm open to any ideas as to what is causing this and how to solve this problem, but also alternative approaches to Excel OLE automation.
My guess is its a null pointer issue..
It looks like neither GetActiveOleObject() nor CreateOleObject() worked.
Try checkign the validity of 'excel' before calling OlePropertyGet.
And I guess you should make sure you have Excel installed.
You can use Visual Studio Tools for Office (see http://msdn.microsoft.com/en-us/library/d2tx7z6d.aspx).
Or you can use ATL support to instantiate the object model provided by office.
Your code may not be able to resolve "Excel.Application" successfully, leading to a null pointer. It uses a registry lookup with that string to identify Excel. It sounds like you're missing that registry entry.
I use such code to determine validity of created objects(in C++ Builder):
Varaint excel = GetActiveOleObject("Excel.Application");
TAutoDriver<IDispatch> dispatcher;
dispatcher.Bind(excel, false);
if (dispatcher.IsBound())
{
Variant workbooks = excel.OlePropertyGet("Workbooks");
}