Description: 这篇文章简明介绍了 google 开源的一款 C++ 方向的测试框架 Gtest 的使用方法做简单介绍,为后续整理发布的数据库引擎开发项目(目前还没发布到博客中)做单元,模块测试方面的技术支撑。
G-Test 的安装
- 通过 github 页面下载 gtest 的源码压缩包,命令如下
$wget https://github.com/google/googletest/archive/master.zip
- 解压之后,在目录下面看到 CMakeList.txt 文件,可知使用的是 cmake 编译工具,保证虚拟机处于联网(NAT模式),输入命令下载 cmake 编译工具
$apt-get install cmake
- 下载 cmake 结束之后,测试其是否能够正常工作
$cmake
如果正常工作会显示如下内容
Usage
cmake [options]
cmake [options]
Options -C = Pre-load a script to populate the cache.
编译安装 gTest
$ mkdir cmake_dir
$ cd cmake_dir
$ cmake ../
正确编译,显示信息如下
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
...
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: /gTester/googletest-master/cmake_dir
在这里我们创建 cmake_dir 文件夹,并在该文件夹的下面执行 cmake 操作的目的是为了让 cmake 编译生成的中间文件与下载的 gTest 的项目文件二者之间分离开,不然会混淆. 在 cmake_dir 文件夹中生成的中间文件如下:
CMakeCache.txt CMakeFiles cmake_install.cmake CTestTestfile.cmake googlemock Makefile
继续输入 make && make install 来安装 gTest,如正确编译安装显示信息如下:
Scanning dependencies of target gmock
[ 14%] Building CXX object googlemock/CMakeFiles/gmock.dir/__/googletest/src/gtest-all.cc.o
[ 28%] Building CXX object googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o
Linking CXX static library libgmock.a
...
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libgmock.a
-- Installing: /usr/local/lib/libgmock_main.a
-- Installing: /usr/local/include/gmock
-- Installing: /usr/local/include/gmock/gmock-generated-actions.h
-- Installing: /usr/local/include/gmock/gmock-cardinalities.h
-- Installing: /usr/local/include/gmock/gmock-actions.h
...
gTest 的入门级使用例子
- 使用 gTest 来编写最简单的测试用例
- 首先编写 C++ 文件
// test.hpp
#ifndef TEST_HPP__
#define TEST_HPP__
int getValue(int _value);
#endif
// test.cpp
#include "test.hpp"
#include
int getValue( int _value ){
return _value ;
}
- 编写包含 gTest库函数的 C++ 测试文件
#include "test.hpp"
#include "gtest/gtest.h"
// first we test ASSERT_TRUE
void test_ASSERT_TRUE(){
ASSERT_TRUE(false) ;
}
void test_EXPECT_TRUE(){
EXPECT_TRUE(false) ;
}
int main( void ){
test_EXPECT_TRUE();
return 0;
}
- 编写 Makefile 文件
GTEST_DIR=/gTester/googletest-master/googletest
USER_DIR= ./
CPPFLAGS += -I$(GTEST_DIR)/include
CXXFLAGS += -g -Wall -Wextra
TESTS = test_tester
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
$(GTEST_DIR)/include/gtest/internal/*.h
all : $(TESTS)
clean :
rm -f $(TESTS) *.a *.o
GTEST_SRCS_= $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
gtest-all.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest_main.cc
gtest.a : gtest-all.o
$(AR) $(ARFLAGS) $@ $^
gtest_main.a : gtest-all.o gtest_main.o
$(AR) $(ARFLAGS) $@ $^
test.o : $(USER_DIR)/test.cpp $(USER_DIR)/test.hpp $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/test.cpp
test_tester.o : $(USER_DIR)/test_tester.cpp $(USER_DIR)/test.hpp $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/test_tester.cpp
test_tester : test.o test_tester.o gtest_main.a
$(CXX) $(CPPFLAGS) $(CXXFLAG) -pthread $^ -o $@
- 输入 make 命令生成可执行文件 test_tester
- 运行 gTest 的测试文件,查看输出结果
.//test_tester.cpp:12: Failure
Value of: false
Actual: false
Expected: true
gTest 中断言介绍
ASSERT_* 的断言函数如果判定最终结果不满足判定输出值,将会发出 断言失败 + 终止程序的结果
EXPECT_* 的断言函数如果判断最终结果不满足判定输出值,将仅会发出 断言失败 的提示信息
基本断言说明
ASSERT_TRUE (condition);
ASSERT_FALSE (condition) ;
上述断言函数是这样的: 括号中的 condition 可以是一个返回结果为布尔值的函数,也可以是一个不二变量,同样也可以是一个逻辑表达式,只要最终返回的结果是布尔值就可以。而两个函数 ASSERT_TRUE 要求这个布尔值必须是 TRUE/真值,如果不是真便会输出'致命错误'并退出当前正在执行的函数。 ASSERT_FALSE 方法刚好相反,它期待的是一个 FALSE/假值,如果不满足同样输出'致命错误'信息,并退出当前正在执行的方法(程序)。
EXPECT_TRUE(condition) ;
EXPECT_FALSE(condition) ;
上述函数的断言是这样的: 如果括号中的 condition 变量返回的布尔值与断言期待的布尔值不同的话,不会退出当前正在执行的方法/程序。 它会继续允许程序的继续运行,但是会输出执行错误的提示信息(如果错误信息流定向是控制台显示器的话)
### 基于两值比较的断言函数说明
+ 在基于而知比较的断言函数中,传入的参数必须要满足下面两种条件中的一种
+ 是基本类型,可以直接进行逻辑比较
+ 如果是符合类似(class ,struct)是需要重载比较运算符的
+ 需要注意的是,如果传入的是指针类型的话,判定的并不是指针指向的数值内容是否相同,而是会判定指针是否指向同一块内存空间
+ 如果需要判定指针指向字符串的逻辑关系,不要使用这一系列的断言函数
ASSERT_EQ(expected, actual) ; expected==actual
ASSERT_NE(expected, actual) ; expected!=actual
ASSERT_LT(expected, actual) ; expected 小于 actual, LT(less than)
ASSERT_LE(expected, actual) ; expected 小于等于 actual, LE(less equal)
ASSERT_GT(expected, actual) ; expected 大于 actual, GT(greater than)
ASSERT_GE(expected, actual) ; expected 大于等于 actual, GE(greater equal)
EXPECT_EQ(expected, actual) ;
EXPECT_NE(expected, actual) ;
EXPECT_LT(expected, actual) ;
EXPECT_LE(expected, actual) ;
EXPECT_GT(expected, actual) ;
EXPECT_GE(expected, actual) ;
基于字符串的比较断言说明
ASSERT_STREQ(str1,str2); str1's content = str2's content
ASSERT_STRNE(str1,str2); str1's content != str2's content
ASSERT_STRCASEEQ(str1,str2); str1's content = str2's content ,ignoring characters case
ASSERT_STRCASENE(str1,str2); ignoring string characters' case, str1's content != str2's content