Visual C++ TDD 设置
我以前很少使用 Visual Studio。 我在业余时间开始了一个个人项目,我想使用测试驱动开发,因为它对我的 Java 开发有巨大的好处。 我很早之前就开始了这个项目,并且使用了 CppUnit。 我知道可能还有其他更好的框架,但这是已经存在的框架。
我的 Visual Stuido 2005 解决方案中有 2 个项目。 当单元测试与应用程序代码一起驻留时,它工作得很好。 随着项目规模的扩大,这变得相当麻烦且不优雅。 我在我的解决方案下创建了一个新项目来容纳单元测试(所以它现在有 3 个项目)。 一切都很顺利,直到我尝试构建解决方案。 一切都已编译,但单元测试项目无法链接。 对于我的测试调用的每个函数,输出给出了 51 个“未解析的外部符号”错误 (LNK2019)。
据我推断,问题出在 Visual Studio 创建的目录结构上。 每个项目都有自己的目录,下面是创建的目标文件和可执行文件。 我认为问题在于,虽然头文件正确包含在每个单元测试中,但链接器无法找到 cpp 文件,因为它们位于不同的目录中。 当它找不到被调用函数的实现时,它会给出 2019 错误。
我对问题的评估正确吗? 我该如何修复它? 我是否需要完全重新组织我的项目,或者只是链接器的简单配置?
谢谢
I haven't worked much with Visual Studio before. I've started a personal project in my spare time and I would like to use test-driven development since it has been a huge benefit to me in my Java development. I started this project quite a while ago, and I used CppUnit. I know there are probably other frameworks that are better, but this is what's already in place.
My Visual Stuido 2005 solution has 2 projects in it. It worked fine when the unit tests resided right alongside the application code. As the project grew in size, this became quite cumbersome and inelegant. I created a new project under my solution to house the unit tests (so it now has 3 projects). Everything went fine until I tried to build the solution. Everything compiled, but the unit test project failed to link. The output gives me 51 "unresolved external symbol" errors (LNK2019) for what seems like every function that my tests call.
As far as I can deduce, the problem is the directory structure that Visual Studio creates. Each project gets its own directory, and then below that are the object files and executables that get created. I think the problem is that, while the header files are properly included in each unit test, the linker can't find the cpp files because they are in a different directory. When it fails to find the implementation of a called function, it gives me the 2019 error.
Am I right in my evaluation of the problem? How can I fix it? Do I need to completely reorganize my projects or is it a simple configuration of the linker?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,你的评价听起来不错。 试试这个:在解决方案资源管理器中,右键单击包含测试的项目名称,然后选择“项目依赖项”。 检查它所依赖的每个项目。 这应该设置链接器设置,以便它可以自动找到正确的文件。
Yes, your evaluation sounds pretty good. Try this: In the solution explorer, right click the name of the project that contains your tests and choose "Project Dependencies". Put a check by every project that it is dependent on. That should set up the linker settings so it automatically can find the correct files.
听起来您的测试项目在主项目中使用的函数/类未导出。 如果未导出代码,则代码所在的 DLL/exe 之外的任何内容都无法引用它。
我们处理这个问题的常见方法是向项目添加一个定义(在项目设置中,转到配置属性 -> C/C++ -> 预处理器,第一行有定义),名为
PROJECTNAME_IMPL
(确保对调试和发布配置都执行此操作!)。 然后有一个任何导出的内容都包含的头文件(称为ProjectNameExport.h),其中包含类似以下内容:然后,在定义类时(例如):
这就是当头文件包含在中时导出类的结果项目中的文件,并在头文件包含在另一个项目(当然链接到第一个项目)的文件中时导入该类。
It sounds like the functions/classes that your test project is using from your main projects aren't exported. If code isn't exported, then nothing outside of the DLL/exe that the code lives in can reference it.
A common way that we handle this is to add a define to the project (in the project settings, go to Configuration Properties -> C/C++ -> Preprocessor, the first line has the defines) called something like
PROJECTNAME_IMPL
(make sure you do this for both Debug and Release configurations!). Then there is a header file (called ProjectNameExport.h) that anything exported includes, which contains something like the following:Then, when defining a class (for example):
This has the result of exporting the class when the header file is included in a file within the project, and importing the class when the header file is included in a file in another project (that links to the first project, of course).
我总是将要测试的代码添加到单独的静态 .lib 文件中,并让主应用程序 EXE 和单元测试 EXE 依赖于此。 新代码添加到.lib项目中,并且依赖项支持确保EXE链接没有错误。 您需要确保 EXE 项目可以找到 .lib 标头,但这取决于您的目录结构。 您还必须注意 .lib 和 EXE 使用相同的 CRT/MFC 库(例如,在使用 CRT 时,您可以与其静态链接或使用 DLL)。
我发现以这种方式使用库比向多个项目添加文件/标头更容易维护。
我正在使用 Boost 测试框架,但无论 TDD 框架如何,我都会以相同的方式构建它。
关于类似设置的好文章可以在这里找到:
http://www.codeproject。 com/KB/architecture/Designing_Robust_Objects.aspx
I always add the code to be tested to a separate static .lib file, and have the main application EXE and unit tests EXE depend on this. New code is added the .lib project, and the dependency support ensure the EXEs link with no errors. You need to make sure the EXE projects can find the .lib headers, but this will depend on your directory structure. You also have to watch that that the .lib and the EXEs are using the same CRT/MFC library (for example, when using the CRT you can statically link with it or use a DLL).
I find using libs in this way easier to maintain than adding files/headers to multiple projects.
I am using the Boost test framework but I would structure this the same no matter the TDD framework.
A good article on a similar setup can be found here:
http://www.codeproject.com/KB/architecture/Designing_Robust_Objects.aspx