0


【CMake】gtest环境搭建与TDD入门(二)

上一篇文章,我们介绍了CMake:传送门

这一篇文章我暂时不打算继续写CMake相关的东西了,转而写一个叫TDD的开发理论,当然,理论是需要实践支撑的,利用CMake,我简单搭了一个gtest环境。

准备

gtest

Gtest是一个跨平台的(Linux、Mac OS X、Windows、Cygwin、Windows CE and Symbian) C++单元测试框架,由google公司发布。gtest是为在不同平台上为编写C++测试而生成的。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。

简而言之:Gtest测试框架可以在不同平台上为编写C++测试。

可以从以下途径下载gtest:
GitHub:https://github.com/google/googletest
Gitee国内镜像:https://gitee.com/mirrors/googletest

将代码 git clone 到本地,接下来需要编译gtest动态链接库,进入项目文件夹下的googletest根目录,如下:

    Directory: D:\toolsSpace\googletest\googletest                                                                                              
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----    2022/9/17 星期六    19:46                bin
d----    2022/9/17 星期六    18:51                cmake
d----    2022/9/17 星期六    19:46                CMakeFiles
d----    2022/9/17 星期六    18:51                docs
d----    2022/9/17 星期六    18:51                include
d----    2022/9/17 星期六    19:46                lib
d----    2022/9/17 星期六    18:51                samples
d----    2022/9/17 星期六    18:51                src
d----    2022/9/17 星期六    18:51                test
-a---    2022/9/17 星期六    19:45           1609 cmake_install.cmake
-a---    2022/9/17 星期六    19:45          18571 CMakeCache.txt
-a---    2022/9/17 星期六    19:44          12322 CMakeLists.txt
-a---    2022/9/17 星期六    19:45           6889 Makefile
-a---    2022/9/17 星期六    18:51           9107 README.md

默认是不编译dll动态库的。修改这个目录下的CMakeLists.txt,找到下面这部分:

# These commands only run if this is the main project
if(CMAKE_PROJECT_NAME STREQUAL "gtest" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution")

  # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
  # make it prominent in the GUI.option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)else()mark_as_advanced(
    gtest_force_shared_crt
    gtest_build_tests
    gtest_build_samples
    gtest_disable_pthreads
    gtest_hide_internal_symbols)endif()

修改option后面的

OFF

ON

,代表开启了编译DLL动态库。

Windows默认使用MSVC编译,就是我上篇文章提到的调用VS的部分。执行下面命令以使用MinGW gcc编译:

cmake -G "MinGW Makefiles"

此处可能会报下面的错:报错
访问127~129:

cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)set_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION})cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)

很明显没有定义

GOOGLETEST_VERSION

的值,在开头加入

set(GOOGLETEST_VERSION 1.11.0)

即可

编译后执行mingw32的mingw32-make命令

mingw32-make

此时,googletest文件夹下新生成一个bin文件夹,包含libgtest.dll、libgtest_main.dll,这两个文件就是我们需要链接的。

搭建

最后成型的结构如下:

DateTestMy
├─ CMakeLists.txt
├─ gtest
│  ├─ include
│  │  └─ gtest
│  │     ├─ gtest-assertion-result.h
│  │     ├─ gtest-death-test.h
│  │     ├─ gtest-matchers.h
│  │     ├─ gtest-message.h
│  │     ├─ gtest-param-test.h
│  │     ├─ gtest-printers.h
│  │     ├─ gtest-spi.h
│  │     ├─ gtest-test-part.h
│  │     ├─ gtest-typed-test.h
│  │     ├─ gtest.h
│  │     ├─ gtest_pred_impl.h
│  │     ├─ gtest_prod.h
│  │     └─ internal
│  │        ├─ custom
│  │        │  ├─ gtest-port.h
│  │        │  ├─ gtest-printers.h
│  │        │  ├─ gtest.h
│  │        │  └─ README.md
│  │        ├─ gtest-death-test-internal.h
│  │        ├─ gtest-filepath.h
│  │        ├─ gtest-internal.h
│  │        ├─ gtest-param-util.h
│  │        ├─ gtest-port-arch.h
│  │        ├─ gtest-port.h
│  │        ├─ gtest-string.h
│  │        └─ gtest-type-util.h
│  ├─ lib
│  │  ├─ libgtest.dll
│  │  └─ libgtest_main.dll
│  └─ src
│     ├─ gtest-all.cc
│     ├─ gtest-assertion-result.cc
│     ├─ gtest-death-test.cc
│     ├─ gtest-filepath.cc
│     ├─ gtest-internal-inl.h
│     ├─ gtest-matchers.cc
│     ├─ gtest-port.cc
│     ├─ gtest-printers.cc
│     ├─ gtest-test-part.cc
│     ├─ gtest-typed-test.cc
│     ├─ gtest.cc
│     └─ gtest_main.cc
├─ include
│  └─ datet.h
├─ libgtest.dll
├─ libgtest_main.dll
├─ README.md
├─ src
│  └─ datet.cpp
└─ test
   └─ datet_unittest.cpp

