3

我正在接管一个通过 ATL 公开组件的项目。

我看到单元测试的两个主要领域需要通过这个设置来覆盖:

  • 测试内部组件(可能会或可能不会通过 COM 公开)
  • 测试外部暴露组件(也称为测试暴露接口)

目前,该项目在解决方案中包含其所有内部组件单元测试。它们由一个预处理器标志启用,该标志编译它并在您运行时执行。

从我一直在做的研究来看,“规范”似乎是将单元测试放在不同的子项目中,并让单元测试的主要解决方案提供挂钩以访问内部组件。使用此设置,单元测试解决方案将设置对正在测试的解决方案的依赖关系。这真的是“规范”吗,还是有很多人将他们的单元测试框架放在正在测试的解决方案中(又名单元测试不是子项目,而是松散的 cpp,#ifdef如果未提供预处理器标志)?

目前使用的单元测试框架似乎是 cppunit,我正在考虑将其切换到 gtest 并尝试将所有内容移到不同的子项目中,但我想确保从长远来看,这些努力是值得的。

我想到的一种方法是__declspec对要测试的类进行测试,并且仅在指定预处理器定义时才公开它们。然后,单独的单元测试子项目将使该预处理器能够告诉主要解决方案公开内部。我只是不确定这是否是最好的路线。

所以我的问题是:

  1. 是否将单元测试放在单独的(子)项目中并从将要测试的源中公开组件(通过钩子,公开类定义等)?
  2. 从 COM DLL 公开内部组件的最佳方式是什么?
  3. __declspec允许测试内部组件的预处理器标志会是一个坏主意吗?有没有其他人在他们的单元测试中做到这一点,在正常操作期间被测试的项目通常不会暴露?

感谢您的评论!

4

3 回答 3

4

另一个团队的某个人说,他们的团队将所有单元测试放在单独的项目中,并且能够通过静态库公开内部。这对我来说很有意义,因为它有助于模块化并提供许多其他好处。因此,每个主要的代码耦合都将是一个静态库(不要太过分;))并且对于每个静态库,您将拥有一个单独的单元测试解决方案。然后你的主 DLL 变成了一个薄包装器,它暴露了必要的项目。

所以解决方案看起来像:

主要解决方案

  • ProjCommonLib
  • 项目导出库
  • ProjImportsLib
  • ProjOtherStuffLib
  • COMDLL 项目
  • 单元测试文件夹
    • ProjCommonLibTests
    • ProjExportsLibTests
    • ProjImportsLibTests
    • ProjOtherStuffLibTests
    • COMDLL-ProjTests

这种类型的设置允许单元测试设置对静态库的依赖关系,并可以完全访问内部,而无需处理 __declspec。这似乎更干净,因为 DLL 对模块化没有任何性能影响,因为其他库就是这样,静态库。

我将此作为“答案”,以查看它是否获得任何赞成票(又名,“这个答案是一个好方法,也是我所做的”)。如果这是一个糟糕的解决方案,请发布您的答案。

于 2011-09-13T13:32:59.837 回答
1

我想说您可以自由选择是将测试嵌入现有项目还是创建新项目。我在我的 cppunit 测试中选择了前一种方法,因为这意味着您不需要创建新项目,但是对于 C# 项目,我使用 Visual Studio 的单元测试框架来完成创建和维护单独项目的繁重工作。

我的 'ed 块没有重新编译,我从来没有遇到过任何问题#ifdef——依赖检查会看到这一点(如果你将它们暴露在一个单独的 dll 中然后使用导出,那么这将是一个问题。

我已经使用cppunit了很多年,而且我最近才使用gtest. 我想说的是,虽然 gtest 的功能非常丰富,但仍有相当多的结构差异使其移植成为一项艰巨的工作。如果现有测试在 cppunit 中,那么我建议继续这样做。

我喜欢 gtest 不支持的 cppunit 的一件事(据我所知)是夹具中的第一个故障会导致夹具失败,因此您可以这样做:

CPPUNIT_ASSERT(pointer!=NULL);
CPPUNIT_ASSERT(pointer->deferenceIt());  // if the pointer was null it would have returned above

gtest 将在此实例中继续运行并在第二行崩溃。如果 cppunit 测试依赖于这种行为,那么这将使其更难以移植。

于 2011-09-12T21:41:24.310 回答
0

使用#ifdef块可能不会触发重新编译,因此我相信将单元测试放在另一个项目中是一个更好的选择。

于 2011-09-12T15:36:30.737 回答