单元测试必须覆盖所测单元的所有代码路径。
问:啊!这样岂不是要写很多啰里啰唆的测试方法?
答:对,因为程序中很多缺陷都是从这些啰里啰唆的错误处理中产生的。如果你的模块中某个错误处理路径很难到达,那你也许要想想是否可以把这个错误处理拿掉。
[大栓:这对于那些爱写复杂代码的人是一个很好的惩罚,不对,是一个很好的锻炼。]
[阿超:对,把单元测试的责任和代码作者绑定在一起后,代码作者就能更真切地体会到复杂代码的副作用,因为验证复杂代码的正确性要困难得多。要注意的一点是:100% 的代码覆盖率并不等同于100% 的正确性,请看下列例子]
e.g.didn’t check return value.
e.g. memory leak
1.4.2.8单元测试应该集成到自动测试的框架中
另一个重要的措施是要把单元测试自动化,这样每个人都能很容易地运行,并且单元测试每天都可以运行。每个人都可以随时在自己机器上运行。团队一般是在每日构建中运行单元测试, 这样每个单元测试的错误就能及时发现并得到修改。
1.4.2.9单元测试必须和产品代码一起保存和维护
单元测试必须和代码一起进行版本维护。如果不是这样,过了一阵,代码和单元测试就会出现不一致,而且所有代码的作者要花时间来确认哪些是程序出现的错误,哪些是由于单元测试更新滞后造成的错误。。。这样就失去了单元测试的意义,同时又给大家增加了负担,折腾多次以后,大家就会觉得维护单元测试是一件很费时费力的事。
1.5BVT 构建验证测试 (Build Verification Test)
望文生义,构建验证测试是指在一个构建完成之后,团队自动运行的一套验证系统的基本功能的测试。大多数情况下,这一套系统都是在自动构建成功后自动运行的,有些情况下也会手工运行,但是由于构建是自动生成的,我们也要努力让BVT自动运行。
问:一个系统有这么多功能点,什么是基本,什么是不基本的?
答:第一,必须能安装;第二,必须能够实现一组核心场景(例如:对于字处理软件来说,必须能打开/编辑/保存一个文档文件,但是一些高级功能.
如: 文本自动纠错, 则不在其中; 又如,网站系统,用户可以注册/上载/下载信息,但是一些高级功能,如删除用户,列出用户参与的所有讨论,则不在其中。
在运行BVT之前,可以运行所有的单元测试, 这样可以保证系统的单元测试和程序员的单元测试版本保持一致。不少情况下,开发人员修改了程序和单元测试,但是忘了把更新的单元测试也同时签入源代码库中。
通过BVT的构建可以称为:可测 (self-test), 意思是说团队可以用这一版本进行各种测试 – 因为它的基本功能都是可用的。通不过BVT的构建称为“不可测”(self-hosed)
如果构建测试不能通过,那么自动测试框架会自动对每一个失败的测试产生一个bug (小强)。一般的做法这些小强都是有最高优先级,是开发人员要首先修改这些小强。大家知道维持每日构建,并产生一个可测的版本是软件开发过程质量控制的基础。对于导致问题的小强,我们该怎么办?
1. 找到导致失败的原因,如果原因很简单,程序员可以马上修改,然后直接提交。
2. 找到导致失败的原因的修改集,把此修改集剔出此版本(程序员必须修改好后再重新提交到源代码库中)。
3. 程序员必须在下一个构建开始前把此小强修理好。
方法1/2都可以使今天的构建成为“可测”,但是有时各方面的修改互相依赖,不能在短时间内解决所有问题,只能采用第三个办法。
问:有人提到一种“smoke test”,冒烟测试,是什么回事?
答:这事实上是一种基本验证测试,据说是从硬件设计行业流传过来的说法 – 当年设计电路板的时候,很多情况下,新的电路板一插上电源就冒起白烟,烧坏了,如果插上电源后没有冒烟,那就是通过了“冒烟测试”,可以进一步测试电路板的功能了。我们正在讨论的BVT也是一种冒烟测试。
1.6功能测试 (functional test)
测试团队拿到一个“可测”等级的构建,他们就会按照测试计划,测试各自负责的模块和功能,这个过程可能会产生总共10来个bug,也可能产生100个以上的bug,那么如何保证我们有效地测试了软件,同时我们在这一步怎样衡量构建的质量?
在“基本场景”的基础上,我们把所有系统目前理论上支持的场景都列出来,然后按功能分类测试,如果测试成功,就在此场景中标明“成功”,否则,就标明“失败”,并且把失败的情况用一个(或几个)“小强”/bug来表示。
当所有的测试人员完成对场景的测试,我们自然地就得出了一个表:
场景ID 场景名 测试结果 Bug/小强id
3024 用户登录 成功
3026 用户按价格排序 失败 5032
3027 用户按名字搜索 失败 5033
…
?… … …
这样我们就能很快地报告“功能测试56% 通过”等等。如果所有场景都能通过,(有些情况下可以把此标准从100% 降低到90% 左右)则这个构建的质量是“可用”,意味着这一个版本可以给用户使用。 这种情况下,客户,合作伙伴可以得到这样的版本 – 这也是所谓“技术预览版”,或“社区预览版”的由来。
但是,有一个重要的问题要大家注意“可用”,并不是指软件都没有bug,而是指在目前的用户场景中,按照场景的要求进行的操作,都能得到预期的效果。
1. 目前还没有定义的用户场景中,程序质量如何,还未得而知。
a. 场景中没有考虑到多种语言设置
2. 不按照场景的要求进行的操作,结果如何,还未得而知。
a. 如:在某一场景中,场景规定用户可以在最后付款前取消操作,回到上一步,如果一个测试人员发现在反复 提交/取消同一访问多次,然后网页出现问题,这并不能说明用户场景失败,当然这个极端的bug也必须找出原因并在适当的时间改正。