首先创建工程目录,切换到工程目录下。

  1. 新建include、src、test分别放头文件、代码实现和测试函数。
  2. 新建gtest文件夹,将googletest的include、src直接挪过来。在gtest下建立lib文件夹,放之前编译出来的 libgtest.dlllibgtest_main.dll 。这两个文件在项目根目录也要复制一份,不然编译出来的exe文件会提示缺dll。
  3. 在工程根目录建立CMakeLists.txt

代码

一切准备就绪,现在开始编写

CMakeLists.txt

,我的如下:

# 指定CMake编译最低要求版本
cmake_minimum_required(VERSION 3.14)
# 给项目命名
project(datet)

# 指定.h头文件目录
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include
                    ${CMAKE_CURRENT_SOURCE_DIR}/gtest/include
)

# 指定.dll链接库文件目录
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/gtest/lib)

# 收集c/c++文件并赋值给变量
# ${CMAKE_CURRENT_SOURCE_DIR}代表CMakeLists.txt当前项目录
file(GLOB
    SRC_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
)

file(GLOB
    SRC_TEST_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/test/*.cpp
)

# 将c文件生成可执行文件sample1.exe
add_executable(${PROJECT_NAME} ${SRC_FILES} ${SRC_TEST_FILES})

# 指定链接库libgtest.dll、libgtest_main.dll
target_link_libraries(${PROJECT_NAME} gtest pthread)

每一项我都写了注释,实际使用时按自己项目内容修改。

我计划用一道很简单的LeetCode题目讲解TDD,题目如下(LeetCode 1154):

输入某年某月某日,判断这一天是这一年的第几天?。 测试用例有多组,注意循环输入

输入描述: 输入多行,每行间隔分割,分别是年,月,日 输出描述: 成功:返回outDay输出计算后的第几天; 失败:返回-1

示例: 输入 2012 12 31 输出 366

这题正常做起来其实非常简单,但是我计划用TDD的思想来完成。
首先是

include\datet.h
intcalculateDate(int year,int month,int day);

然后是

src\datet.cpp
#include"datet.h"intcalculateDate(int year,int month,int day){return1;}

src下的cpp文件应当引用h文件,最后是

test\datet_unittest.cpp

。你可能会对函数内容有疑问,请保持疑问,继续读下去。

#include"gtest/gtest.h"#include"datet.h"TEST(dayFirstTest,dayFirst){EXPECT_EQ(calculateDate(2022,1,1),1);}intmain(int argc,char**argv){
    testing::InitGoogleTest(&argc,argv);returnRUN_ALL_TESTS();}

main函数相关内容用于初始化gtest,基本不需要更改。
这里我写了一个简单的测试用例,测试case为dayFirstTest,name为dayFirst。其实一眼就能看出百分百通过测试的,而且换个数肯定通不过,但不要着急。

运行

首先是构建

cmake -G "MinGW Makefiles"

结果如图:构建结果
接着编译

mingw32-make

结果如下:编译结果执行datet.exe,回车,即可看到测试结果:在这里插入图片描述
这个测试我们通过了,这是显而易见的。但其实换个测试用例就大概率过不了。TDD的思想就在于,由测试引导开发,因为有不过的测试用例,所以需要对应修改代码,再重构,再编写新的不过的测试用例,如此循环,直到所有的测试用例全通过为止。

我将在下一篇文章介绍TDD。

标签: tdd c++ 单元测试

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

“【CMake】gtest环境搭建与TDD入门(二)”的评论:

还没有评论