参考阿里巴巴开发手册,第八条规则(单元测试的基本目标:语句覆盖率达到70%;核心模块的语句覆盖率和分支覆盖率都要达到100%)。
很多回答说小公司基本不用做,其实小公司不做单元测试的话,就会导致测试压力更大,要是开发的功能和需求不符合还会耽误进度,所以要进行单元测试。
大公司,有完整的上线流程,开发、单元测试、测试申请单的提交一直到软件的上线都有完整的规范及文档,开发从理解需求文档到定义数据库字段,开发,单元测试是很严格的。
在开发的整个环节中,越晚发现问题,解决问题的成本就越高。单元测试的意义就在于提前发现问题,减少开发和测试的成本。
从测试覆盖率来说,测试金字塔越往上执行的测试,可覆盖case会逐渐变下,比如UI测试只能保证页面正常,接口异常不会测试覆盖完整。而接口覆盖完整了,又不能保证代码中所有逻辑都覆盖,某些函数某些类的功能无法覆盖,通常发现的问题,都是不太好复现的bug。
并不是所有的项目都适合做单元测试,即使进行单元测试,也应该是一些基础底层模块或者核心模块进行单元测试。
合适的单元测试框架:Java中的TestNG、JUnit,Python中的Unittest、Pytest,PHP中的PHPUnit
一般来说应该对以下代码进行单元测试:
所有程序集中的公开类以及公开类里面的公开方法添加单元测试
对于构造函数和公共属性进行单元测试
前期抓住重点进行测试,主要是一些可复用代码进行测试。
JUnit是Java的单元测试框架,用于编写和运行可重复的测试,特性:
用于测试期望结果的断言(Assertion)
用于共享共同测试数据的测试工具
用于方便的组织和运行测试的测试套件
图形和文本的测试运行器
TestNG是一个测试框架,引入了一些新功能,TestNG 消除了大部分的旧框架的限制,使开发人员能够编写更加灵活和强大的测试。 因为它在很大程度上借鉴了Java注解( JDK5.0 引入的)来定义测试,它也可以显示如何使用这个新功能在真实的Java语言生产环境中。
特点如下:
注解
TestNG 使用 Java 和面向对象的功能
支持综合类测试(例如,默认情况下,不用创建一个新的测试每个测试方法的类的实例)
独立的编译时测试代码和运行时配置/数据信息
灵活的运行时配置
主要介绍“测试组”。当编译测试,只要要求 TestNG 运行所有的“前端”的测试,或“快”,“慢”,“数据库”等
支持依赖测试方法,并行测试,负载测试,局部故障
灵活的插件 API
支持多线程测试
Right----------结果是否正确?
B---------------是否所有的边界条件都是正确的?
I----------------能查一下反向关联吗?
C---------------能用其他手段交叉检查一下结果吗?
E---------------你是否可以强制错误条件发生?
P---------------是否满足性能要求?
如果代码能运行正确,如何才知道它是正确的呢?
1、使用更明确的设计文档
2、真实环境数据
3、????
尽可能的至少各种特殊或者意外的情况,测试程序是否能正常工作,如:
l 完全伪造或者不一致的输入数据,如叫作“(*@Q!&#?±的文件。
l 格式错误的数据,如错误格式的邮件地址
l 空值或不完整的值
l 一些与意料中的合理值相去甚远的值,如年纪为10000
l 如果要求是一个不允许出现重复数值的list,但传入一个有重复数值的list
l 要求是一个有序的list,但传入一个无序的list
l 处理的顺序是错误的,或者与期望的次序不一致。如未登录系统就尝试打印。
Conformance(一致性)值是否和预期的一致
Ordering(顺序性)值是否应该的那样有序或者无序
Range(区间性)值是否位于合理范围
Reference(依赖性)代码是否引用了一些代码本身控制范围之外的资源
Existence(存在性)值是否存在(是否非空,非零,在集合中等等)
Cardinality(基数性)是否恰好有足够的值
Time(相对或绝对的时间性)所有事情的发生是否有序?是否在正确的时间?是否恰好及时?
通常一些结果可以使用反向的逻辑关系来验证它们是否正确,如:计算a*b的函数,测试方法如下:
Public void UsingInverse(){ double x = MyMath.AB(4,4); Assert.AreEqual<double>(x,4*4);}
计算一个结果可以存在多个算法,同一个算法可以使用稳定的版本来校验新改进的版本,如:
Public void UsingStd(){ double number = 23214.01; double result1 = MyMath.旧方法(number1); double result2 = MyMath.新方法(number1); Assert.AreEqual<double>(result1,result2);}
真实运行环境各种出乎意料的事情都可能发生,如断电,断网等等。在测试中模拟这些情况可以使用Mock对象来实现。
如数据采集的功能,在十个网站上进行采集工作很正常,那么在1000个网站上或更多的网站上进行采集它的速度如何?是否写个单元测试?