CMake:利用Google Test库进行单元测试

本文介绍了如何在CMake项目中使用GoogleTest进行单元测试,利用FetchContent模块下载并集成GoogleTest库,同时展示了如何配置CMakeLists.txt以支持单元测试并编写测试用例。
摘要由CSDN通过智能技术生成

CMake:利用Google Test库进行单元测试

导言

本篇,我们将学习如何在CMake的帮助下使用Google Test框架实现单元测试。与前一个配置(Catch2)相比,Google Test框架不仅仅是一个头文件,也是一个库,包含两个需要构建和链接的文件。可以将它们与我们的代码项目放在一起,但是为了使代码项目更加轻量级,我们将选择在配置时,下载一个定义良好的Google Test,然后构建框架并链接它。我们将使用较新的FetchContent模块(从CMake版本3.11开始可用)。关于FetchContent相关使用将在后续的笔记中学习。

此外,我们将在相关测试内容学习完成后挑选一个框架(Google Test目前更加流行)写一个小的项目实践,尽可能多的将该框架下的功能加以熟悉。

项目结构

NOTE

main.cppsum_integers.cppsum_integers.hpp与上一篇内容相同,我们对test.cpp将做相关的修改。

.
├── CMakeLists.txt
├── main.cpp
├── sum_integers.cpp
├── sum_integers.h
└── test.cpp

项目地址:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter4/03

CMakeLists.txt

cmake_minimum_required(VERSION 3.11 FATAL_ERROR)

project(test_gtest LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

add_library(sum_integers sum_integers.cpp)

add_executable(sum_up main.cpp)
target_link_libraries(sum_up sum_integers)

option(ENABLE_UNIT_TESTS "Enable unit tests" ON)
message(STATUS "Enable testing: ${ENABLE_UNIT_TESTS}")

if(ENABLE_UNIT_TESTS)
  include(FetchContent)

  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://gitcode.net/mirrors/google/googletest.git
    GIT_TAG        release-1.8.0
  )

  FetchContent_GetProperties(googletest)

  if(NOT googletest_POPULATED)
    FetchContent_Populate(googletest)

    # Prevent GoogleTest from overriding our compiler/linker options
    # when building with Visual Studio
    set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
    # Prevent GoogleTest from using PThreads
    set(gtest_disable_pthreads ON CACHE BOOL "" FORCE)

    # adds the targers: gtest, gtest_main, gmock, gmock_main
    add_subdirectory(
      ${googletest_SOURCE_DIR}
      ${googletest_BINARY_DIR}
    )

    # Silence std::tr1 warning on MSVC
    if(MSVC)
      foreach(_tgt gtest gtest_main gmock gmock_main)
        target_compile_definitions(${_tgt}
          PRIVATE
            "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING"
        )
      endforeach()
    endif()
  endif()

  add_executable(cpp_test "")

  target_sources(cpp_test
    PRIVATE
      test.cpp
  )

  target_link_libraries(cpp_test
    PRIVATE
      sum_integers
      gtest_main
  )

  enable_testing()

  add_test(
    NAME google_test
    COMMAND $<TARGET_FILE:cpp_test>
  )
endif()

注意: CMake 3.11版本以后才可以使用FetchContent模块。

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

告诉CMakeWindows 平台上自动从共享库(DLL)中导出所有符号(函数、变量、类等)。

当将此选项设置为 ON 时,CMake会自动在库的代码中插入导出指令,确保它们可以被外部链接。这在 Windows 上特别重要,因为需要明确的导出声明才能让符号从 DLL 外部访问。

然而,启用此选项可能会导致生成较大的二进制文件,并可能意外地暴露符号。如果链接了多个库,还可能导致符号冲突。因此,虽然它简化了符号的导出,但需要仔细考虑其影响,以及是否适用于自己的项目。

option(ENABLE_UNIT_TESTS "Enable unit tests" ON)
message(STATUS "Enable testing: ${ENABLE_UNIT_TESTS}")
if(ENABLE_UNIT_TESTS)
    # all the remaining CMake code will be placed here
