如何对C ++ / WinRT组件进行单元测试?最好具有代码覆盖率

时间:2019-02-14 23:15:19

标签: visual-c++ visual-studio-2017 c++-winrt

我正在编写一些新的基于C ++ / WinRT的组件,以替换一些较旧的C ++ / CX代码。目标是能够使用不了解CX的第三方C ++工具(静态代码分析器等)。

但是,旅程的第一步是确保我可以正确地对自己的代码进行单元测试。单元测试C ++ / CX代码通常使用“ C ++单元测试应用”项目类型,该项目类型基于C ++ / CX,并且有其自身的问题(缺少代码覆盖支持,在测试显示在资源管理器中之前运行所有必需的功能,稳定性等)。 )

浏览Visual Studio 2017中的可用项目类型,我没有看到基于C ++ / WinRT的项目的单元测试项目模板。我唯一的选择是使用“ C ++单元测试应用程序”模板来解决所有失败,还是有另一种方法来构建C ++ / WinRT库的测试?

也许有一种方法可以配置“本机测试项目”或“ Google测试”项目模板来支持我正在寻找的内容?

理想情况下,我正在寻找不需要启动UI的东西,它是纯C ++(/ WinRT),并且支持Visual Studio的代码覆盖率分析。

2 个答案:

答案 0 :(得分:1)

没有专门针对C ++ / WinRT的单元测试项目,就像没有其他库(如STL)那样。我推荐Catch2,因为它支持C ++ 17(C ++ / WinRT的要求)并且在Windows上可以很好地工作。这也是我们用于测试C ++ / WinRT本身的工具。 Catch2很不错,因为它可以帮助您创建一个简单的控制台应用程序,充当包含所有测试的测试驱动程序。

对于代码覆盖率,我没有强烈建议,但是如果您使用的是Visual Studio,则可能需要尝试VSInstr。它可以用于代码覆盖,并生成可以使用Visual Studio查看的报告。

确保使用/ profile链接器选项构建代码。这将确保概要文件挂钩包含在PE文件的专用部分中。接下来,运行vsinstr来检测您感兴趣的任何二进制文件(这些二进制文件以前是用/ profile构建的):

vsinstr /coverage tests.exe

现在运行vsperfcmd以开始收集覆盖率数据:

vsperfcmd /start:coverage /output:report

正常运行代码。对于Catch2,您只需在命令行中运行可执行文件即可。然后,您需要按以下步骤停止收集:

vsperfcmd /shutdown

您已完成。现在,您可以在Visual Studio中查看报告:

devenv report.coverage

希望有帮助。同样,这不是特定于C ++ / WinRT的,并且由于C ++ / WinRT是仅标头的库,因此您可能会得到很多与您的特定项目无关的噪音。我还没有找到解决这个问题的好方法。

答案 1 :(得分:0)

将我对@KennyKerr答案的评论扩展到那些有兴趣的人...

如果您打算按照建议使用Catch2,则C ++ / WinRT Windows控制台应用程序模板是一个很好的起点。您要做的几乎只是调整main()来设置Catch2并开始编写测试用例。我唯一的抱怨是C ++ / WinRT模板不允许您通过UI添加Windows运行时组件项目引用(必须通过编辑vcxproj来完成)。添加NuGet包引用可能存在类似的问题。

正如我在上面的评论中指出的那样,市场上有一个用于Visual Studio 2017/2019的Catch2测试适配器。请注意,它需要一个.runsettings文件来启用适配器并告诉它哪些项目是Catch2测试应用程序(通过正则表达式)。没有正确配置的运行设置,它将找不到您的测试。我还必须增加发现超时,否则有时会“忘记”我的测试。

关于代码覆盖率,使用Visual Studio时,您可以配置代码覆盖率以在.runsettings文件中包含/排除函数。有关详情,请参见Microsoft's Site。对于我自己,我在CodeCoverage部分中添加了以下内容,到目前为止,效果很好:

<Functions>
  <Include>
    <Function>.*YourNamespaceHere.*</Function>
  </Include>
  <Exclude>
    <Function>winrt.*GetRuntimeClassName</Function>
    <Function>winrt::impl.*</Function>
    <Function>winrt::(?!YourNamespaceHere).*</Function>
  </Exclude>
</Functions>

对于那些尝试像我一样测试C ++ / WinRT Windows运行时组件的人,并且具有未作为WRC界面的一部分公开的代码,这是我为使该可测试性所做的工作...

  1. 创建一个C ++共享项目项目
  2. 将Windows运行时组件(WRC)项目的所有代码移到共享项目项目中,然后移出WRC项目。今后,只能从共享项目中添加/删除文件。这样,添加/删除文件时,您无需触摸WRC或Test项目。
  3. 在您的原始WRC项目和测试项目中都添加对此共享项目的引用
  4. 确保您的测试项目和WRC项目在编译设置和项目/ NuGet参考方面的配置均相似
  5. 编辑测试项目,并确保RootNamespace的配置与WRC项目相同(可能必须通过您喜欢的编辑器完成)。这是必需的,否则生成的标头将以名称空间作为前缀,因此共享代码将找不到该标头。
  6. (代码覆盖率可选)在测试项目中,启用分析(链接器>高级>配置文件>是)

您现在应该能够编写行使私有代码的测试。至于这是否是最好的方法,我留给读者看。它对我有用,并且我正在测试的代码非常简单,以至于我不必过度担心项目定义不能完美匹配。您的里程可能会有所不同。

我将注意到上面的内容也可以用于使“本机测试项目”与C ++ / WinRT一起使用,您只需要执行将C ++ / WinRT位首先集成到测试项目中的额外步骤即可。