gtest简介及简单使用

本文摘自 gtest简介及简单使用 ,在此感谢作者的分享. 

具体使用教程

____________________________________________________________________________________________________________________

gtest下载地址(Google已将gtest已放到github上)

在Ubuntu下编译gtest步骤:在gtest-1.7.0.zip目录下,依次执行:unzip gtest-1.7.0.zip ;

cd  gtest-1.7.0 ; ./configure ;  make  ; cd  lib ; mv .libs libs ;此时,会在gtest-1.7.0/lib/libs目录下生成libgtest.a和libgtest_main.a库(说明:gtest-1.7.0/lib下会生成libgtest.la和libgtest_main.la库,.la为libtool生成的共享库,其实是个配置文档。lib下的libs文件刚开始生成时是隐藏文件,需要用mv指令转成正常文件,libs除了libgtest.a和libgtest_main.a库还有其它一些文件,没有什么用,全部删除即可)。

动态库与静态库生成:

对于像gtest这样的工具,编译后需要手动创建静态链接库和动态链接库的,

静态:ar libgtest.a gtest-all.o
动态: g++ -I./ -shared -o libgtest.so.0 gtest-all.o

         Ubuntu下举例:(1)、在gtest-1.7.0同一目录下新建一个test文件;(2)、此test文件夹下存放fun.h和gtest_test.cpp文件,fun.h文件内容与Windows下的fun.h内容完全一致;

         (3)、gtest_test.cpp文件内容为:

 1 #include "../gtest-1.7.0/include/gtest/gtest.h"
 2 
 3 #include "fun.h"
 4 
 5  
 6 
 7 TEST(fun, add)
 8 
 9 {
10 
11     EXPECT_EQ(1, add(2,-1));
12 
13     EXPECT_EQ(5, add(2,3));
14 
15 }
16 
17  
18 
19 int main(int argc, char** argv)
20 
21 {
22 
23     ::testing::InitGoogleTest(&argc, argv);
24 
25     return RUN_ALL_TESTS();
26 
27 }

(4)、将终端定位到/test目录下,输入  g++  -g  gtest_test.cpp -o  gtest_test  -I../gtest-1.7.0/include  -L../gtest-1.7.0/lib/libs  -lgtest  -lgtest_main  -lpthread ;会在/test目录下生成gtest_test执行文件;

(5)、执行 ./gtest_test 输出信息与Windows下一致。

 

更通用的做法是:不必在每个平台下分别编译生成静态库,可以直接使用/fused-src/gtest下的gtest.h和gtest-all.cc两个文件,此两个文件包含了所有你需要用到的Google Test的东西。如果没有/fuse-src这个文件,可以使用/scripts/fuse_gtest_files.py这个文件生成,操作步骤是:(1)、配置好python;(2)、打开命令提示符,将其定位到/scripts文件夹下,输入命令:python  fuse_gtest_files.py fused_gtest ;会在/scripts文件夹下生成一个fused_gtest/gtest文件,里面包含gtest.h和gtest-all.cc两个文件,此两个文件和/fuse-src中的同名文件内容是完全一致的。

 

下面是对gtest的一些总结:

 

1.  TEST(test_case_name, test_name)

TEST_F(test_fixture,test_name)

TEST宏的作用是创建一个简单测试,它定义了一个测试函数,在这个函数里可以使用任何C++代码并使用提供的断言来进行检查。

多个测试场景需要相同数据配置的情况,用TEST_F。

2.  gtest中,断言的宏可以分为两类,一类是ASSERT系列,一类是EXPECT系列。

{ASSERT|EXPECT}_EQ(expected,actual): Tests that expected == actual

{ASSERT|EXPECT}_NE(v1,v2):           Tests that v1 != v2

{ASSERT|EXPECT}_LT(v1,v2):           Tests that v1 < v2

{ASSERT|EXPECT}_LE(v1,v2):           Tests that v1 <= v2

{ASSERT|EXPECT}_GT(v1,v2):           Tests that v1 > v2

{ASSERT|EXPECT}_GE(v1,v2):           Tests that v1 >= v2

EXPECT_*和ASSERT_*的区别:(1)、EXPECT_*失败时,案例继续往下执行;(2)、ASSERT_*失败时,直接在当前函数中返回,当前函数中ASSERT_*后面的语句将不会执行,退出当前函数,并非退出当前案例。

断言:布尔值检查、数值型数据检查、字符串检查、显示成功或失败、异常检查、Predicate Assertions、浮点型检查、Windows HRESULT assertions、类型检查。

3.  ::testing::InitGoogleTest(&argc,argv):gtest的测试案例允许接收一系列的命令行参数,将命令行参数传递给gtest,进行一些初始化操作。gtest的命令行参数非常丰富。

4.  RUN_ALL_TESTS():运行所有测试案例。

5.  可以通过操作符"<<"将一些自定义的信息输出,如在EXPECT_EQ(v1, v2)<< "thisis a error! "

6.  gtest的事件一共有3种:(1)、全局的,所有案例执行前后;(2)、TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后;(3)、TestCase级别的,每个TestCase前后。

全局事件:要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。SetUp方法在所有案例执行前执行;TearDown方法在所有案例执行后执行。