endif()

检查ENABLE_UNIT_TESTS。默认情况下,它为ON,但有时需要设置为OFF,以免在没有网络连接时,也能使用Google Test

include(FetchContent)

FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://gitcode.net/mirrors/google/googletest.git
  GIT_TAG        release-1.8.0
)

使用了FetchContent模块来下载和集成Google Test库(googletest)。

  • include(FetchContent):用于包含FetchContent模块,该模块允许在项目中获取外部依赖项。

  • FetchContent_Declare(googletest ...):使用FetchContent_Declare宏来声明要获取的外部依赖项。在这种情况下,它声明了一个名为googletest的外部依赖项。

  • GIT_REPOSITORY:这是指定用于获取库的Git存储库的URL

  • GIT_TAG:这是Git存储库中的特定标签或分支,指定希望获取的库的版本。在这里,它指定了Google Test库的版本为release-1.8.0

使用这段代码后,当构建项目时,CMake将尝试下载并集成Google Test库,以便可以在项目中进行单元测试。请注意,实际项目中可能还需要在测试目标中链接Google Test库,并设置测试用例等。

if(NOT googletest_POPULATED)
    FetchContent_Populate(googletest)

    # Prevent GoogleTest from overriding our compiler/linker options
    # when building with Visual Studio
    set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
    # Prevent GoogleTest from using PThreads
    set(gtest_disable_pthreads ON CACHE BOOL "" FORCE)

    # adds the targers: gtest, gtest_main, gmock, gmock_main
    add_subdirectory(
      ${googletest_SOURCE_DIR}
      ${googletest_BINARY_DIR}
    )

    # Silence std::tr1 warning on MSVC
    if(MSVC)
      foreach(_tgt gtest gtest_main gmock gmock_main)
        target_compile_definitions(${_tgt}
          PRIVATE
            "_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING"
        )
      endforeach()
    endif()
  endif()
  • if(NOT googletest_POPULATED):检查是否已经获取并集成了Google Test库。如果googletest_POPULATED未定义,则会执行其中的代码块。

  • FetchContent_Populate(googletest):将下载的Google Test库内容填充到指定的目录,以便后续构建和集成。

  • set(gtest_force_shared_crt ON CACHE BOOL "" FORCE):在使用Visual Studio构建时,将强制Google Test使用共享运行时(C Runtime)库。可以避免构建时的链接错误。

  • set(gtest_disable_pthreads ON CACHE BOOL "" FORCE):禁用Google Testpthreads的使用。这可能在某些环境中是必需的,例如在没有pthreads支持的平台上。

  • add_subdirectory(...):将Google Test库添加到项目中。它会在指定的源码目录和二进制目录中进行构建。

  • 对于Microsoft Visual Studio(MSVC),在构建Google Test库时,通过target_compile_definitionsgtestgtest_maingmockgmock_main目标添加了宏定义以消除MSVC下的警告。

相关源码

test.cpp

#include "sum_integers.h"
#include "gtest/gtest.h"
#include <vector>

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

TEST(example, sum_zero) {
  auto integers = {1, -1, 2, -2, 3, -3};
  auto result = sum_integers(integers);
  ASSERT_EQ(result, 0);
}

TEST(example, sum_five) {
  auto integers = {1, 2, 3, 4, 5};
  auto result = sum_integers(integers);
  ASSERT_EQ(result, 15);
}

输出

mkdir build
cd build
cmake ..
ctest
Test project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/03/build
    Start 1: google_test
1/1 Test #1: google_test ......................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.01 sec
./cpp_test
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from example
[ RUN      ] example.sum_zero
[       OK ] example.sum_zero (0 ms)
[ RUN      ] example.sum_five
[       OK ] example.sum_five (0 ms)
[----------] 2 tests from example (0 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 2 tests.

最后祝大家变得更强!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值