gtest功能测试一
一、前言
这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:
1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。
2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。
二、示例
// int型比较,预期值:3,实际值:Add(1, 2)
EXPECT_EQ(3, Add(1, 2))
//
假如你的Add(1, 2) 结果为4的话,会在结果中输出:
g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(16): error: Value of: Add(1, 2)
Actual: 4
Expected:3
如果是将结果输出到xml里的话,将输出:(关于将结果输出为xml,见:http://www.cnblogs.com/coderzh/archive/2009/04/10/1432789.html)
<testcase name="Demo" status="run" time="0" classname="AddTest">
<failure message="Value of: Add(1, 2) Actual: 4 Expected: 3" type=""><![CDATA[g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp:16
Value of: Add(1, 2)
Actual: 4
Expected: 3]]></failure>
</testcase>
如果你对自动输出的出错信息不满意的话,你还可以通过操作符<<将一些自定义的信息输出,通常,这对于调试或是对一些检查点的补充说明来说,非常有用!
下面举个例子:
如果不使用<<操作符自定义输出的话:
for (int i = 0; i < x.size(); ++i)
{
EXPECT_EQ(x[i], y[i]);
}
看到的结果将是这样的,你根本不知道出错时 i 等于几:
g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(25): error: Value of: y[i]
Actual: 4
Expected: x[i]
Which is: 3
如果使用<<操作符将一些重要信息输出的话:
for (int i = 0; i < x.size(); ++i)
{
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}
从输出结果中就可以定位到在 i = 2 时出现了错误。这样的输出结果看起来更加有用,容易理解:
g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(25): error: Value of: y[i]
Actual: 4
Expected: x[i]
Which is: 3
Vectors x and y differ at index 2
三、布尔值检查
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_TRUE(condition); | EXPECT_TRUE(condition); | condition is true |
| ASSERT_FALSE(condition); | EXPECT_FALSE(condition); | condition is false |
四、数值型数据检查
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_EQ(expected, actual); | EXPECT_EQ(expected, actual); | expected == actual |
| ASSERT_NE(val1, val2); | EXPECT_NE(val1, val2); | val1 != val2 |
| ASSERT_LT(val1, val2); | EXPECT_LT(val1, val2); | val1 < val2 |
| ASSERT_LE(val1, val2); | EXPECT_LE(val1, val2); | val1 <= val2 |
| ASSERT_GT(val1, val2); | EXPECT_GT(val1, val2); | val1 > val2 |
| ASSERT_GE(val1, val2); | EXPECT_GE(val1, val2); | val1 >= val2 |
五、字符串检查
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_STREQ(expected_str, actual_str); | EXPECT_STREQ(expected_str, actual_str); | the two C strings have the same content |
| ASSERT_STRNE(str1, str2); | EXPECT_STRNE(str1, str2); | the two C strings have different content |
| ASSERT_STRCASEEQ(expected_str,actual_str); | EXPECT_STRCASEEQ(expected_str,actual_str); | the two C strings have the same content, ignoring case |
| ASSERT_STRCASENE(str1, str2); | EXPECT_STRCASENE(str1, str2); | the two C strings have different content, ignoring case |
*STREQ*和*STRNE*同时支持char*和wchar_t*类型的,*STRCASEEQ*和*STRCASENE*却只接收char*,估计是不常用吧。下面是几个例子:
TEST(StringCmpTest, Demo)
{
char* pszCoderZh = "CoderZh";
wchar_t* wszCoderZh = L"CoderZh";
std::string strCoderZh = "CoderZh";
std::wstring wstrCoderZh = L"CoderZh"; EXPECT_STREQ("CoderZh", pszCoderZh);
EXPECT_STREQ(L"CoderZh", wszCoderZh); EXPECT_STRNE("CnBlogs", pszCoderZh);
EXPECT_STRNE(L"CnBlogs", wszCoderZh); EXPECT_STRCASEEQ("coderzh", pszCoderZh);
//EXPECT_STRCASEEQ(L"coderzh", wszCoderZh); 不支持 EXPECT_STREQ("CoderZh", strCoderZh.c_str());
EXPECT_STREQ(L"CoderZh", wstrCoderZh.c_str());
}
六、显示返回成功或失败
直接返回成功:SUCCEED();
返回失败:
| Fatal assertion | Nonfatal assertion |
| FAIL(); | ADD_FAILURE(); |
TEST(ExplicitTest, Demo)
{
ADD_FAILURE() << "Sorry"; // None Fatal Asserton,继续往下执行。 //FAIL(); // Fatal Assertion,不往下执行该案例。 SUCCEED();
}
七、异常检查
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_THROW(statement, exception_type); | EXPECT_THROW(statement, exception_type); | statement throws an exception of the given type |
| ASSERT_ANY_THROW(statement); | EXPECT_ANY_THROW(statement); | statement throws an exception of any type |
| ASSERT_NO_THROW(statement); | EXPECT_NO_THROW(statement); | statement doesn't throw any exception |
例如:
int Foo(int a, int b)
{
if (a == 0 || b == 0)
{
throw "don't do that";
}
int c = a % b;
if (c == 0)
return b;
return Foo(b, c);
} TEST(FooTest, HandleZeroInput)
{
EXPECT_ANY_THROW(Foo(10, 0));
EXPECT_THROW(Foo(0, 5), char*);
}
八、Predicate Assertions
在使用EXPECT_TRUE或ASSERT_TRUE时,有时希望能够输出更加详细的信息,比如检查一个函数的返回值TRUE还是FALSE时,希望能够输出传入的参数是什么,以便失败后好跟踪。因此提供了如下的断言:
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_PRED1(pred1, val1); | EXPECT_PRED1(pred1, val1); | pred1(val1) returns true |
| ASSERT_PRED2(pred2, val1, val2); | EXPECT_PRED2(pred2, val1, val2); | pred2(val1, val2) returns true |
| ... | ... | ... |
Google人说了,他们只提供<=5个参数的,如果需要测试更多的参数,直接告诉他们。下面看看这个东西怎么用。
bool MutuallyPrime(int m, int n)
{
return Foo(m , n) > 1;
} TEST(PredicateAssertionTest, Demo)
{
int m = 5, n = 6;
EXPECT_PRED2(MutuallyPrime, m, n);
}
当失败时,返回错误信息:
error: MutuallyPrime(m, n) evaluates to false, where
m evaluates to 5
n evaluates to 6
如果对这样的输出不满意的话,还可以自定义输出格式,通过如下:
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_PRED_FORMAT1(pred_format1, val1);` | EXPECT_PRED_FORMAT1(pred_format1, val1); | pred_format1(val1) is successful |
| ASSERT_PRED_FORMAT2(pred_format2, val1, val2); | EXPECT_PRED_FORMAT2(pred_format2, val1, val2); | pred_format2(val1, val2) is successful |
| ... | ... |
用法示例:
testing::AssertionResult AssertFoo(const char* m_expr, const char* n_expr, const char* k_expr, int m, int n, int k) {
if (Foo(m, n) == k)
return testing::AssertionSuccess();
testing::Message msg;
msg << m_expr << " 和 " << n_expr << " 的最大公约数应该是:" << Foo(m, n) << " 而不是:" << k_expr;
return testing::AssertionFailure(msg);
}
TEST(AssertFooTest, HandleFail)
{
EXPECT_PRED_FORMAT3(AssertFoo, 3, 6, 2);
}
失败时,输出信息:
error: 3 和 6 的最大公约数应该是:3 而不是:2
是不是更温馨呢,呵呵。
九、浮点型检查
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_FLOAT_EQ(expected, actual); | EXPECT_FLOAT_EQ(expected, actual); | the two float values are almost equal |
| ASSERT_DOUBLE_EQ(expected, actual); | EXPECT_DOUBLE_EQ(expected, actual); | the two double values are almost equal |
对相近的两个数比较:
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_NEAR(val1, val2, abs_error); | EXPECT_NEAR(val1, val2, abs_error); | the difference between val1 and val2 doesn't exceed the given absolute error |
同时,还可以使用:
EXPECT_PRED_FORMAT2(testing::FloatLE, val1, val2);
EXPECT_PRED_FORMAT2(testing::DoubleLE, val1, val2);
十、Windows HRESULT assertions
| Fatal assertion | Nonfatal assertion | Verifies |
| ASSERT_HRESULT_SUCCEEDED(expression); | EXPECT_HRESULT_SUCCEEDED(expression); | expression is a success HRESULT |
| ASSERT_HRESULT_FAILED(expression); | EXPECT_HRESULT_FAILED(expression); | expression is a failure HRESULT |
例如:
CComPtr shell;
ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application"));
CComVariant empty;
ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));
十一、类型检查
类型检查失败时,直接导致代码编不过,难得用处就在这?看下面的例子:
template <typename T> class FooType {
public:
void Bar() { testing::StaticAssertTypeEq<int, T>(); }
};
TEST(TypeAssertionTest, Demo)
{
FooType<bool> fooType;
fooType.Bar();
}
十二、总结
本篇将常用的断言都介绍了一遍,内容比较多,有些还是很有用的。要真的到写案例的时候,也行只是一两种是最常用的,现在时知道有这么多种选择,以后才方便查询。
gtest功能测试一的更多相关文章
- 关于web端功能测试的测试方向
一.功能测试 1.1链接测试 链接是web应用系统的一个很重要的特征,主要是用于页面之间切换跳转,指导用户去一些不知道地址的页面的主要手段,链接测试一般关注三点: 1)链接是否按照既定指示那样,确实链 ...
- GTest Google的一种白盒单元测试框架 开源项目
GTest为google开源的白盒单元测试跨平台测试框架,含丰富的断言.类型参数化测试.死亡测试.以及其他的测试选项设置.文件保存等,以下将对该项目C++的实现进行简要的分析,作为学习记录备份. 基本 ...
- Google C++单元测试框架---Gtest框架简介(译文)
一.设置一个新的测试项目 在用google test写测试项目之前,需要先编译gtest到library库并将测试与其链接.我们为一些流行的构建系统提供了构建文件: msvc/ for Visual ...
- ROS系统C++代码测试之gtest
1. 安装gtestsudo apt-get install libgtest-dev 2.修改CMakeLists.txtfind_package(GTest REQUIRED)uncommend ...
- 几何服务,cut功能测试
关于几何服务 几何服务用于辅助应用程序执行各种几何计算,如缓冲区.简化.面积和长度计算以及投影.在 ArcGIS Server 管理器中启动几何服务之后,您才能够在应用程序开发过程中使用该服务. 问题 ...
- gTest详解
1. 安装使用 1.1 安装 在https://code.google.com/p/googletest/ 下载源码 进入msvc, 注意编译方式, 如果是dll, 选择 gtest-md 编译生成l ...
- google gtest window 平台应用
下载gtest:https://code.google.com/p/googletest/downloads/detail?name=gtest-1.7.0.zip 编译: 会出现的问题:error ...
- Web应用功能测试测试点
做了几年的功能测试,也经手了好几个Web应用的项目,在做项目当中积累了一些经验.在这里我对通用一些功能模块的测试点做个记录,一来梳理一下测试用例设计的思路,以便加快相似项目的测试用例的设计,二来有利于 ...
- gtest学习一:在vs2013中搭建gtest环境
gtest版本:1.7.0,在哪里下载源码就不说了,网上太多了~ 配置过程: 1.下载解压后,进入googletest/msvc目录,直接打开gtest.sln,发现有四个工程:gtest.gtest ...
随机推荐
- amoeba实现MySQL读写分离
amoeba实现MySQL读写分离 准备环境:主机A和主机B作主从配置,IP地址为192.168.131.129和192.168.131.130,主机C作为中间件,也就是作为代理服务器,IP地址为19 ...
- css奇特用法之 IMG添加背景图片配合显示--效果惊艳
IMG标签本身是显示图片的,但通过CSS可以再为其设置背景图片,让其和自身的图片配合来显示,最终的效果会让你惊叹.当然,这个发现来自于老外,所以代码马上与大家分享.再此之前,我也从来没有想到过这个思路 ...
- JS辨别浏览器系统IOS或安卓
详细内容请点击 /* * 智能机浏览器版本信息: * */ (function($,window,document){ $.extend({ browser:{ ...
- CSS3 照片墙
HTML <body> <h2>照片墙制作</h2> <div class="container"> <img class=& ...
- 跟我一起学习ASP.NET 4.5 MVC4.0(五)(转)
前面几篇文章介绍了一下ASP.NET MVC中的一些基础,今天我们一起来学习一下在ASP.NET MVC中控件的封装.在页面中我们会经常使用到Html对象,来程序控件,当然这里的控件不是说ASP.NE ...
- (转)Android面试题
1. 下列哪些语句关于内存回收的说明是正确的? (b ) A. 程序员必须创建一个线程来释放内存 B.内存回收程序负责释放无用内存 C.内存回收程序允许程序员直接释放内存 D.内存回收程序可以在 ...
- iOS - 数组(NSArray)
1. 数组的常用处理方式 //--------------------不可变数组 //1.数组的创建 NSString *s1 = @"zhangsan"; NSString *s ...
- 学习笔记:JavaScript传参方式———ECMAScript中所有函数的参数都是按值传递
我们把命名参数(arguments)视为局部变量,在向参数传递基本类型值时,如同基本类型变量的复制一样,传递一个副本,参数在函数内部的改变不会影响外部的基本类型值.如: function add10( ...
- Nginx在嵌入式系统中的应用
-----------------本文转载自 http://blog.csdn.net/xteda/article/details/39708009 ------------------------- ...
- AJAX项目中的一些总结
最近在做AJAX数据处理交互,遇到一些问题,备份以免以后忘记 1.参数地址问题 确保参数地址的正确性 ; 阅读后台源码,参数和返回值要确定: 一般的大点公司应该有规范: 2.关于ajax事件触发请求多 ...