0


使用CMake和Catch2进行单元测试

前言

单元测试是软件开发过程中的重要部分,它帮助我们确保每个组件按预期工作。C++ 中进行单元测试的一个流行选择是 Catch2 测试框架,结合 CMake 构建系统,可以创建一个强大且灵活的测试环境。在这篇博客中,将演示使用 Catch2 集成到 CMake 的 CTest 工具中进行单元测试。

环境准备

  • CMake:v3.28
  • Catch 2:v3.6.0 假设目录结构如下:
  1. MyProject/
  2. |-- CMakeLists.txt
  3. |-- src/
  4. |-- main.cpp
  5. |-- test/
  6. |-- CMakeLists.txt
  7. |-- test.cpp

CMake 配置

根目录

  1. CMakeLists.txt

  1. # CMakeLists.txt
  2. cmake_minimum_required(VERSION 3.28)
  3. ...
  4. option(ENABLE_TESTS "Build the test" ON)
  5. ...
  6. if (ENABLE_TESTS)
  7. # 启用测试
  8. enable_testing()
  9. add_subdirectory(test)
  10. endif ()

使用

  1. enable_testing()

启用 CTest 测试。

  1. test

目录下的

  1. CMakeLists.txt

  1. # test/CMakeLists.txt
  2. include(FetchContent)
  3. FetchContent_Declare(
  4. Catch2
  5. GIT_REPOSITORY https://github.com/catchorg/Catch2.git
  6. GIT_TAG v3.6.0
  7. )
  8. FetchContent_MakeAvailable(Catch2)
  9. add_executable(SimZipTest test.cpp)
  10. target_link_libraries(SimZipTest PRIVATE SimZip Catch2::Catch2WithMain)
  11. add_test(NAME SimZipTest
  12. COMMAND $<TARGET_FILE:SimZipTest> --success
  13. )

这里使用了 CMake 的

  1. FetchContent

方式集成 Catch2,并指定了 Git tag 为

  1. v3.6.0

,然后使用

  1. target_link_libraries()

将需要链接的库和 Catch 的库链接上。

Catch 2 有两种方式:

  1. Catch2::Catch2

  1. Catch2::Catch2WithMain

。如果不需要自定义 main 函数,则使用后者。如果需要自定义 main,则应该只链接

  1. Catch2::Catch2

之后便是

  1. add_test()

命令添加测试。

注意,这里使用了

  1. --success

选项传递给单元测试的可执行文件,用于显示 Catch 2的输出。

编写测试代码

  1. test

目录下,编写

  1. test.cpp

代码:

  1. // test.cpp#include"../SimZip.h"#include<catch2/catch_test_macros.hpp>#include<fstream>#include<filesystem>voidgenerateData(){
  2. std::ofstream file("data.txt");if(file.is_open()){for(auto i =0; i <10; i++){ file <<"this is data for test.";}
  3. file.close();}}TEST_CASE("create zip","[create_zip]"){generateData();
  4. SimZip zip("test.zip", SimZip::OpenMode::Create);REQUIRE(zip.add("data.txt")==true);REQUIRE(zip.add("data.txt","folder/rename.txt")==true);REQUIRE(zip.add("empty.txt")==false);
  5. zip.save();}TEST_CASE("extract zip","[extract_zip]"){
  6. SimZip zip("test.zip", SimZip::OpenMode::Read);SECTION("Extract single file from zip"){
  7. zip.extract("data.txt","output/");REQUIRE(fs::exists("output/data.txt"));}SECTION("Extract all files from zip"){ zip.extractall("output/");
  8. std::vector<std::string> expected_files ={"data.txt","folder/rename.txt"};for(constauto& file: expected_files){REQUIRE(fs::exists("output/"+ file));}}}

在 Catch2 测试框架中,

  1. TEST_CASE

是一个宏,用于定义一个测试用例。这个宏接受几个参数,其中最常见的是测试用例的名称和可选的标签。

  1. TEST_CASE("test name","[tags]"){// 测试代码 }
  1. 测试用例名称:第一个参数是测试用例的名称,它是一个描述性的字符串,表明测试用例的目的或测试的行为。在 Catch2 中运行测试时,这个名称会被用来识别和过滤特定的测试。
  2. 标签:第二个参数是可选的,它允许你为测试用例添加标签。标签通常用方括号 [] 包围,并可以用逗号 , 分隔,从而为测试用例分配多个标签。标签可以用来对测试进行分类,或者在运行测试时进行过滤。
  1. SECTION

是一个宏,用于将一个测试案例(

  1. TEST_CASE

)划分为多个独立的部分,每个部分都可以单独运行或独立地进行断言检查。这允许你以模块化的方式编写测试,并且可以针对相同的测试设置运行多个不同的测试场景。

运行测试

使用命令:

  1. cmake -B build
  2. cmake --build build
  3. ctest --test-dir build/

然后就可以看到测试结果:

  1. $ ctest
  2. Test project /mnt/f/Code/CppProjects/SimZip/build
  3. Start 1: SimZipTest
  4. 1/1 Test #1: SimZipTest ....................... Passed 0.06 sec100% tests passed, 0 tests failed out of 1
  5. Total Test time(real)=0.10 sec

对 CTest 添加

  1. -V

参数,可以看到详细信息

  1. ctest --test-dir build/ -V

如果你使用的是 CLion,那么可以很方便地进行测试,选择 CTest 然后运行,即可执行测试。

测试结果:

Clion CTest运行截图

总结

CMake 和 Catch2 的结合提供了一个简单而强大的单元测试解决方案,它可以帮助你确保代码的质量。通过遵循上述步骤,你可以轻松地在你的 C++ 项目中集成测试,并保持代码的可维护性和健壮性。

标签: 单元测试

本文转载自: https://blog.csdn.net/no_say_you_know/article/details/139104506
版权归原作者 L-Super 所有, 如有侵权,请联系我们删除。

“使用CMake和Catch2进行单元测试”的评论:

还没有评论