作者:吴紫鄂(zewu@live.cn)
测试驱动开发 test-driven development (TDD),在软件开发中得到了越来越广泛的推广,在项目开发的早期重视QA的作用,正确的配置QA将带来前所未有软件质量保障。TDD真正的含义确往往被人们曲解,一个月前项目刚刚起步开始的时候屡次在规划会议上强调TDD,但是时隔一个月,项目的部分模块已经开始编码的时候我却发现大多数人所谓的测试(这里只涉及到程序员内部的白盒测试)还只是停留在使用主观臆断和使用肉眼去观察仅有的几个测试用例,主要存在一下几个误区:
1、没有统一的测试框架,没有注重自动化测试:软件测试不是像我们上学的时候那样写上一段代码,然后随意的配上几个可能的数据,观察一下测试的结果就算测试,统一软件过程更加讲究测试的方法和自动化测试工具的使用,目前可以为游戏开发直接使用的自动化测试工具似乎还没有诞生,但是对于c++本身有很多的测试框架可以提供给我们进行测试夹具、自动化测试的辅助。《Exploring the C++ Unit Testing Framework Jungle 》一文中作者Noel Llopis提供了一个轻量级的Test Framework,并且比较了常见的c++单元测试框架,可以给我们带来很大的启发。
- CppUnit
- Boost.Test
- CppUnitLite
- NanoCppUnit
- Unit++
- CxxTest
2、没有完整的测试计划,没有完善的测试用例(Test Case):仅仅使用一时的主观臆断编写几个简单的测试函数,或者更陀的是改变几个缺省的参数去使用肉眼观察测试结果,这种事情是学生们干的,对于一个职业程序员来讲,一定要有一个测试优先的观念,为我们写的代码提供能完整覆盖所有Case的测试路径,即Test Case。而且像上面介绍的几个Unit Test Framework都提供了测试夹具(Fixture)和测试包(Suite)的概念,可以使得我们能够将我们的Test Case很好的归档,并且通过其通过的Setup和Teardown功能很好地进行自动化测试,至少是半自动化测试。Test Case的归档也为我们以后的维护提供了参考。
3、测试不是一次性的:刚刚写完代码,又挤了点时间写了几个测试函数,运行一下没有发现问题,测试完成……真是要命啦,测试怎么可能是一次性的呢?测试不仅是要有完整的Test Case,而且在每次修改代码之后都应该运行Test Case。
4、测试结果的收集:测试结果也绝不是用肉用所能保证其正确性的,在功能比较少的情况下还能接受,当项目越来越庞大的时候,就必学使用上面提到的类似Unit Test Framework进行测试结果的收集,而且一般都提供能良好的Handles exceptions and crashes 机制。
如果还不明白TDD那就找本最近两年出版的软件工程类的书籍看看,如果还在为Uint Test发愁那就都一下下面的参考资料的文章,如果还在做手动的机械的信赖肉眼的测试工作那就应该赶紧选一个适合自己的轻量级的Unit Test Framework更好地开始工作。总是必须使用自动化测试代替人脑工作。
参考资料
《Exploring the C++ Unit Testing Framework Jungle 》http://www.gamesfromwithin.com/articles/0412/000061.html
《lists of what they wish for in C++ unit-testing frameworks》http://c2.com/cgi/wiki?ConsiderationsForAndComparisonOfCplusplusTestFrameworks