使用CppUnit
下载地址:http://downloads.sourceforge.net/cppunit/cppunit-1.12.1.tar.gz
版本: 1.12.1
编译
下载后解压,打开 src/CppUnitLibraries.dsw,使用VS2010打开,默认转换dsw为sln。然后编译,我编译的为debug版本,解决的几个编译错误如下:
1. 在linker\general\output file中, 生成文件的名字为不带“d”的名字,在post-build中,会copy错误。修改办法:
(1)General\TargetName中,$(ProjectName)-->$(ProjectName)d,而cppunit_dll工程比较特殊,它需要在cppunitd_dll中间加"d",没办法使用$(ProjectName),可直接写为cppunitd_dll
(2)Linker\General\Output Files中,DebugDll\cppunit_dll.dll-->DebugDll\$(TargetName)$(TargetExt)
(3)Linker\Advanced\Import Libraries中,.\DebugDll\cppunit_dll.lib-->.\DebugDll\$(TargetName).lib
(4)PostBuild Event\Command Line中:改为:
copy "$(TargetPath)" ..\..\lib\$(TargetName)$(TargetExt)
copy "$(TargetDir)$(TargetName).lib" ..\..\lib\$(TargetName).lib
即将dll和lib文件拷贝到上层目录lib中。
2. 遇见error LNK2001: unresolved external symbol __DllMainCRTStartup@12错误,修改办法为:
Linker\Input\Additional Dependencies,Debug:加入msvcrtd.lib; Release:加入msvcrt.lib
3. #import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("7.0") lcid("0") raw_interfaces_only named_guids错误,将其修改为:
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("8.0") lcid("0") raw_interfaces_only named_guids。
这样将会从%common_files%\MicrosoftShared\MSEnv\dte80a.olb导入dte80a.olb。
这样可编译通过,生成文件自动拷贝到上级目录的lib下,一共7个文件。
4. 使用VS2013编译的话,会出现下面的错误:
“error MSB8031: Use of MBCS encoding in MFC projects require an additional library to be downloaded and installed. Please see http://go.microsoft.com/fwlink/?LinkId=286820 for more information. C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\v120\Microsoft.CppBuild.targets
”
原因是自VS2013开始,移除了MBCS MFC包。需要自行下载。下载(http://www.microsoft.com/en-us/download/details.aspx?id=40770)安装完成后,即可消除此错误。
可以参考【5】了解具体解释。
工程
* cppunit (cppunit.lib) : unit testing framework library, the one you use to write unit tests.
* cppunit_dll(cppunit_dll.dll/lib) : same as above, but build as a DLL. CppUnit的框架类库是cppunit工程和cppunit_dll,是1份代码对应2个工程,2种不同的使用方法:static library和dynamic library.如果确定使用cppunit工程的活,cppunit_dll工程就可以删掉了。
* DllPlugInTester(DllPlugInTester.exe) : test plug-in runner executable. Use this to test DLL in your post-build step, or debug them. 在测试工程的post-build中测试DLL的一个工具,如Example下的simple_plugin工程:DllPlugInTesterd.exe simple_plugind.dll。这个工程也可以删掉
* TestRunner (testrunner.dll) : a MFC extension DLL to run and browser unit tests from a GUI. 一个MFC扩展DLL,生成界面程序,是必须的。
* DSPlugIn (lib/TestRunnerDSPlugIn.dll) : a VC++ 6.0 add-in used by testrunner.dll. If you double-click on a failure in the MFC TestRunner, a running instance of VC++ will open the file and highlight the line. This add-ins is not required for Visual Studio 7. 仅提供给VC6.0使用的,使用VS2010可将该工程删掉。
* TestPlugInRunner : (Warning: experimental) a VC++ application to run test plug-in. A test plug-in is a DLL that publish a specified interface. This application is still incomplete (the auto-reload feature is missing).该工程还不完善。
可见,只有cppunit和TestRunner2个工程是必须的。
Examples:
* CppUnitTestMain : the actual test suite use to test CppUnit. Use a TextTestRunner, and post-build testing with CompilterOutputter. Configuration to link against cppunit static library and cppunit dll library.
* CppUnitTestApp : contains the same test suite as CppUnitTestMain, but run them using the MFC TestRunner.
* hierarchy : a sample demonstrating how to sublcass test (you might rather want to use HelperMacros.h and the CPPUNIT_TEST_SUB_SUITE macro which does it in a 'cleaner' way. That sample has not been updated for a long time).
* HostApp : a sample using the MFC TestRunner demonstrating different test failure. Also demonstrates the MFC Unicode TestRunner.
* Money : an example that come along with the Money article of the documentation. Probably what you want to look at if you are a newbie.
打开 examples/Examples.dsw,Examples.dsw包含了所有的工程,包括cppunit,cppunit_dll,TestRunner等,转换的时候,会提示是否覆盖,注意不要覆盖,否则会把上面步骤修改好的工程设置覆盖掉。
编译,需修改的地方包括:
1. simple_plugin和money工程
(1)General\Target Name修改为$(ProjectName)d。
(2)Linker\Output File,DebugPlugIn/simple_plugind.dll-->DebugPlugIn/$(TargetName)$(TargetExt)
(3)Linker\Advanced\Import Libraries中,.\DebugPlugIn\simple_plugind.lib-->.\DebugPlugIn\$(TargetName).lib
(4)post-build,将..\..\lib\DllPlugInTester_dlld.exe改为..\..\lib\DllPlugInTesterd.exe。因为DllPlugInTester工程生成的文件名字被改为了DllPlugInTesterd.exe
(5)另外,..\..\lib\DllPlugInTesterd.exe -b --xml tests.xml -c "$(TargetPath)"始终编译不过,最后将其删掉。
2. DllPlugInTesterTest工程
编译时会出现如下的错误:
1> Updating E:\GitHub\ZhchnchnCodes\Cpp\CppUnit\lib\cppunitd_dll.dll 1> 1 file(s) copied. 1> Updating E:\GitHub\ZhchnchnCodes\Cpp\CppUnit\lib\cppunit_dll.dll 1> The system cannot find the file specified. 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(170,5): error MSB6006: "cmd.exe" exited with code 1.
(1)打开编译时详细verbose信息:VS2013菜单->Tools->Options->Project and Solutions->Build and Run->MSBuild project build output verbosity: 选择Detailed.
(2)再次编译DllPlugInTesterTest工程,发现如下的详细编译信息:
1> ..\..\lib\cppunit_dll.dll will be compiled as it was not found in the tracking log. 1> ..\..\lib\cppunitd_dll.dll will be compiled as not all outputs are available. 1> copy E:\GitHub\ZhchnchnCodes\Cpp\CppUnit\lib\cppunitd_dll.dll .\DebugTest\cppunitd_dll.dll 1> copy E:\GitHub\ZhchnchnCodes\Cpp\CppUnit\lib\cppunit_dll.dll .\DebugTest\cppunit_dll.dll 1> Updating E:\GitHub\ZhchnchnCodes\Cpp\CppUnit\lib\cppunitd_dll.dll 1> 1 file(s) copied. 1> Updating E:\GitHub\ZhchnchnCodes\Cpp\CppUnit\lib\cppunit_dll.dll 1> The system cannot find the file specified. 1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(170,5): error MSB6006: "cmd.exe" exited with code 1. 1>Done executing task "CustomBuild" -- FAILED. 1>Done building target "CustomBuild" in project "DllPlugInTesterTest.vcxproj" -- FAILED.
可以发现该工程在拷贝cppunit_dll.dll时出现了错误,原因是我们并没有编译Release版本,因此没有cppunit_dll.dll文件,因此“The system cannot find the file specified”。
(3)使用Notepad++打开DllPlugInTesterTest.vcxproj文件,搜索“cppunit_dll.dll”文件,可以发现下面的设置:
<ItemGroup> <CustomBuild Include="..\..\lib\cppunit_dll.dll"> <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy %(FullPath) $(IntDir)%(Filename).dll</Command> <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Updating %(FullPath)</Message> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\$(InputName).dll;%(Outputs)</Outputs> <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy %(FullPath) $(IntDir)%(Filename).dll</Command> --(a) <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Updating %(FullPath)</Message> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\$(InputName).dll;%(Outputs)</Outputs> </CustomBuild> <CustomBuild Include="..\..\lib\cppunitd_dll.dll"> <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy %(FullPath) $(IntDir)%(Filename).dll</Command> --(c) <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Updating %(FullPath)</Message> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\$(InputName).dll;%(Outputs)</Outputs> <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy %(FullPath) $(IntDir)%(Filename).dll</Command> --(b) <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Updating %(FullPath)</Message> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\$(InputName).dll;%(Outputs)</Outputs> </CustomBuild> </ItemGroup>
由于我们编译的是Debug版本,所以会执行(a)(b)两处的设置。由于“cppunit_dll.dll”根本不会用于Debug,所以(a)处的设置会导致错误。同理,如果编译Release版本,(c)处也会出错。
可以将不必要的设置删除。
<ItemGroup> <CustomBuild Include="..\..\lib\cppunit_dll.dll"> <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy %(FullPath) $(IntDir)%(Filename).dll</Command> <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Updating %(FullPath)</Message> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\$(InputName).dll;%(Outputs)</Outputs> </CustomBuild> <CustomBuild Include="..\..\lib\cppunitd_dll.dll"> <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy %(FullPath) $(IntDir)%(Filename).dll</Command> <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Updating %(FullPath)</Message> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\$(InputName).dll;%(Outputs)</Outputs> </CustomBuild> </ItemGroup>
使用
1. 把cppunit-1.12.1\include加到目的工程的包含文件,cppunit-1.12.1\lib加到目的工程的库文件,cppunit-1.12.1\lib想加到环境变量里也行,那样不用拷贝cppunit.lib文件。否则需要将cppunit.lib考到目的工程的目录。
参考
【3】如何使用CppUnit进行单元测试(http://www.vckbase.com/index.php/wv/1465)
【4】开放源码 C/C++ 单元测试工具,第 2 部分: 了解 CppUnit(http://www.ibm.com/developerworks/cn/aix/library/au-ctools2_cppunit/?ca=drs-tp4608#resources)
【5】 Visual Studio unable to recognise my MFC library for my webcam laser rangefinder code(http://stackoverflow.com/questions/21360411/visual-studio-unable-to-recognise-my-mfc-library-for-my-webcam-laser-rangefinder)