提高测试效率的途径

网友投稿 605 2022-11-19

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

提高测试效率的途径

1、提高测试效率的基本思路

2、减少测试时间

要减少测试时间,首先要弄清楚哪些环节消耗时间最多,然后才能对症下药。单元测试最耗时的环节有:编写测试代码、建立测试用例、找出遗漏用例。

测试代码具有很多固定的内容,例如都要建立和销毁被测试对象,执行被测试程序等,这些代码完全可以由工具自动生成,测试人员只要设定测试用例的输入输出就行了。

如果测试用例也由工具自动生成当然最省时,可惜这是不现实的,因为测试工具不能自动了解程序的功能,只能依靠参数的数据类型之类的信息生成测试用例,生成的用例和实际需要往往相差很远。用工具自动生成大量测试用例然后手工修改怎么样?听起来不错,但用起来效率不高,因为很多输入输出是比较复杂的,必须由人工补充一些代码,如果预先生成大量用例,那么每个用例都是在相同的起点上修改,效率并不高。如果工具只生成第一个测试用例,由用户完善后,再用拷贝并修改的办法建立其他用例,那么就可以充分利用已完善的用例,如果每次都选择拷贝近似的用例,通常只需要修改一两个数据就能建立新的用例。

找出遗漏用例是一个大难题,多数单元测试工具都只能统计出覆盖率,但是未覆盖的往往是最难的,要提高覆盖率往往成本很高,解决这个问题对提高测试完整性,降低测试成本具有极其重要的意义。这里提出一个新的思路:在运行现有的测试用例后,针对某一未覆盖的逻辑单位,由测试工具从现有的用例中计算出可以覆盖该逻辑单位的近似用例,再提供一些提示,由用户根据提示进行修改,从而获得预期的测试用例。这里说的近似用例是指需修改的数据最少,数值的差异也最小,例如,程序涉及到三个参数,那么近似用例大概只需要改一个参数就行,如果有多个用例可供选择,那么就选择数值改动幅度最小的。这个思路涉及到复杂的技术,这里就不详述了。

3、提高编码效率

编程的主要时间消耗不在于敲键盘,而在于编程思路和调试。这里说的编码,主要是指编写有一定复杂度的函数,即局部代码的实现,这是单元测试的重点,也是编码阶段最主要的工作。

程序员通常是在了解程序需实现的功能,并有了大概思路后即开始编码,而不是先将所有细节都想清楚。编码时也很难一气呵成,一般来说,写几行,就要编译调试一下,输出一些数据,看看已经写的对不对,再想下一步要怎么写,也就是说,要不断地了解已经编写的程序的行为,不断整理和完善编程思路。如果测试工具可以自动地描述程序行为,就可以帮助程序员更快捷地整理和完善编程思路,从而提高编码效率。

程序行为是什么?无非就是三点:输入是什么?执行了哪些代码?输出又是什么?在测试结果中显示输入输出数据,及标示出所执行的代码,是完全可以做到的,对于较复杂的程序而言,这种功能可以成倍地提高编码效率。

4、使用测试代码调试

调试是开发过程中无可逃避的工作,调试时必需执行程序,如何执行?一般由别的代码来调用,也就是说需要驱动,驱动大致可分为自然驱动和专门驱动。

自然驱动:利用项目中已有的代码作为驱动,通常是在被调试的函数中加断点,从界面执行一个需要调用该函数的功能,调试器中断时就可以调试了;专门驱动:为需要调试的函数编写专门的驱动代码,通过执行驱动代码来执行被调试函数。

自然驱动的主要优点是不需要其他工作就可以直接调试,甚至感觉不到需要驱动,主要缺点是输入数据通常是公共的,即很多代码都使用相同的输入源进行调试,实际输入往往是经过其他代码处理后的中间结果,要针对各种可能输入都进行调试往往很困难,造成调试不全面,程序员的思维受到局限,难于做到全面地考虑各种可能输入。

专门驱动的主要优点是输入数据是专门针对于被测试程序,容易做到比较全面,程序员的思维也会比较全面,对编写功能齐全的健壮的程序很有好处,要针对某种特定输入进行调试比较容易,缺点是需要花费大量的时间来编写驱动代码。

调试也需要"驱动"和"输入数据",也需要执行程序,这与测试是一样的,因此,我们可以利用测试代码来调试,既避免了自然驱动的缺点,又无需编写专门的调试驱动代码。

5、减少调试工作

如果边编码边测试,则只有在测试失败时才可能需要调试,从而大量减少调试工作。另一方面,如果测试工具具有描述程序行为的功能,即显示输入输出数据,及标示出所执行的代码,那么,当程序有错时,浏览输入输出数据和所执行的代码,通常都能快速发现错误原因,从而进一步减少单步调试。

