`

你能测试你的代码吗

阅读更多

 

在敏捷开发的理念被越来越多的人接受,实践,另一个名字也逐渐被人们熟悉:TDD TDDTest Drive Development,测试驱动开发。在实践你的代码前,你应该先实现针对代码的测试代码。

测试驱动的好出显而易见: 用了丰富而全面的测试代码,可以保证你的代码的质量。在修复了一个bug后,你如何保证你的改动没有破坏以前的实现?没有引入新的bug?你制作的第三方库发布了一个新版本,你如何保证某些方法的行为和这个方法的前一个版本是一致的?答案就是完整的丰富的持久的测试。

我们不谈系统测试,集成测试,压力测试,我们谈单元测试。大的程序由小的代码片段构成,正如每一所房子都由一块块的砖构建。但是,你能保证你提交的那一小段代码片段的行为么?它的行为可预测么,或者说,给定一个输入,你能确定它的真实输出吗?

这时候,你该问问你自己:我能测试这段代码吗?

这是一个简单的问题,这也是一个有趣的问题。当我第一次由衷的,不是为了应付所谓的TDD实践,问自己时,我着实被自己吓到了。

因为我的代码里,有很多方法是无法被测试的。因为,有很多方法要从外部资源获得数据,也许是读取配置文件,也许是打开一个数据库连接,或者从socket中读取字节流;因为,有很多方法都没有输出,仅仅是为了对传入的参数做些改变,或者只是为了打印些数据。你应该注意了,当你觉得对一个方法的测试无法入手的时候,你应该考虑,我是否应该重写这段代码,让它更容易被测试呢?

这时候,你该问问自己:这段代码是不是承担了太多任务呢?

你只是想从配置文件里读取文本,然后解析每一行的文件进行配置,那你就该让一个方法负责读取文件,产生一个文本流,而另一个方法只负责解析一行字符串,解析后返回结果。现在,写你的测试用例吧!你完全可以保证你的方法对每一行输入是否产生了你期望的输出!至于文件读取,如果文件格式正确的,那么你的解析方法99%会按照你期望的行为工作,你对代码的正确性的信心是不是增加了呢?

如果你只是想依赖某些void函数对参数做些操作,我希望你能接受下函数式编程的观点:方法就是input->output,这会让你更容易写出测试用例和健壮的代码。如果这个方法仅仅是打印些内容,那么,你就该将print作为内容的消费者,而产生print的方法是生产者。针对生产者的测试会更容易开展。

当你写完代码时,问问自己:“我能测试这段代码吗”,你就在追求代码之美的路上,又前进了一步。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics