Skip to content

设计

通过前面的学习,你可能认为 TDD 只要遵循三法则即可万事大吉。事实远非如此。TDD 的水很深,需要旷日持久的学习才能掌握。

接下来我们将从软件层面检视 TDD。

测试数据库

数据库测试的规则如下:

  1. 不要测试数据库。
  2. 将数据库从业务规则解耦。

对于规则一,我们没必要测试数据库,可以假定数据库正常工作。如果不正常,你很快就会发现。

对于规则二,可以使用接口的方式进行解耦的工作。

当我们测试数据库时,注意不要使用生产数据库做测试。创建刚好有足够数据行数的测试数据库,证明测试有效。备份这个数据库。在运行测试之前,恢复数据库,这样测试总能操作同样的数据。

测试 GUI

GUI 测试的规则如下:

  1. 不要测试 GUI。
  2. 测试 GUI 之外的其他所有部分。
  3. GUI 比你想象得要小。

对于规则一和二,GUI 大多是非常易变的模块。测试 GUI 很有可能是在浪费时间,因为那部分代码会频繁变动,测试也很难持续有效。

对于规则三,GUI 只是软件中很小的元素,用来在屏幕上呈现信息。

测试模式

有很多种测试模式,接下来介绍可能是最有用的三种。

专为测试创建子类

专为测试创建子类基本上被当作一种安全机制来使用。测试可以询问安全的类对象,检查不安全的方法是否确实被调用了。

有时,为测试编写子类的目的不在于安全,而在于便利和吞吐量。例如,你也许不希望被测试的方式启动新进程,或者不希望其执行成本高昂的运算。

自励

自励(Self-Shunt)模式下,既然测试类是一个类,将其设计成测试对象的子类常常很方便。

切记,当采用这种模式时,不同的测试框架每次会构造出不同的测试类。

HUMBLE OBJECT

跨越硬件边界通信的代码很难测试。而 Humble Ojbect(小角色对象)模式是一种妥协方案。这种模式承认有些代码不能被切实地测试,目标是将代码弄到简单到不需要测试。

测试设计

脆弱测试问题

TDD 新手程序员的难题之一是脆弱测试。如果对生产代码的小改动导致多个测试失败,则测试集就是脆弱的。如果对某个小模块的一些小修改导致其他模块的大量修改,就会出现明显的设计问题。小修改造成大破坏,就是低劣设计。

一一对应

测试与生产代码之间的一一对应关系会导致非常强的耦合和脆弱性,因此:

  1. 将测试的结构与生产代码的结构解耦。

具体 vs 通用

  1. 测试越具体,代码越通用。

转换优先顺序

  1. 如果变换操作得到不够好的解决方案,试试另一种变换操作。

变换模式之间的优先顺序:

  • {} -> Nil
  • Nil -> Constant
  • Constant -> Variable
  • Unconditional -> Selection
  • Value -> List
  • Selection -> Iteration
  • Statement -> Recursion
  • Value -> Mutated Value

Released under the MIT License.