[英]Path of least resistance when unit testing C++ code in an exe, in Visual Studio 2012
I'm in need of some sage advice here. 我在这里需要一些圣人的建议。 Long story short, I'm rebuilding a - for me - relatively complex app comprised of about 7000 lines of code.
长话短说,我正在重建 - 对我来说 - 相对复杂的应用程序,包含大约7000行代码。 I ran into a number of issues when I created the first iteration of my application and it seems to me that test driven development might just be the ticket.
当我创建应用程序的第一次迭代时遇到了许多问题,在我看来,测试驱动的开发可能只是票证。
I was pleased to see that Visual Studio 2012 now natively supports TDD in C++, so I went ahead and read as much as I could. 我很高兴看到Visual Studio 2012现在原生支持C ++中的TDD,所以我继续尽可能多地阅读。 Unfortunately, Vs2012 is fairly new and I feel the documentation is somewhat lacking.
不幸的是,Vs2012相当新,我觉得文档有点缺乏。 But this is a little beside the point.
但这有点不合时宜。 I'm relying mainly on the following guide on the MSDN site:
我主要依赖于MSDN网站上的以下指南:
http://msdn.microsoft.com/en-us/library/hh419385.aspx#objectRef http://msdn.microsoft.com/en-us/library/hh419385.aspx#objectRef
It fairly clearly states that if the code under testing is to be built as an .exe, then the way forward is creating a separate test project and linking the output object file. 它相当清楚地表明,如果要测试的代码是作为.exe构建的,那么前进的方法是创建一个单独的测试项目并链接输出对象文件。 I'm guessing they mean the object files?
我猜他们的意思是对象文件? Or maybe not?
或者可能不是?
I'm honestly a little confused as to how many .obj's I need to link. 我真的有点困惑,我需要链接多少.obj。 At first I thought I needed to link every single obj file which is fairly tedious.
起初我以为我需要链接每个相当乏味的obj文件。
If anyone has experience doing this and could perhaps also recommend which macros or similar short cuts to use in order to make this process as painless as possible, I'd be much obliged! 如果有人有这方面的经验,也许还可以推荐使用哪些宏或类似的捷径,以使这个过程尽可能轻松,我会非常感激!
This will depend on how you have your solution structured. 这取决于您如何构建解决方案。 The way I like to structure my solutions is to have three projects.
我喜欢构建我的解决方案的方式是有三个项目。
main()
call main()
调用中的.lib With this structure you can use the Add New Reference...
button in the Common Properties
section and the references will be sorted for you (except the header include path found in C++\\General\\Additional include directories
). 使用此结构,您可以使用
Common Properties
部分中的Add New Reference...
按钮,并为您排序引用(除了在C++\\General\\Additional include directories
找到的头包含路径)。
If you do not want to restructure your projects you can tell the linker about each obj file ( Linker\\Input\\Additional dependencies
). 如果您不想重构项目,可以告诉链接器每个obj文件(
Linker\\Input\\Additional dependencies
)。 This may be a significant number of .obj files if you have a lot of classes that you want to test. 如果您要测试很多类,这可能是大量的.obj文件。 Unfortunately, you may have issues if you use pre-compiled headers.
不幸的是,如果您使用预编译的标头,则可能会出现问题。
I would suggest restructuring the projects if you can. 如果可以,我建议重组项目。
There's a nifty option when you use a project dependency, that lets you choose between linking the output file or having the IDE automatically select all the object files from the other project as dependencies. 当您使用项目依赖项时,有一个很好的选项,它允许您选择链接输出文件或让IDE自动选择其他项目中的所有目标文件作为依赖项。
(Don't worry about the .NET stuff in the screenshot, this was taken from an project where a C++/CLI DLL included a native static library project. Just do the same thing with a native test project including a native DLL or EXE project, choosing to link with the inputs.) (不要担心屏幕截图中的.NET内容,这是从C ++ / CLI DLL包含本机静态库项目的项目中获取的。只需对包含本机DLL或EXE项目的本机测试项目执行相同操作,选择与输入链接。)
: *** CollectObjLibFilenames.bat ***
dir /B *.obj > ObjLibFilenames.txt
dir /B *.lib >> ObjLibFilenames.txt
Microsoft says "If you use precompiled headers, LINK requires that all of the object files created with precompiled headers must be linked in."
微软称 “如果您使用预编译的头文件,LINK要求必须链接使用预编译头文件创建的所有目标文件。”
I thought there would be a name collision if I added the object file containing my application's entry point,main(int argc, char *argv)
, but my unit test projects link successfully with or without main.obj.我想如果我添加了包含我的应用程序入口点的对象文件
main(int argc, char *argv)
,那么会发生名称冲突,但我的单元测试项目成功链接有或没有main.obj。 I have not tried linking a file with other entry point flavors (WinMain, wWinMain, wmain).我没有尝试将文件与其他入口点风格(WinMain,wWinMain,wmain)链接。 If you have a name collision with one of those, you could aways change the name of your entry point (which would be weird): Properties, Linker, Advanced , edit the Entry point, and rename the Application's entry point function correspondingly.
如果你的名字与其中一个发生冲突,你就可以改变你的入口点的名字(这很奇怪): 属性,链接器,高级 ,编辑入口点,并相应地重命名应用程序的入口点功能。 The option is not specified in the unit test project I just looked at, which I assume means default, which almost surely is
main(int argc, char *argv)
.我刚才看到的单元测试项目中没有指定该选项,我认为这意味着默认,几乎肯定是
main(int argc, char *argv)
。
My main.cpp files have only one function (main) and no globals, ie no other part of the application refers to anything in main.cpp.我的main.cpp文件只有一个函数(main),没有全局变量,即应用程序的其他部分没有引用main.cpp中的任何内容。 I assume you can get away with omitting any object file if nothing in it is referenced by a linked file.
我假设你可以省略任何目标文件,如果链接文件中没有引用它。 Not worth the effort to figure out which satisfy that requirement for small applications.
不值得努力找出哪些满足小应用程序的要求。 For large applications...good luck with that;
对于大型应用程序......祝你好运; Eventually you'll want to test all your execution paths anyway.
最终你还是要测试所有的执行路径。
You will likely have a precompiled header object file, stdafx.obj file in the unit test project as well as the one in your application project.您可能在单元测试项目中有一个预编译的头目标文件stdafx.obj文件以及应用程序项目中的文件。 That will not be a problem, as the default object file names for the precompiled header files are $(TargetName).pch, where $(TargetName) resolves the project name.
这不会有问题,因为预编译头文件的默认对象文件名是$(TargetName).pch,其中$(TargetName)解析项目名称。 Ie, the pch object files will have different names.
即,pch对象文件将具有不同的名称。
Suggetion: Rather than copying the contents of my application's stdafx.h file into the corresponding unit test file, include the application's stdafx.h in the unit test project's stdafx.h file, so you don't have to update the unit test's version when the application's file changes.建议:不要将我的应用程序的stdafx.h文件的内容复制到相应的单元测试文件中,而是将应用程序的stdafx.h包含在单元测试项目的stdafx.h文件中,这样您就不必更新单元测试的版本了。应用程序的文件发生了变化。
#include <stdafx.h>
works, but I use the relative path between the two projects (if their relative paths are stable), or the full pathname of the application's source file if that's more stable, to be sure the right file is found.#include <stdafx.h>
有效,但是我使用两个项目之间的相对路径(如果它们的相对路径是稳定的),或者是应用程序源文件的完整路径名(如果它更稳定),以确保找到正确的文件。 See difference-between-include-hpp-and-include-hpp for an unsettling explanation about how #include"header.h" and #include are interpreted.请参阅include-hpp-and-include-hpp之间的差异,以获得有关如何解释#include“header.h”和#include的令人不安的解释。 Spoiler: it's another implementation specific feature of C++.
Spoiler:它是C ++的另一个特定于实现的功能。
__________________________________________________________________________________________________________________________________________________
As an aside, precompiled header files are specified on a per source file (.cpp) basis.另外,预编译头文件是基于每个源文件 (.cpp)指定的。 An individual .cpp file can use only one precompiled header file, but you can have more than one precompiled header file in the same project .
单个 .cpp文件只能使用一个预编译的头文件,但您可以在同一个项目中拥有多个预编译的头文件。 See this:
看到这个:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.