当前位置:首页>技术文章 > 单元测试实践的主要问题与解决(三)
技术文章| Articles
相关文章
单元测试实践的主要问题与解决(三)
发布时间:2014-01-25 22:11:53
(承上篇)
3.2 如何解决“做不了”
上面我们只是用一个独立的函数来演示ETDD过程。在实际的工作中,代码之间通常是互相依赖的,这种依赖关系会造成测试难于进行,这就是“做不了”的问题。
我们首先来分析一下。“做不了”主要是指可测性问题。可测性问题的核心是内部输入。在解释内部输入前,我们先来看一下一般的输入:外部输入。
外部输入是指在被测代码的外部可以设定的输入,包括参数、成员变量、全局变量。外部输入一般可以直接设定。
单元测试的核心难点在于内部输入,什么是内部输入呢?
像下面这个例子,这两个数据,都是在被测试代码的内部,通过调用关联代码来取得,也就是内部取得的数据。对于内部取得的数据,代码要如何处理呢?跟参数一样,也是分类处理。因此,测试时也要分类检测,这就是内部输入。
解决内部输入的主要方法有打桩、模拟对象、底层模拟。
先来介绍打桩。桩就是代替真实代码的一些代码。桩的功能主要有隔离、补齐和控制。可以通过编写桩代码,来解决内部输入问题。这是桩的控制功能。
解决内部输入的另一个方法是模拟对象,这个比较复杂,另外,对于C和C++也不太适用。我们可以采用底层模拟来解决内部输入问题。
底层模拟有三个特点:一是内部输入与外部输入一起管理;二是不需要考虑关联代码的状态,无所关联代码是否存在,是否隔离,都可以直接使用;三是不需要编写代码。
下面我也用一个案例来讲解一下底层模拟。这个示例,是一个空调控制程序。
代码的功能,是首先取得环境的温度,然后与预设的目标温度比较,计算出温度差,温度每差一度,制冷器运行60秒。
上面演示的是简单类型的底层模拟,复杂类型也一样可以模拟,下面我演示一下。
这个底层函数返回的是一个对象指针,如何模拟呢?双击函数名,打开底层模拟器。
这是模拟的结果。
复杂对象的数据一样可以移到表格中,这时,要移到表格中的不是对象本身,而是对象中包含的数据。例如,要把data.ui移到表格中,双击它的值“1234”就行了。
例如,以下函数处理的是由界面输入的数据,这也是单元测试的一个难点。可以使用局变数据模拟,把界面输入转换成普通的内部输入。
这个函数的逻辑功能是计算SQL字符串,但计算结果没有输出到外部,这是内部输出,工具也可以判断内部输出是否正确。
从而实现单元测试的目标:无论别人怎么样,我总是对的! 如果所有代码单元都做到了这一点,那会怎么样呢?整个项目就没有代码错误。
来看看嵌入式测试。在设备上进行单元测试不仅难度大、成本高,也无法达到应有的效果。如果在设备上测试,设备的一些输出是难于控制的,例如这个例子,假设只有在发生雷击时,获取前车距离的函数才会返回失败,那我们是不是等着雷击呢?
即使不考虑成本,嵌入式单元测试也应该在PC上进行,这样才能做到“我总是对的”。
(未完待续)