gTest - 从源码引入自己的项目[原文来自Raymii.org]

写在前面

这是我在解决搭建gTest测试框架遇到的问题时,偶然遇到的一篇英文博客文章,来自于一位荷兰的博主,他发布在他的个人博客上的。

Hi there! I’m Remy, a developer from The Netherlands with a focus on C++, C, some C#, Linux and embedded systems. I currently work on a C++ and Qt stack running on Yocto Linux. It controls hardware, runs the UI and has a few utilities for IoT connectivity and configuration. Technologies I’m fluid in include C, C# & C++, Windows (MFC/Win32), .NET (Core, Xaml, Framework and C++/CLI), Flash, Qt, Ansible, Bash & PowerShell. I was Linux and UNIX sysadmin for over 10 years before I got into development.

原文链接

点此跳转原文

获取本文代码

本文的代码,已上传码云gitee,无需逐个复制到文件中。

但是不包含Google Test的源代码。

仓库地址:https://gitee.com/gz2022/google-test-example.git

获取Google Test源码

Google Test作为一款开源软件,是支持从源码构建的。
github源码仓库为https://github.com/google/googletest
如果要求不高的话,也可以在码云gitee上获取,比较方便一些。https://gitee.com/mirrors/googletest
使用下面的git命令可以获取源代码。

git clone https://github.com/google/googletest
git clone https://gitee.com/mirrors/googletest

Google Test官方文档中的构建方式

Google Test的官方文档中,有Quickstart: Building with CMake章节,里面介绍了一种通过CMake构建的方式。
其核心部分是编写如下内容的CMakeLists.txt文件

cmake_minimum_required(VERSION 3.14)
project(my_project)

# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

这个方法我调试未成功,猜测主要原因在于

URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip

这一行。需要连接到github自行下载Google Test源码并且构建。
但是连接github有时候比较麻烦。

其实通过其他途径,获取源代码并不困难,只是需要构建而已。build的过程万变不离其宗,应该还是有其他方案的,哪怕原始一些。

Raymii.org博客中的示例工程

然后我在搜索的过程中,就找到了Raym的博客。他没有使用官方文档中的方式。

我们先来跟随着Raym的脚步来从头开始构建一个项目。

他的文章中,假设我们有这样一个项目,需要使用gTest进行测试,项目文件名为ExampleProject,其中包含buildlibsrctst(short for test)4个子文件夹。以及根目录下的CMakeLists.txt文件。
项目的代码主要由3个文件组成,Formula.cppFormula.hmain.cpp

  • build:用于构建的文件夹
  • lib:存储项目的其他依赖库,这里只存储了用于测试的gTest
  • src:项目的源代码
    • Formula.cppFormula.hmain.cpp:待测的项目代码
    • CMakeLists.txtsrc文件夹下的CMakeLists文件
  • tst:项目测试代码
    • Formula-test.cpp:对Formula类的测试代码,通过命名规范来清晰地实现项目和测试的分离。
    • main.cpp:测试项目的主函数
    • CMakeLists.txttst文件夹下的CMakeLists文件
$ tree -L 2 ExampleProject/
ExampleProject/
|-- build/
|-- CMakeLists.txt
|-- lib/
|   `-- googletest 
|-- src/
|   |-- CMakeLists.txt
|   |-- Formula.cpp
|   |-- Formula.h
|   `-- main.cpp
`-- tst/
    |-- CMakeLists.txt
    |-- Formula-test.cpp
    `-- main.cpp

将整个google test项目的源代码,都拷贝到lib文件夹下的googletest中。从下面的实例可以看出,googletest文件夹下面就是gTest仓库中的所有内容。内容可能有所不同,因为这个terminal信息是我已经build之后的样子,可能会多出一些文件。

user@ubuntu:~/cpp_workspace/GoogleTestExample/lib$ cd googletest/
user@ubuntu:~/cpp_workspace/GoogleTestExample/lib/googletest$ ls
build        CMakeLists.txt   docs                  googletest           LICENSE       WORKSPACE
BUILD.bazel  CONTRIBUTING.md  fake_fuchsia_sdk.bzl  googletest_deps.bzl  MODULE.bazel  WORKSPACE.bzlmod
ci           CONTRIBUTORS     googlemock            install              README.md

项目各个文件中的内容

各级CMakeLists.txt

根目录下CMakeLists.txt的内容