6、增强调试器功能

如果测试代码由工具自动生成,可以考虑通过加强测试代码的功能,来间接增强调试器功能,具体来说,以下功能是很有价值的:

自动选择调试输入:捕捉合适的调试输入通常需要高级断点,有时是很麻烦的,如果由测试工具来选择某个测试用例作为调试输入,那么又可以省下不少时间。

后退和重复:调试器一般不支持后退,但测试代码可以实现模拟后退,例如,当到达测试代码尾部时,自动检查是否处于调试状态,如果是,则返回测试代码入口重新执行,这样,调试时只要使用"执行到光标所在行"之类的调试器命令,就可以实现后退和重复。由于每个测试用例都是独立的,重新执行时会建立新的被测试对象,因此,后退时,成员变量、参数、局部变量都能实现真正的后退,全局变量和静态变量则不能后退(幸运的是,这两种变量在一般函数中用得不多)。可以实现无限制的后退与重复,调试结束时关闭调试器就行了。

调试过程中切换输入:有时,需要比较不同输入时某个变量的值,如果调试过程中可以切换输入,岂不妙哉?综合使用"自动选择调试输入"和"后退和重复"即可做到调试过程中切换输入。

增强编辑继续功能:"编辑继续"功能对已执行过的代码通常是无效的,但利用后退和重复功能,可以让"编辑继续"功能发挥更大的效能。

7、实现零时间彻底测试

之前我们讨论了实现彻底测试的"三步法",本文讨论了减少测试时间及挖掘编码调试中的效率潜力,用减少编码调试时间来抵消测试时间,从而实现零时间彻底测试。

单元测试和编码调试有紧密的关系,边编码边测试,实现编码调试测试一体化,可以避免重复工作,最大限度地提高开发效率。如果测试工具实现了本文所述的全部技术,那么,做到"零时间彻底测试"是不成问题的,甚至可以进一步缩减编码阶段的工期,我们来比较一下"测试耗费的时间"及"测试所节约的时间",看看哪一个更多些:

假如测试工具实现了前述的所有技术和方法,那么:

测试方面:

第1步,自动生成测试代码,只要填写输入输出数据就可以建立第一个测试用例,其他用例采用拷贝修改的办法建立。这一步只需建立容易想到的用例,不必考虑是否遗漏,因此,这一步费时是很少的;

第2步,由工具自动统计白盒覆盖率,自动画出逻辑结构图,并标示未覆盖的逻辑单位(语句、条件、分支、路径),用户选择一个未覆盖的逻辑单位,系统自动从现有的测试用例中计算出一个近似用例,并生成一些提示,依据提示修改一个输入数据及预期输出,即可建立预期的测试用例。如果逻辑单位不可覆盖,也能根据修改提示判断出来并从逻辑结构图中删除。这一步是"拾遗",即找出遗漏的测试用例,这种用例的数量通常不多,因此耗时也不会太多;

第3步,由工具自动生成大量测试用例,捕捉编码时未考虑某些特殊输入形成的错误。这一步通常不需要消耗什么时间。

再来看看能够从编码调试中挖出来的时间:

通过描述程序行为,帮助整理和完善编码思路,提高编码效率;

通过描述程序行为,帮助快速找出错误原因,减少单步调试;

通过增强调试器功能,提高调试效率。

编程工作的主要时间消耗在于编程思路和调试,上述功能从这两方面入手,所节约的时间是相当可观的,当编写比较复杂的代码时,所节约的时间可能比测试所消费的时间多得多,不但能实现零时间测试,而且还可能缩短编码工期。

8、舒适高效地开发

在原来用于编码的时间内同时完成编码和单元测试,会不会增加程序员的劳动强度?不会的,因为:

1)找出并消除局部代码中的错误,本来就是程序员的份内工具,并不是额外工作;

2)编程最累人的是调试,翻江倒海地找一个小小Bug的经历,相信每个程序员都有过,不但累人,而且气人,充分的单元测试使这种情形几乎不会出现;

3)编程工作中比较累人的还有清理思路,一般环境下要了解程序行为并不容易,这对程序员完善编程思路很不利,如果通过测试工具来描述程序行为,使程序行为一目了然,不但提高工作效率,还会感觉比较舒适。

程序员的工作目的是解决问题,工作乐趣也在于解决问题,最忌的是注意力被分散和思维被干扰。本文介绍的单元测试技术,测试工作的大部分由工具完成,不会分散注意力和干扰思维,并通过描述程序行为等手段,帮助程序员专注于问题的解决,更好地发挥潜能,也使工作更有乐趣。

上一篇:单元测试彻底测试的方法
下一篇:单元测试四问
相关文章

 发表评论

暂时没有评论,来抢沙发吧~