gtest使用说明

为了提高代码质量,在同事的帮助下学习了如何使用gtest进行单元测试

准备工作

1 首先从googlecode上下载gtest的源码(googlecode明年一月即将关闭不知道这个项目会何去何从呢)

解压后参考README文件进行编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GTEST_TARGET=googletest ./travis.sh
GTEST_TARGET=googlemock ./travis.sh
```

此时目录下会生成一个build目录,代码的单元测试依赖的就是这个目录里的静态库文件

2 安装lcov

一般yum即可安装,如果不行的话,那就下载安装

这里不用编译,直接make install即可

```c
wget http://downloads.sourceforge.net/ltp/lcov-1.11.tar.gz
tar xvf lcov-1.11.tar.gz
cd lcov-1.11
make install

3 准备项目代码和Makefile

首先创建一个gtest的目录,后面单元测试的代码都放在这个目录里面

头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost.localdomain gtest_test]# cat hello.h 
#ifndef HELLO_H
#define HELLO_H

class hello{
public:
hello();
int set_i(int temp);
private:
int i;
};

#endif

CPP文件

注意这里只要使用到main函数,外部一定要加上ifndef GOOGLE_TEST否则后面的操作会报错,main链接冲突

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@localhost.localdomain gtest_test]# cat hello.cpp 
#include "hello.h"
#include <iostream>

using namespace std;

hello::hello()
{
i = 0;
}

int hello::set_i(int temp)
{
i = temp;
return i;
}

#ifndef GOOGLE_TEST
int main()
{
class hello A;
cout << A.set_i(1) << endl;
}
#endif

项目本身的Makefile中规中矩没啥好说的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@localhost.localdomain gtest_test]# cat Makefile 
CC=g++
CFLAGS=-std=c++0x -g -O2 -Wall -Wno-deprecated
INCLUDE=-I./
LINK_LIBS=-L./
TARGET=hello
OBJS=$(patsubst %.cpp,%.o,$(wildcard *.cpp))
OBJS+=$(patsubst %.cc,%.o,$(wildcard *.cc))

all:$(TARGET)

$(TARGET):$(OBJS)
@echo " LD $@"
@$(CC) -o $@ $^ $(LINK_LIBS)

.cpp.o:
@echo " CC $@"
@$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE)

.cc.o:
@echo " CC $@"
@$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE)

clean:
rm -f $(TARGET) $(OBJS)

然后是gtest的Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
CC=g++                                                                                        
GTEST_DIR=/root/googletest
CFLAGS=-fprofile-arcs -ftest-coverage -DGOOGLE_TEST -std=c++0x -g -O2 -Wall -Wno-deprecated
INCLUDE=-I$(GTEST_DIR)/googletest/include -I./
LINK_LIBS=$(GTEST_DIR)/build/googletest/libgtest.a -lpthread -fprofile-arcs -ftest-coverage -L./
TARGET=gtests
OBJS=$(patsubst %.cpp,%.o,$(wildcard *.cpp))
OBJS+=$(GTEST_DIR)/googletest/src/gtest_main.o
OBJS+=$(patsubst %.cc,%.o,$(wildcard gtest/*.cc))
OBJS+=$(patsubst %.cc,%.o,$(wildcard *.cc))

all:$(TARGET)

$(TARGET):$(OBJS)
@echo " LD $@"
@$(CC) -o $@ $^ $(LINK_LIBS)

.cpp.o:
@echo " CC $@"
@$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE)

.cc.o:
@echo " CC $@"
@$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDE)

clean:
rm -f $(TARGET) $(OBJS)
.cleanall:
rm -f $(TARGET) $(OBJS)
rm -rf *.gcno *.gcda gtest/*.gcno gtest/*.gcda gtest/app.info gtest/results
1
2
3
4
5
6
7
8
9
10
11
12
这个文件是对刚才hello项目的文件修改而生成的
GTEST_DIR路径是刚才编译完的build路径的上一级
CFLAGS需要加上-fprofile-arcs -ftest-coverage -DGOOGLE_TEST
INCLUDE需要加上-I$(GTEST_DIR)/googletest/include
LINK_LIBS需要加上$(GTEST_DIR)/build/googletest/libgtest.a -lpthread -fprofile-arcs -ftest-coverage -lpthread
TARGET修改为gtests
加上一句OBJS+=$(GTEST_DIR)/googletest/src/gtest_main.o
和OBJS+=$(patsubst %.cc,%.o,$(wildcard gtest/*.cc))
另外加上一段来清除运行gtest生成的中间文件
.cleanall:
rm -f $(TARGET) $(OBJS)
rm -rf *.gcno *.gcda gtest/*.gcno gtest/*.gcda gtest/app.info gtest/results

编写单元测试代码

单元测试代码如何写,在samples文件夹下有示例代码,不再赘述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost.localdomain gtest_test]# cat gtest/gtest_hello.cc 
#include "gtest/gtest.h"
#include "hello.h"
#define private public
#define protected public
//add header file of tested object here...
#undef private
#undef protected
class TS_hello : public testing::Test {
protected:
static void SetUpTestCase() {}
static void TearDownTestCase() {}
virtual void SetUp() {}
virtual void TearDown() {}
};

TEST_F (TS_hello, main) {
class hello A;
ASSERT_EQ(1,A.set_i(1));
}

生成可视化结果

1
2
3
4
make
./gtests
lcov --directory ./ --capture --output-file ./gtest/app.info
genhtml -o ./gtest/results ./gtest/app.info

此时运行结果就在gtest/results/index.html下了,这是个可以直接打开的网页

示例图

福利脚本

我同事做了个shell脚本,利用这个脚本能够很轻松的生成结果,也贴在这里

福利脚本

d选项是项目路径

c选项是生成单元测试代码模版,例如hello就是生成gtest_hello.cc,不加这个选项就能自动生成可视化分析页面

g选项是指定gtest代码路径(build目录上一级)

1
2
./run_gtest.sh -d ./ -g /root/googletest -c hello
./run_gtest.sh -d ./ -g /root/googletest