I'm starting with an existing, monolithic, .exe native Visual Studio 2012 project. I want to add a native Unit Test project alongside, according to http://msdn.microsoft.com/en-us/library/hh419385.aspx#objectRef, which suggests that this is supported:
The code under test is built as an .exe file: Add a separate test project. Link it to the output object file.
I dllexport
'ed the methods I needed to test, linked my test project with the exe project's .lib
library and things seemed to work for my simple test functions. However, as soon as I tried something more interesting I started getting access violations like this one:
First-chance exception at 0x04fa4aac (TestApplication.exe) in vstest.executionengine.x86.exe: 0xC0000005: Access violation reading location 0x011bf0e0.
So I created a new solution with the simplest .exe and Unity Test project pair I could muster and I was able to reproduce the exceptions with this caller (Unit Test project) and callee (.exe project):
Callee (.exe project) Header.h
:
#include <string>
__declspec( dllexport ) std::string __cdecl strTest( std::string j );
Callee (.exe project) Header.cpp
:
#include "Header.h"
std::string strTest( std::string j ) {
std::string output;
output += j;
output += "HAHA";
return output;
}
Caller (Unit Test project) unittest1.cpp
:
#include "CppUnitTest.h"
#include "../TestApplication/Header.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest {
TEST_CLASS(UnitTest1) {
public:
TEST_METHOD(TestMethod1) {
std::string test = strTest( "bla " );
}
};
}
The access violation always happens inside the std::string
constructor being called by the std::string output;
line in strTest()
.
I made sure that the two projects have identical settings (especially calling convention, optimization/debug settings, bit-ness, and character set). I also disabled and removed the pre-compiled headers for both projects.
I even tried creating a second exe project with the functions above and have my main exe project link against the second exe project. This worked perfectly. When I tried to have my Unit Test project link against that second exe project, in the same way I had my main exe project working, I got the same access violations again.
The only thing that worked was converting my exe project into a dll project (litterally just changing the Configuration Type of my exe project from Application (.exe)
to Dynamic Library (.dll)
).
So the question is, can I somehow get my exe project unit-testable using Visual Studio 2012's unit testing or should I just start splitting it up into dlls already?
Edit:
I submitted an issue on Microsoft Connect on this and was told that it is indeed a bug: https://connect.microsoft.com/VisualStudio/feedback/details/804696/linking-visual-studio-2012-c-unit-testing-project-against-an-exe-causes-access-violations
I've done some more tests using the same solution I attached on completely fresh installs of Windows 7 Pro x64 SP1 and Windows 8.1 Pro Preview x64 on VMware Workstation 9 virtual machines. Nothing but all Windows updates and the specific Visual Studio was installed for each test. I always reverted to a clean snapshot between tests. I also ran all Visual Studios with all-default settings.
On Windows 7, everything I tried gave me the same access violation. I tried my solution with:
- Visual Studio Express 2012 for Windows Desktop w/ Update 2
- Visual Studio Express 2012 for Windows Desktop w/ Update 3
- Visual Studio 2012 Ultimate w/ Update 3
- Visual Studio 2013 RC Professional
On Windows 8.1, with Visual Studio Express 2012 for Windows Desktop w/ Update 3 my Unit Tests all ran fine. I'm assuming the other combinations I tried on Windows 7 all work fine on 8.1.
Back on Windows 7, when I switched from x86 to the x64 platform and setting the Default Processor Architecture for the Test Settings to X64 the same test passed. I no longer got access violations.
So this is likely a (Windows 7/x86 platform)-specific problem.
Also, regarding the access violation, it's not always so graceful. I also sometimes get a "vstest.executionengine.x86.exe has stopped working" dialog box with these problem details:
Problem signature:
Problem Event Name: BEX
Application Name: vstest.executionengine.x86.exe
Application Version: 12.0.20827.3
Application Timestamp: 521cc637
Fault Module Name: StackHash_9321
Fault Module Version: 0.0.0.0
Fault Module Timestamp: 00000000
Exception Offset: 00ae9998
Exception Code: c0000005
Exception Data: 00000008
OS Version: 6.1.7601.2.1.0.256.1
Locale ID: 1033
Additional Information 1: 9321
Additional Information 2: 9321642ea520dd869526c054c7161ae9
Additional Information 3: bfae
Additional Information 4: bfaed60192419c1d7d34eac41dbe71a8