说明

被测试代码文件 sample1.h、sample1.cc
测试代码文件 sample1_unittest.cc

官网上如是描述sample1:

Sample #1 shows the basic steps of using Google Test to test C++ functions.

sample1演示了如何使用gtest来对C++函数进行单元测试。

如何把sample1的代码跑起来,请参考我写的另外一篇文章《用Visual Studio创建集成了gtest的命令行工程》(链接:http://www.cnblogs.com/duxiuxing/p/4272343.html)。

理解被测试代码

被测试代码是两个全局函数:

函数名 函数功能
Factorial() 阶乘运算函数
IsPrime() 判断入参是否为质数

理解测试代码:TEST宏

sample1使用了gtest的TEST宏来组织它的测试代码,TEST宏它有两个参数:

  • 参数1:test_case_name,对应于被测试的函数,比如“FactorialTest”对应的被测试函数是“Factorial”;
  • 参数2:test_name,对应于一组可以独立运行的测试代码。

这似乎跟我以往对单元测试的认知有所出入,我以前的理解是:

  • 测试用例(Test Case)是最小的执行单位;
  • 一个或几个测试用例组成一个测试包(Test Suite)。

老牌单元测试框架CppUnit里面也是按照Test Suite和Test Case的概念来组织测试代码的。其实,“gtest的TestCase和Test”and“CppUnit的TestSuite和TestCase”,本质上是一回事,它们只是两套框架内对于相同事物的不同称谓而已。实际上不管你习惯于哪套称谓,在阅读文档的时候有疑问的话,结合上下文,应该也是很容易理解的。

CoderZh的大作《玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest》(链接:http://www.cnblogs.com/coderzh/archive/2009/03/31/1426758.html)中提到:

我们使用了TEST这个宏,它有两个参数,官方的对这两个参数的解释为:[TestCaseName,TestName],而我对这两个参数的定义是:[TestSuiteName,TestCaseName]。

在进行单元测试的时候,我们可以用若干组测试代码,从不同的维度来测试同一个函数,test_case_name和test_name是一对多的关系。这种组织关系从sample1的执行结果很容易看出来:

第1组test case的代码是这么组织的:

被测试的函数 Factorial()
test case name FactorialTest
  - test name 1 Negative:测试入参<0的情况
  - test name 2 Zero:测试入参=0的情况
  - test name 3 Positive:测试入参>0的情况

第2组test case的代码是这么组织的:

被测试的函数 IsPrime()
test case name IsPrimeTest
  - test name 1 Negative:测试入参<0的情况
  - test name 2 Trivial:测几个特殊的入参
  - test name 3 Positive:测试入参>0的情况

理解测试代码:EXPECT_*断言和ASSERT_*断言

对于sample1的两个被测试函数来说,单元测试要做的事情就是:

  1. 设定输入;
  2. 执行被测试函数;
  3. 判断输出是否符合预期。

在“判断输出是否符合预期”这一步,代码中使用了EXPECT_*宏,我们把这类宏称为断言。当一个EXPECT_*断言检查到不符合预期的情况时(简称为“断言失败”),gtest会在屏幕上输出该断言的位置(源文件路径和代码行号)和错误信息。

与EXPECT_*断言一一对应的还有ASSERT_*断言,它们的区别在于:

  • ASSERT_*断言失败时会产生致命失败,并结束当前函数(简单理解就是会调用return)。
  • EXPECT_*断言产生非致命失败,代码会继续往下执行,而不会终止当前函数。

两者的使用场景小结:

  • 通常更推荐使用EXPECT_*断言,因为在同一个测试函数中,可能存在多处断言失败的情况,使用EXPECT_*断言能够发现一次运行中的所有失败情况。
  • 当某个断言失败就没有必要继续往下执行的时候,应该使用ASSERT_*断言。
  • ASSERT_*断言失败会立刻从当前的代码返回,这可能导致当前代码之后的一些“清洁回收”代码没有被执行,进而出现内存泄漏。这种问题一旦发现,是应该通过调整测试代码来修复的。

理解测试代码:检查数值比较结果的断言

Factorial()是一个阶乘运算函数,它的原型如下:

// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.
int Factorial(int n);

对Factorial()进行单元测试的时候,sample1_unittest.cc中使用了一组检查数值比较结果的断言:     

致命断言(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

理解测试代码:检查布尔值的断言

IsPrime()用于判断入参是否为质数 ,它的原型如下:

// Returns true iff n is a prime number.
bool IsPrime(int n);

对IsPrime()进行单元测试的时候,sample1_unittest.cc使用了一组检查布尔值的断言:

致命断言(Fatal assertion) 非致命断言(Nonfatal assertion) 预期结果(Verifies)
ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition is true
ASSERT_FALSE(condition); EXPECT_FALSE(condition); condition is false

 


系列文章索引:http://www.cnblogs.com/duxiuxing/p/4270836.html

解读sample1的更多相关文章

  1. 解读sample5

    说明 被测试代码文件 sample1.h.sample1.cc和sample3-inl.h 测试代码文件 sample5_unittest.cc 官网上如是描述sample5: Sample #5 i ...

  2. 解读sample3

    说明 理解被测试代码 理解测试代码:test fixture简介 编写fixture class TEST_F宏 其他 不应该被忽略的注释 说明 被测试代码文件 sample3-inl.h 测试代码文 ...

  3. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  4. SDWebImage源码解读 之 NSData+ImageContentType

    第一篇 前言 从今天开始,我将开启一段源码解读的旅途了.在这里先暂时不透露具体解读的源码到底是哪些?因为也可能随着解读的进行会更改计划.但能够肯定的是,这一系列之中肯定会有Swift版本的代码. 说说 ...

  5. SDWebImage源码解读 之 UIImage+GIF

    第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...

  6. SDWebImage源码解读 之 SDWebImageCompat

    第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...

  7. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

  8. SDWebImage源码解读之SDWebImageCache(上)

    第五篇 前言 本篇主要讲解图片缓存类的知识,虽然只涉及了图片方面的缓存的设计,但思想同样适用于别的方面的设计.在架构上来说,缓存算是存储设计的一部分.我们把各种不同的存储内容按照功能进行切割后,图片缓 ...

  9. SDWebImage源码解读之SDWebImageCache(下)

    第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...

随机推荐

  1. SpringMVC中文乱码

    刚刚构建的SpringMVC项目,一般都是中文乱码的. 这时的工程就是一个JSP页面的事情,可以添加如下代码 <%@ page language="java" import= ...

  2. composer 说明<转>

    转自  http://blog.csdn.net/zzulp/article/details/18981029 Composer是一个基于项目的依赖管理器,负责将PHP项目所依赖的包或库安装到项目所在 ...

  3. 在imge控件中直接显示图片(图片是byte[]格式)

    在工作过程中遇到了这个问题,在网上查了一些资料,结合自己的解决方法及解决过程总结了下,方面以后查阅.如果能帮到同样遇到这个问题的你,将非常高兴哦~_~ 由于asp.net中的Image控件是在Syst ...

  4. MVC部署出现HTTP 404 错误

    asp.net mvc部署出现问题,http错误404.0,报错如下图: 在网上找了好多方法都不行.最后我的解决方案是: 打好这个补丁就行了http://support.microsoft.com/k ...

  5. (转)织梦dedecms后台发布文章提示“标题不能为空”

    问题症状:V5.7登录后台后,发布英文标题没问题,发布中文会提示“标题不能为空”. 问题根源:htmlspecialchars在php5.4默认为utf8编码,gbk编码字符串经 htmlspecia ...

  6. 【转】 HVTableView创建--展开/折叠列表能 AAShareBubbles社会分享动画组

    原文: http://blog.csdn.net/billfanggs/article/details/17279969 HVTableView HVTableView是UITableView(带有展 ...

  7. iOS 格式化输出符号与类型转换

    1.iOS 格式化输出符号 %@    对象 %d,   %i 整数 %u     无符号整形 %f      浮点(双字节) %x,   %X  二进制整数 %o     八进制整数 %zi     ...

  8. 1.Weblogic通Eclipse调试配置(Weblogic同Eclipse调试配置技术)

    概述:环境是eclipse,maven,svn, 在实际的的应用项目中,我们经常遇到本地应用程序没有问题,而部署到Weblogic上缺出现问题,查看日志并找不到原因,这时就需要调试部署上的程序与本地e ...

  9. c/c++内存机制(一)(转)

    转自:http://www.cnblogs.com/ComputerG/archive/2012/02/01/2334898.html 一:C语言中的内存机制 在C语言中,内存主要分为如下5个存储区: ...

  10. 基于VC的串行通信技术应用实例

    在工业控制中,串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛.   本文将介绍在Windows平台下串行通信的工作机制和用Visual C++设计串行通信程序的 ...