一、安装googletest
单测对程序员而言是提升代码质量最重要、最有效的一个措施,对程序员来说,要想写一个好的程序,那么必定少不了好的单元测试。googletest(gtest)是google开发出来的一个开源的、跨平台的测试框架,是C++中最出名的测试框架。
gtest支持linux、windows以及mac系统,安装它依赖下面几项:
gtest源码:gtest属于开源项目,代码仓库
https://github.com/google/googletest
。
cmake:gtest使用cmake构建项目,编译需要cmake环境,
cmake下载地址
。
编译器:linux环境下可使用g++编译,windows环境下使用vs或者clion等工具编译,mac环境使用xcode或clion等工具编译。
这里的测试环境为mac+clion(付费),
clion下载地址
,选择clion是因为clion跨平台。
windows环境除了配置clion编译环境以外,其他步骤和mac系统一致。
1.1 环境配置
第一步,先使用git克隆代码到本地,注意最好不要放到中文路径了。
第三步,安装clion,linux和mac环境下安装clion和gcc环境就可以使用了,windows配置clion编译环境可参考
Window10上CLion极简配置教程
。
1.2 编译gtest库
配置好环境后,使用clion打开代码目录,然后载入代码目录,选择
gtest
项目编译生成:
编译成功后生成
libgtestd.a
文件到cmake编译路径的
lib
路径下:
生成的
libgtestd.a
即为gtest的库文件,项目中引用这个库文件就能使用gtest了。
二、使用googletest
2.1 引入库
将libgtestd.a文件拷贝到代码根路径的lib路径下,在CMakeList.txt中加上以下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "gtest/gtest.h"
int
add
(
int
a
,
int
b
)
{
return
a
+
b
;
}
TEST
(
add
,
zero
)
{
EXPECT_EQ
(
0
,
add
(
0
,
0
)
)
;
}
TEST
(
add
,
positive_number
)
{
EXPECT_EQ
(
3
,
add
(
1
,
2
)
)
;
}
TEST
(
add
,
negative_number
)
{
EXPECT_EQ
(
-
3
,
add
(
-
1
,
-
2
)
)
;
}
int
main
(
)
{
::
testing
::
InitGoogleTest
(
)
;
return
RUN_ALL_TESTS
(
)
;
}
执行结果:

三、gtest的使用教程
参考文档:
Googletest Primer
,google官方出品。
3.1 基本用法
gtest最基本的用法就是断言,它内部提供了很多种断言方式,例如:
[ OK ] add.zero (0 ms)
[ RUN ] add.positive_number
[ OK ] add.positive_number (0 ms)
[ RUN ] add.negative_number
[ OK ] add.negative_number (0 ms)
TEST(add, negative_number) {
EXPECT_EQ(-3, add(-1, 2)) << "this is a incorrect test";
开始测试pop。
从直观上来看,所有和pop相关的测试案例都要这么来写,要先推入元素,再弹出。而实际上,步骤1和步骤2是和本轮测试无关,它只起到了初始化数据的作用,它是多余的,但是所有的测试案例又不得不做这一步操作。那么有没有办法解决这个问题呢?有!Test Fixtures的就是解决这种问题的,它可以在测试案例开始前自动生成好需要的数据。
定义了一个简单的
栈
的类:
1
2
3
4
5
6
7
8
9
10
11
12
13
TEST_F
(
stack_test
,
push
)
{
EXPECT_EQ
(
stack1
.size
(
)
,
2
)
;
EXPECT_EQ
(
stack2
.size
(
)
,
0
)
;
stack2
.push
(
1
)
;
EXPECT_EQ
(
stack2
.size
(
)
,
1
)
;
}
TEST_F
(
stack_test
,
pop
)
{
EXPECT_EQ
(
stack1
.size
(
)
,
2
)
;
EXPECT_EQ
(
stack2
.size
(
)
,
0
)
;
stack1
.pop
(
)
;
EXPECT_EQ
(
stack1
.size
(
)
,
1
)
;
}
在执行TEST_F之前,gtest会自动构建一个stack_test的实例,并执行SetUp函数。也就是说,当真正执行到我们的测试代码的时候,就已经存在一个初始化好的测试环境了。这个时候可以直接访问stack_test的内部成员,通过成员变量来做单元测试。
原理来看其实很简单,就是把初始化的过程交给了gtest来完成,它来帮我们实例对象,进行初始化,我们直接用就行。
测试结果:
5.1 clion环境跨平台使用gtest
如何在不改变CMakeList.txt的情况下跨平台使用gtest?配置CMakeList,根据不同平台读取不同的库:
# 根据不同平台设置库的目录
if (UNIX AND NOT APPLE) # unix非苹果系统
set(PROJ_LIBRARY_PATH /home/maqian/code/lib)
set(GTEST_LIBRARY_NAME libgtestd.a)
elseif (WIN32) # windwos系统
set(PROJ_LIBRARY_PATH d:/mingw64/lib)
set(GTEST_LIBRARY_NAME libgtestd.a)
elseif (APPLE) # mac系统
set(PROJ_LIBRARY_PATH /Users/maqian/code/lib)
set(GTEST_LIBRARY_NAME libgtestd.a)
else () # 未知系统
MESSAGE(STATUS "other platform: ${CMAKE_SYSTEM_NAME}")
endif ()
# 引入链接库目录
link_directories(${PROJ_LIBRARY_PATH})
# 链接库到目标
target_link_libraries(xxxx ${GTEST_LIBRARY_NAME})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 根据不同平台设置库的目录
if
(
UNIX
AND
NOT
APPLE
)
# unix非苹果系统
set
(
PROJ_LIBRARY_PATH
/
home
/
maqian
/
code
/
lib
)
set
(
GTEST_LIBRARY_NAME
libgtestd
.a
)
elseif
(
WIN32
)
# windwos系统
set
(
PROJ_LIBRARY
_
PATH
d
:
/
mingw64
/
lib
)
set
(
GTEST_LIBRARY_NAME
libgtestd
.a
)
elseif
(
APPLE
)
# mac系统
set
(
PROJ_LIBRARY_PATH
/
Users
/
maqian
/
code
/
lib
)
set
(
GTEST_LIBRARY_NAME
libgtestd
.a
)
else
(
)
# 未知系统
MESSAGE
(
STATUS
"other platform: ${CMAKE_SYSTEM_NAME}"
)
endif
(
)
# 引入链接库目录
link_directories
(
$
{
PROJ_LIBRARY_PATH
}
)
# 链接库到目标
target_link_libraries
(
xxxx
$
{
GTEST_LIBRARY_NAME
}
)
默认情况下,goland(jetbrains家的软件:idea、pycharm、phpstorm以及webstorm都是一样)安装protobuf插件后只会在一个特定的库路径下搜索proto文件。如果...
07月25日
一、文件流 C++的IO类中定义了三个文件读写流fstream、ifstream以及ofstream,它们都继承于相同的父类istream,通过不同的实现以实现不同的文件流操作。 三者的区别为: if...
12月26日
使用形式: using指令(using directive)的使用形式为using namespace std。 using声明(using declaration)的使用形式为using std::...
11月07日
一、const和成员函数的故事 const的用途有以下几种: 修饰全局、局部、成员变量 修饰成员函数 修饰变量的时候const限制了变量在整个程序运行期间都是不能修改的,而修饰成员函数的时候限制函数内...
10月19日