简介

  • C++17代码整洁之道阅读笔记

第二章 构建安全体系

2.3 单元测试

  • 单元测试是一小段代码,在特定上下文环境中,单元测试能够执行产品的一部分代码。单元测试能够在很短的时间内,展示出你的代码是否达到了预期的运行结果。

  • 单元测试框架

    • C++的单元测试框架有很多种,例如: CppUnit, Boost.Test, CUTE, Google Test等
    • 一般而言,几个单元测试框架的集合成为xUnit,所有遵循所谓的xUnit的基本设计的单元测试的框架,其结构和功能都是从Smalltalk的SUnit集成而来的。

2.5 良好的单元测试原则

  • 单元测试的代码的质量
    • 高质量的要求产品代码,同样高质量的要求单元测试的代码。更进一步的讲,理论上,产品代码和测试代码之间不应该有任何区别
  • 单元测试的命名
    • 如果单元测试失败,开发人员希望立即知道以下信息:
      • 测试单元的名称是什么?谁的单元测试失败了?
      • 单元测试测试了什么?单元测试的环境是怎么样的(测试场景)
      • 预期的单元测试结果是什么?单元测试失败的实例测试结果又是什么
    • 因此,单元测试的命名需要具备直观性和描述性,这是非常重要的
  • 首先,以这样的方式命名单元测试模块(依赖于单元测试框架,称为测试用具或者测试夹具)是很好的做法,这样单元测试代码很容易衍生于单元测试框架。单元测试应该有一个像 Test的名字,很显然,必须用测试对象的名字来替换 占位符
  • 例如,如果被测试的系统(SUT)是Money单位,与该测试单元对应的单元测试夹具,以及所有的单元测试用例都应该命名为MoneyTest
  • 除此之外,单元测试必须有直观的且易理解的名称,如果单元测试的名称或多或少没有意义,那么单元测试的名称不会有太大的帮助。通过下面的建议,可以为单元测试取一个好名字
    • 一般来说,可以在不同场景下使用多种用途的类,一个直观的且易理解的名称应该包含以下三点:
      • 单元测试的前置条件,也就是执行单元测试之前的SUT的状态
      • 被单元测试测试的部分,通常是被测试的过程,函数或者方法(API)的名称
      • 单元测试预期的测试结果
    • 遵循以上三点建议,测试过程或方法的单元测试命名的模板,如下所示
      • __
    • 示例
      • void CustomerCacheTest::cacheIsEmpty_addElement_sizeIsOne();
      • void MoneyTest::giveTwoMoneyObjectsWithDifferentBalance_theInequalityComparison_Works();
    • 另一个构建直观的且易理解的单元测试名称的方法,就是在单元测试名称中显示特定的需求。这样的单元测试的名称通常能够反应应用程序域的需求
    • 示例
      • void UserAccountTest::creatingNewAccountWithExistingEmailAddressThrowsException();
      • void BookInventoryTest::aBookThatIsAlreadyBorrowedCanNotBeBorrowedTwice();
    • 几乎所有的单元测试框架都会把失败的单元测试名称输出到标准输出
  • 单元测试的独立性
    • 每个单元测试和其他的单元测试都必须是独立的。如果单元测试之间是以特定的顺序指定的,那么这将是致命的
    • 永远不要编写 一个单元测试的输出是另一个单元测试的输入 的单元测试。当离开一个单元测试的时候,不应该改变测试单元的状态,这是后续单元测试执行的先决条件
  • 单元测试环境的独立初始化
    • 在运行所有单元测试时,每个单元测试都必须是应用程序的一个独立的可运行的实例,每个单元测试都必须完全自行设置和初始化其所需的环境,着同样适用于执行单元测试后的清理工作。
  • 不对getters和setter做单元测试

  • 不对第三方代码做单元测试
    • 我们可以预测第三方代码都有自己的单元测试。在你的项目中,不使用那么没有自己的单元测试和质量可疑的库或框架,这是一种明智的架构选择。
  • 不对外部系统做单元测试。

  • 如何处理数据库的访问
    • 能不使用数据库进行单元测试,就不使用数据库进行单元测试。
    • 只在内存中执行所有的单元测试。
    • 单元测试不要访问数据库,磁盘,网络等外设
    • 数据库测试不是单元测试的内容,它是系统集成和系统测试级别的内容
  • 不要混淆测试代码和产品代码

  • 测试必须快速执行

第三章 原则

  • 我建议学生们把更多的精力放在学习基本思想上,而不是新技术上,因为新技术在他们毕业之前就有可能过时,而基本思想则永远不会过时。

  • 一般来说,不仅是软件开发,把生活中的一切事情变得尽可能简单并不一定都是坏事。
  • 也就是说,下面这些原则我们不应该学一次就忘掉,建议熟练掌握它们。这些原则非常重要,理想情况下,它们会成为每个开发人员的第二天性。