项目的名称是ExampleProject,通过project()语句来指定。

cmake_minimum_required(VERSION 3.10)
project(ExampleProject)

set(CMAKE_CXX_STANDARD 14)

include_directories(src)

add_subdirectory(src)
add_subdirectory(tst)
add_subdirectory(lib/googletest)
src文件夹下CMakeLists.txt的内容

根据cmake变量${CMAKE_PROJECT_NAME}获取项目的名称(由project()语句指定了的),并通过set()语句赋值给变量${BINARY}

这里的file()语句我也没看懂,但是他能起到的作用就是把当前目录下的所有*.h*.cpp文件都添加到一个${SOURCES}变量中。

set(BINARY ${CMAKE_PROJECT_NAME})
file(GLOB_RECURSE SOURCES LIST_DIRECTORIES true *.h *.cpp)
set(SOURCES ${SOURCES})
add_executable(${BINARY}_run ${SOURCES})
add_library(${BINARY}_lib STATIC ${SOURCES})
tst文件夹下CMakeLists.txt的内容

src文件夹相比,区别是多了一个target_link_libraries()语句。
测试代码需要依赖于库${CMAKE_PROJECT_NAME}_lib,而由前文可知,${BINARY}_lib就是${CMAKE_PROJECT_NAME}_lib(根据set(BINARY ${CMAKE_PROJECT_NAME}))。也就是说,原项目中构建了一个库(而且是静态库),供测试代码在构建时使用。

set(BINARY ${CMAKE_PROJECT_NAME}_tst)
file(GLOB_RECURSE TEST_SOURCES LIST_DIRECTORIES false *.h *.cpp)
set(SOURCES ${TEST_SOURCES})
add_executable(${BINARY} ${TEST_SOURCES})
add_test(NAME ${BINARY} COMMAND ${BINARY})
target_link_libraries(${BINARY} PUBLIC ${CMAKE_PROJECT_NAME}_lib gtest)

项目的源代码

src/main.cpp
#include <iostream>
#include "Formula.h"

int main() {
    std::cout << "Bla: " << Formula::bla(2) << std::endl;
    return 0;
}
src/Formula.h

Formula类定义了一个静态方法,传入一个整数,返回这个整数的2倍。

#ifndef EXAMPLEPROJECT_FORMULA_H
#define EXAMPLEPROJECT_FORMULA_H

class Formula {
public:
    static int bla(int arg1);
};

#endif //EXAMPLEPROJECT_FORMULA_H
src/Formula.cpp
#include "Formula.h"

int Formula::bla(int arg1) {
    return arg1 * 2;
}

测试程序的源代码

tst/main.cpp
#include "gtest/gtest.h"

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
tst/Formula-test.cpp
#include "gtest/gtest.h"
#include "Formula.h"

TEST(blaTest, test1) {
    //arrange
    //act
    //assert
    EXPECT_EQ (Formula::bla (0),  0);
    EXPECT_EQ (Formula::bla (10), 20);
    EXPECT_EQ (Formula::bla (50), 100);
}

构建并运行测试

进入build文件夹,并按照cmake的常用操作进行构建

cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -G "Unix Makefiles"
make all

构建出的二进制程序,就在build文件夹下,使用find命令可以查找出来。(下面还有一些中间文件)

user@ubuntu:~/cpp_workspace/GoogleTestExample/build$ find . -executable -type f
./src/GoogleTestExample_run
./CMakeFiles/3.16.3/CompilerIdC/a.out
./CMakeFiles/3.16.3/CompilerIdCXX/a.out
./CMakeFiles/3.16.3/CMakeDetermineCompilerABI_C.bin
./CMakeFiles/3.16.3/CMakeDetermineCompilerABI_CXX.bin
./test/GoogleTestExample_tst

运行项目程序

运行

./src/ExampleProject_run

输出

Bla: 4

运行测试程序

运行

./test/GoogleTestExample_tst

输出

user@ubuntu:~/cpp_workspace/GoogleTestExample/build$ ./test/GoogleTestExample_tst
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from blaTest
[ RUN      ] blaTest.test1
[       OK ] blaTest.test1 (0 ms)
[----------] 1 test from blaTest (0 ms total)

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

至此,一个完整的利用gTest对项目代码进行测试的流程已经结束了。

  • gTest是以第三方库的形式参与到项目之中的。
  • 测试代码与原工程的代码也是分离的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值