如何使用CMake和Microsoft单元测试框架运行.dll测试套件



在一个CMake项目中,我根据以下生成了一个C++/CLI项目和一个测试SHARED库

CMake用于集成的Microsoft单元测试框架(VS2017(

我正在尝试运行测试,但Visual StudioVisual Studio Code都无法发现我的测试。

唯一的区别是,我创建了一个test子文件夹作为CMake子项目,它有各自的CMakeLists.txt,但配置完全相同。

我做错了什么?

关联问题分析

你链接的问题的答案有几个问题:

  • 它使用了一些非常老派的CMake技术(include_directories((+link_directorie(((。请使用一些较新的3.x版本的CMake并应用现代CMake技术[1][2]
  • 此外,不应将SHARED/STATIC关键字传递给add_library((,而应使用BUILD_SHARED_LIBS变量来控制是构建共享二进制文件还是静态二进制文件
  • 它是不完整的。您需要调用add_test((为ctest创建一个测试,否则ctest和IDE都无法知道您的单元测试。此外,需要在顶级项目中调用enable_testing((,否则add_test()无效

最小工作示例

CMakeLists.txt:

cmake_minimum_required(VERSION 3.21)
project(so70759660)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
enable_testing()
add_subdirectory(tests)
endif()

tests/CMakeLists.txt:

find_package(MSUnitTestFramework REQUIRED)
find_program(VSTest_EXECUTABLE NAMES vstest.console.exe REQUIRED)
add_library(mytest)
target_sources(mytest PRIVATE Mytest.cpp)
target_link_libraries(mytest PRIVATE MSUnitTestFramework::MSUnitTestFramework)
add_test(NAME mytest COMMAND "${VSTest_EXECUTABLE}" "$<TARGET_FILE:mytest>")

cmake/FindMSUnitTestFramework.cmake:

add_library(MSUnitTestFramework::MSUnitTestFramework SHARED IMPORTED)
set_target_properties(MSUnitTestFramework::MSUnitTestFramework PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "$ENV{VCInstallDir}Auxiliary/VS/UnitTest/include"
IMPORTED_IMPLIB "$ENV{VCInstallDir}Auxiliary/VS/UnitTest/lib/x86/Microsoft.VisualStudio.TestTools.CppUnitTestFramework.lib"
)
set(MSUnitTestFramework_FOUND TRUE)

注意:

  • 使用IMPORTED目标并通过target_link_libraries((链接它是include_directories()/include_libraries()的现代替代方案
  • FindMSUnitTestFramework模块负责定位和创建这个导入的目标。请注意,我提供的例子是相当硬编码的;"聪明";在寻找库时,可能会考虑不同的Visual Studio版本或目标体系结构。您可能需要对此进行改进

tests/MyTest.cpp:

#include <CppUnitTest.h>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
TEST_CLASS(Class1) {
public:
TEST_METHOD(Method1) { Assert::AreEqual(0, 0); }
TEST_METHOD(Method2) { Assert::AreNotEqual(0, 42); }
};

CMakePresets.json:

{
"version": 3,
"configurePresets": [
{
"name": "vs2022",
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl",
"BUILD_TESTING": "ON",
"BUILD_SHARED_LIBS": "ON"
}
}
],
"buildPresets": [
{
"name": "vs2022",
"configurePreset": "vs2022"
}
],
"testPresets": [
{
"name": "vs2022",
"configurePreset": "vs2022",
"configuration": "Debug"
}
]
}

兼容性

我只能通过使用Visual Studio生成器和MSVC工具链来运行它。对于其他生成器(Ninja、Make等(,我总是遇到链接器错误,但无法找出原因。

VS代码确实在测试资源管理器中显示测试(您可能需要CMake测试资源管理扩展(,但Visual Studio没有。我怀疑这是一个普遍的问题,VS使用多配置生成器只识别add_test(<name> <command> <args>)签名,而不识别add_test(NAME <name> COMMAND <command> ...)。这是一个相关的错误报告。但不幸的是,第一个签名是不够的,因为它不支持像$<TARGET_FILE:...>这样的生成器表达式。

个人意见

IMHO如果您可以选择使用哪个单元测试框架/库,我建议您再次使用Microsoft单元测试框架,原因如下:

  • 您将自己限制在MSVC工具链中
  • 它相当适合Visual Studio/MBuild。将它集成到任何其他构建系统中都相当乏味
  • AFAIK您甚至不能单独安装它,只能将它作为Visual Studio的一部分进行安装
  • 它不是跨平台的,所以你总是会被Windows卡住

我的建议是使用一些跨平台的东西,这些东西可以与不同的编译器/工具链一起使用,可能是开源的,并提供与其他构建系统的更好集成。示例包括GTest、Catch、Boost。测试等等。有了这些,你可以使用一个单独的配置生成器,比如Ninja,然后Visual Studio中的测试资源管理器应该会发现它们强调文本

最新更新