表1 单元测试case列表
接下来需要在单元测试工程中实现上述case,最小断言数是业务逻辑上的判断,并不是代码的边界条件,真实的case需要考虑代码的边界条件,比如数组为空等条件,因此,最终的断言数量会大于等于最小断言数。在需求业务上,最小断言数也是该需求的业务条件。
写完case后需要跑一遍单元测试并检查覆盖率报告,当覆盖率报告中缺少有些单元测试case列表中没有但是实际逻辑中会有的逻辑时,需要更新单元测试case列表,添加遗漏的逻辑,并将对应的代码补上。直到所有需要维护的逻辑都被覆盖,该项目中的单元测试才算完成。单元测试并不是QA的黑盒测试,需要保证对代码逻辑的覆盖。
对表1分析,第一个页面的“发布新闻”的case可以直接调用“编写新闻”的case,以满足条件“2.编写了新闻的前提下,点击发布按钮”,在JUnit框架下,case(带@Test注解的那个函数)也是个函数,直接调用这个函数就不是case,和case是无关的,两者并不会相互影响,可以直接调用以减少重复代码。第二个页面不同于第一个,一进入就需要网络请求,后续业务都需要依赖这个网络请求,单元测试不应该对某一个条件过度耦合,因此,需要用mock解除耦合,直接mock出网络请求得到的数据,单独验证页面对数据的响应。
总结
单元测试并不是一个能直接产生回报的工程,它的运行以及覆盖率也不能直接提升代码质量,但其带来的代码控制力能够大幅度降低大规模协同开发的风险。现在的商业App开发都是大型团队协作开发,不断会有新人加入,无论新人是刚入行的应届生还是工作多年,在代码存在一定业务耦合度的时候,修改代码就有一定风险,可能会影响之前比较隐蔽的业务逻辑,或者是丢失曾经的补丁,如果有高覆盖率的单元测试工程,就能很快定位到新增代码对现有项目的影响,与QA验收不同,这种影响是代码级的。
在本文所设计的单元测试流程中,单元测试的case和具体页面的具体业务流程以及该业务的代码逻辑紧密联系,单元测试如同技术文档一般,能够体现出一个业务逻辑运行了多少函数,需要注意什么样的条件。这是一种新人了解业务流程、对业务进行代码级别融入的好办法,看一下以前的单元测试case,就能知道与该case对应的那个页面上的那个业务逻辑会执行多少函数,以及这些函数可能出现的结果。
原文转自:http://tech.meituan.com/Android_unit_test.html