(承上篇)
3.2 如何解决“做不了”
上面我们只是用一个独立的函数来演示ETDD过程。在实际的工作中,代码之间通常是互相依赖的,这种依赖关系会造成测试难于进行,这就是“做不了”的问题。
我们首先来分析一下。“做不了”主要是指可测性问题。可测性问题的核心是内部输入。在解释内部输入前,我们先来看一下一般的输入:外部输入。
外部输入是指在被测代码的外部可以设定的输入,包括参数、成员变量、全局变量。外部输入一般可以直接设定。![单元测试实践的主要问题与解决(5)_c](http://hi.csdn.net/attachment/201112/15/0_1323916485J5z8.gif)
单元测试的核心难点在于内部输入,什么是内部输入呢?
像下面这个例子,这两个数据,都是在被测试代码的内部,通过调用关联代码来取得,也就是内部取得的数据。对于内部取得的数据,代码要如何处理呢?跟参数一样,也是分类处理。因此,测试时也要分类检测,这就是内部输入。
![单元测试实践的主要问题与解决(5)_测试_02](http://hi.csdn.net/attachment/201112/15/0_13239165617MEe.gif)
内部输入有六种情形,我们利用工具都可以处理。
![单元测试实践的主要问题与解决(5)_工具_03](http://hi.csdn.net/attachment/201112/15/0_1323916628M9SB.gif)
解决内部输入的主要方法有打桩、模拟对象、底层模拟。
先来介绍打桩。桩就是代替真实代码的一些代码。桩的功能主要有隔离、补齐和控制。可以通过编写桩代码,来解决内部输入问题。这是桩的控制功能。
![单元测试实践的主要问题与解决(5)_单元测试_04](http://hi.csdn.net/attachment/201112/15/0_1323916693G1P3.gif)
用打桩来解决内部输入,有一些问题:一是编写桩代码增加了工作量;二是内部输入和外部输入分离,难于管理;三是只能解决部分内部输入问题。例如,要在一个用例中多次调用同一关联函数,要求每次输出不同,桩代码就很难做到。
![单元测试实践的主要问题与解决(5)_工作_05](http://hi.csdn.net/attachment/201112/15/0_1323916812wLz7.gif)
解决内部输入的另一个方法是模拟对象,这个比较复杂,另外,对于C和C++也不太适用。我们可以采用底层模拟来解决内部输入问题。
底层模拟有三个特点:一是内部输入与外部输入一起管理;二是不需要考虑关联代码的状态,无所关联代码是否存在,是否隔离,都可以直接使用;三是不需要编写代码。
下面我也用一个案例来讲解一下底层模拟。这个示例,是一个空调控制程序。
代码的功能,是首先取得环境的温度,然后与预设的目标温度比较,计算出温度差,温度每差一度,制冷器运行60秒。![单元测试实践的主要问题与解决(5)_c_06](http://hi.csdn.net/attachment/201112/15/0_1323916939oFk2.gif)
首先,我们设定外部数据。假设,预设的目标温度是25度,是这个全局变量,设为25。返回值为1,表示操作成功。假设环境温度是28度,那么,制冷器应该运行180秒,这里填180。然后执行测试。
![单元测试实践的主要问题与解决(5)_工具_07](http://hi.csdn.net/attachment/201112/15/0_1323917108voRm.gif)
由于环境温度还没有设定,测试进行不下去。环境温度由这个函数来取得。即使这个函数可以正常工作,取到的环境温度也不可能满足我们的测试需求。我们可以用底层模拟来解决。
![单元测试实践的主要问题与解决(5)_测试_08](http://hi.csdn.net/attachment/201112/15/0_13239171754HHp.gif)
(未完待续)