1.6提升测试的有效性
当测试团队解决了测试的通过率、稳定性、耗时和覆盖率问题以后,测试的有效性便成为下一个需要解决的问题。
1.6.1测试有效性需要面对的挑战
挑战1:“注水”的成功率和覆盖率
在推动测试的通过率和覆盖率提升的过程中,我们发现,个别工程师的测试用例里有“注水”的行为,例如,校验做得不够,该写的assert没写,甚至还有一些用例,无论代码返回什么结构、抛什么错,用例的执行结果都是通过的。必须防止这种“注水”行为的出现。
我们考虑过的解决方法有:
加强代码评审。但是,代码评审需要工程师的时间、能力和责任心。指望代码评审来发现所有的测试有效性问题也不现实。
对测试代码进行静态代码分析。例如,我们可以识别出被测代码在数据库里,然后解析测试代码,看测试用例是否检查了被测代码库的数据。但这个方法只对一部分的情况比较有效,普适性不强。
靠价值观保证,与绩效考评挂钩:只要发现测试用例有“注水”的情况,写这个测试用例的工程师的当年绩效考评就下调。这个做法的局限性在于:会有很多漏网之鱼,而且等到绩效考评时再改善就太滞后了。
挑战2:谁来测试测试代码
长期以来,一直困扰软件测试专业的一个问题是:“谁来测试测试代码(Whatteststhetestcode)”。
无论是单元测试(UnitTest),还是端到端(End-to-End,E2E)的自动化测试用例,这些测试代码的价值就是让开发人员可以放心地修改应用代码。只要测试是通过的,我们就相信修改后的应用代码是基本正确的。但如果想要修改测试代码,怎么保证修改后的测试代码是基本正确的呢?换句话说,如何确保对于被测系统(SystemUnderTest,SUT)里的任意Bug来说,只要修改前的测试代码能报错,修改后的测试代码就能报错。我们也许可以再写一堆测试代码来测试测试代码,但这堆测试代码又会面临同样的问题。换言之,如何度量测试的有效性(TestEffectiveness)。如果度量都无法做到,那么更谈不上保障和提高了。
测试有效性度量的困难有以下两方面:
传统的测试有效性的定义是:测试有效性=测试中发现的Bug数/(测试中发现的Bug数+交付后发现的Bug数)。但是按照这个定义,度量是滞后的,而且由于依赖人工上报、收集Bug,这个度量数据存在比较大的误差。
测试有效性不能靠代码覆盖率来度量。即使修改后的测试代码的代码覆盖率和修改前的代码覆盖率是一样的,也不等于修改后的代码的“抓Bug”能力没有下降。即便修改后的测试代码能够正确地抓出所有历史上已知的Bug,也不代表它对那些尚未发生的Bug的捕捉能力和修改前的测试代码是一样的。