TestSuite事件:需要写一个类,继承testing::Test,然后实现两个静态方法:(1)、SetUpTestCase方法在第一个TestCase之前执行;(2)、TearDownTestCase方法在最后一个TestCase之后执行。

TestCase事件:是挂在每个案例执行前后的,需要实现的是SetUp方法和TearDown方法。(1)、SetUp方法在每个TestCase之前执行;(2)、TearDown方法在每个TestCase之后执行。

每个基于gtest的测试过程,是可以分为多个TestSuite级别,而每个TestSuite级别又可以分为多个TestCase级别。这样分层的结构的好处,是可以针对不同的TestSuite级别或者TestCase级别设置不同的参数、事件机制等,并且可以与实际测试的各个模块层级相互对应,便于管理。

7.  参数化:必须添加一个类,继承testing::TestWithParam<T>,其中T就是你需要参数化的参数类型。

8.  编写死亡测试案例时,TEST的第一个参数,即test_case_name,请使用DeathTest后缀,原因是gtest会优先运行死亡测试案例,应该是为线程安全考虑。

9.  testing::AddGlobalTestEnvironment(newFooEnvironment):在main函数中创建和注册全局环境对象。

10.  对于运行参数,gtest提供了三种设置的途径:(1)、系统环境变量;(2)、命令行参数;(3)、代码中指定FLAG。

命令行参数:(1)、--gtest_list_tests:使用这个参数时,将不会执行里面的测试案例,而是输出一个案例的列表;(2)、--gtest_filter:对执行的测试案例进行过滤,支持通配符;(3)、--gtest_also_run_disabled_tests:执行案例时,同时也执行被置为无效的测试案例;(4)、--gtest_repeat=[COUNT]:设置案例重复运行次数;(5)、--gtest_color=(yes|no|auto):输出命令行时是否使用一些五颜六色的颜色,默认是auto;(6)、--gtest_print_time:输出命令时是否打印每个测试案例的执行时间,默认是不打印的;(7)、--gtest_output=xml[:DIRECTORY_PATH\|:FILE_PATH:将测试结果输出到一个xml中,如—gtest_output=xml:d:\foo.xml  指定输出到d:\foo.xml ,如果不是指定了特定的文件路径,gtest每次输出的报告不会覆盖,而会以数字后缀的方式创建;(8)、--gtest_break_on_failure:调试模式下,当案例失败时停止,方便调试;(9)、--gtest_throw_on_failure:当案例失败时以C++异常的方式抛出;(10)、--gtest_catch_exceptions:是否捕捉异常,gtest默认是不捕捉异常的,这个参数只在Windows下有效。

 

使用举例:

foo.h

#ifndef __FOO_H__
#define __FOO_H__
int max(int a, int b)
{
return a>b?a:b;
}
#endif

foo_test.cpp

#include <bits/stdc++.h>
#include <gtest/gtest.h>
#include "foo.h"

TEST(foo, max)
{
EXPECT_EQ(2, max(2,-1));
EXPECT_EQ(3, max(2,3));
}

int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

makefile

CPP=g++
CPPFLAGS=-g -Wall -std=c++11
LIBS=-L/usr/local/lib/gtest1.7.0 -lgtest_main -lgtest -pthread
INCLUDE=-I. -I/usr/local/include/gtest1.7.0
OBJS= foo_test.o
main:$(OBJS)
#       indent main.cpp -linux
        ${CPP} ${CPPFLAGS} ${INCLUDE} $(OBJS) -o xmain $(LIBS)
clean:
        rm -f xmain *core* *~ ${OBJS}

编译与运行,控制台输入:

$make
$ ./xmain [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from foo [ RUN ] foo.max [ OK ] foo.max (0 ms) [----------] 1 test from foo (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. (0 ms total) [ PASSED ] 1 test.

使用时可能会出现的问题:

1.undefined reference to `pthread_key_create' (linker error)

1) You need to specify -pthread after -lgtest. The linker takes libraries in order, and only takes as much as it needs to resolve references which are undefined at that point.

2) Nope, the problem is with Gtest's build.

If you build it using the standard configure approach, it isn't supplying the -lpthread correctly to create libgtest.so. Hence, when you try building a final shared library that actually uses the pthread capability it fails.

Instead, use the Cmake approach:

cd gtest-1.7.0
mkdir build
cd build
cmake -DBUILD_SHARED_LIBS=ON ..
make 

And then manually install these into /usr/lib/

This version correctly links in libpthread into libgtest.

简要说明

1
2
3
4
TEST(name1, name2)
{
EXPECT_EQ(value1, value2);
}

这是要执行的测试用例,后面是执行内容
name1:测试用例名称
name2:测试名称
这两个参数都只起到提示作用,我们也可以这么使用
name1:类名
name2:方法名
或者
name1:文件名
name2:函数名

EXPECT_EQ(value1, value2);
用例执行成功时,期望value1和value2是相等的,相等才算通过测试,如上例中的:
EXPECT_EQ(2, max(2,-1));
max(2, -1)的执行结果值期望是2如果不等,则用例运行失败。

1
2
3
4
5
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

这个是main函数,InitGoogleTest会初始化一些环境变量,RUN_ALL_TESTS()会调用所有的TEST(name1, name2)

posted @ 2017-09-09 09:28  PKICA  阅读(5062)  评论(0编辑  收藏  举报