测试是软件开发过程中一个必须的环节,测试确保软件的质量符合预期。
对于工程师自己来说,单元测试也是一种提升自信心的方式。
直接交付没有经过测试的代码是不太好的,因为这很可能会浪费整个团队的时间,在一些原本早期就可以发现的问题上。而单元测试,就是发现问题一个很重要的环节。
本文以C++语言为基础,讲解如何进行单元测试并生成测试报告。
在工具上,我们会使用下面这些:
为了方便本文的讲解,我专门编写了一个演示项目作为代码示例。
演示项目的源码可以在我的Github上获取:paulQuei/gtest-and-coverage。
你可以通过下面几条命令下载和运行这个项目:
git clone https://github.com/paulQuei/gtest-and-coverage.git
cd gtest-and-coverage
./make_all.sh
要运行这个项目,你的机器上必须先安装好前面提到的工具。如果没有,请阅读下文以了解如何安装它们。
如果你使用的是Mac系统,下文假设你的系统上已经安装了brew包管理器。如果没有,请通过下面这条命令安装它:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
演示项目的目录结构如下:
.
├── CMakeLists.txt
├── googletest-release-1.8.1.zip
├── include
│ └── utility.h
├── make_all.sh
├── src
│ └── utility.cpp
└── test
└── unit_test.cpp
这里演示的内容是:以测试一个我们要提供的软件库为例,讲解如何对其进行单元测试并生成测试报告。
为了简单起见,这个软件库只有一个头文件和一个实现文件。
当然,在实际上的项目中,一个软件库会通常包含更多的文件,不过这并不影响我们要说明的问题。
演示项目中的文件说明如下:
文件名称 | 说明 |
---|---|
make_all.sh | 入口文件,会执行:编译,测试和生成报告等所有工作 |
CMakeLists.txt | 项目的编译文件 |
googletest-release-1.8.1.zip | google test源码压缩包 |
utility.h | 待测试的软件库的头文件 |
utility.cpp | 待测试的软件库的实现文件 |
unit_test.cpp | 对软件库进行单元测试的代码 |
演示项目在如下的环境中测试过。
MacBook Pro
Ubuntu
为了简化编译的过程,这里使用CMake作为编译工具。关于CMake的更多内容请参见请官网:https://cmake.org。
关于如何安装CMake请参见这里:Installing CMake。
另外,你也可以通过一条简单的命令来安装CMake:
brew install cmake
sudo apt install cmake
由于篇幅所限,这里不打算对CMake做过多讲解,读者可以访问其官网或者在网络上搜寻其使用方法。
这里仅仅对演示项目中用到的内容做一下说明。演示项目中的CMakeLists.txt
内容如下:
cmake_minimum_required(VERSION 2.8.11) ①
project(utility) ②
set(CMAKE_CXX_STANDARD 11) ③
set(GTEST googletest-release-1.8.1) ④
include_directories("./include" "${GTEST}/googletest/include/")
link_directories("build/gtest/googlemock/gtest/")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") ⑤
add_library(${CMAKE_PROJECT_NAME}_lib src/utility.cpp) ⑥
add_executable(unit_test test/unit_test.cpp) ⑦
target_link_libraries(unit_test ${CMAKE_PROJECT_NAME}_lib gtest gtest_main pthread) ⑧
以编号为序,这段代码说明如下:
${CMAKE_PROJECT_NAME}
进行引用。--coverage
到编译器flag中,这个参数是很重要的,因为这是生成代码覆盖率所必须的。关于该编译参数的说明见这里:Program Instrumentation Options。libutility_lib.a
库文件。软件测试有很多种分类方式。从测试的级别来说,可以大致分为:
这其中,单元测试是最局部和具体的。它通常需要对代码中的每一个类和函数进行测试。
单元测试通常由开发者完成,需要针对代码逻辑进行测试。所以它是一种白盒测试。
xUnit是几种单元测试框架的总称。最早源于Smalltalk的单元测试框架SUnit,它是由Kent Beck开发的。
除此之外,还有针对Java语言的JUnit,针对R语言的RUnit。
在本文中,我们使用Google开发的xUnit框架:Google Test。
Google Test的项目主页在Github上:Github: Google Test。
实际上,这个项目中同时包含了GoogleTest和GoogleMock两个工具,本文中我们只会讲解第一个。
Google Test支持的操作系统包含下面这些:
目前有很多的项目都使用了Google Test,例如下面这些: