参考阿里巴巴开发手册,第八条规则(单元测试的基本目标:语句覆盖率达到70%;核心模块的语句覆盖率和分支覆盖率都要达到100%)。

很多回答说小公司基本不用做,其实小公司不做单元测试的话,就会导致测试压力更大,要是开发的功能和需求不符合还会耽误进度,所以要进行单元测试。

大公司,有完整的上线流程,开发、单元测试、测试申请单的提交一直到软件的上线都有完整的规范及文档,开发从理解需求文档到定义数据库字段,开发,单元测试是很严格的。

单元测试是地基

在开发的整个环节中,越晚发现问题,解决问题的成本就越高。单元测试的意义就在于提前发现问题,减少开发和测试的成本。

从测试覆盖率来说,测试金字塔越往上执行的测试,可覆盖case会逐渐变下,比如UI测试只能保证页面正常,接口异常不会测试覆盖完整。而接口覆盖完整了,又不能保证代码中所有逻辑都覆盖,某些函数某些类的功能无法覆盖,通常发现的问题,都是不太好复现的bug。

在项目中开展单元测试

并不是所有的项目都适合做单元测试,即使进行单元测试,也应该是一些基础底层模块或者核心模块进行单元测试。

合适的单元测试框架:Java中的TestNG、JUnit,Python中的Unittest、Pytest,PHP中的PHPUnit

一般来说应该对以下代码进行单元测试:

  • 所有程序集中的公开类以及公开类里面的公开方法添加单元测试

  • 对于构造函数和公共属性进行单元测试

  • 前期抓住重点进行测试,主要是一些可复用代码进行测试。

主流框架JUnit和TestNG

JUnit是Java的单元测试框架,用于编写和运行可重复的测试,特性:

  • 用于测试期望结果的断言(Assertion)

  • 用于共享共同测试数据的测试工具

  • 用于方便的组织和运行测试的测试套件

  • 图形和文本的测试运行器

TestNG是一个测试框架,引入了一些新功能,TestNG 消除了大部分的旧框架的限制,使开发人员能够编写更加灵活和强大的测试。 因为它在很大程度上借鉴了Java注解( JDK5.0 引入的)来定义测试,它也可以显示如何使用这个新功能在真实的Java语言生产环境中。

特点如下:

  • 注解

  • TestNG 使用 Java 和面向对象的功能

  • 支持综合类测试(例如,默认情况下,不用创建一个新的测试每个测试方法的类的实例)

  • 独立的编译时测试代码和运行时配置/数据信息

  • 灵活的运行时配置

  • 主要介绍“测试组”。当编译测试,只要要求 TestNG 运行所有的“前端”的测试,或“快”,“慢”,“数据库”等

  • 支持依赖测试方法,并行测试,负载测试,局部故障

  • 灵活的插件 API

  • 支持多线程测试

测试哪些内容?

Right----------结果是否正确?

B---------------是否所有的边界条件都是正确的?

I----------------能查一下反向关联吗?

C---------------能用其他手段交叉检查一下结果吗?

E---------------你是否可以强制错误条件发生?

P---------------是否满足性能要求?

RIGHT:结果是否正确

如果代码能运行正确,如何才知道它是正确的呢?

1、使用更明确的设计文档

2、真实环境数据

3、????

B:边界条件

尽可能的至少各种特殊或者意外的情况,测试程序是否能正常工作,如:

  • l 完全伪造或者不一致的输入数据,如叫作“(*@Q!&#?±的文件。

  • l 格式错误的数据,如错误格式的邮件地址

  • l 空值或不完整的值

  • l 一些与意料中的合理值相去甚远的值,如年纪为10000

  • l 如果要求是一个不允许出现重复数值的list,但传入一个有重复数值的list

  • l 要求是一个有序的list,但传入一个无序的list

  • l 处理的顺序是错误的,或者与期望的次序不一致。如未登录系统就尝试打印。

B:边界条件的-CORRECT

Conformance(一致性)值是否和预期的一致

Ordering顺序性)值是否应该的那样有序或者无序

Range区间性)值是否位于合理范围

Reference(依赖性)代码是否引用了一些代码本身控制范围之外的资源

Existence(存在性)值是否存在(是否非空,非零,在集合中等等)

Cardinality基数性)是否恰好有足够的值

Time(相对或绝对的时间性)所有事情的发生是否有序?是否在正确的时间?是否恰好及时?

I:检查反向关联

通常一些结果可以使用反向的逻辑关系来验证它们是否正确,如:计算a*b的函数,测试方法如下:

Public void UsingInverse(){ double x = MyMath.AB(4,4); Assert.AreEqual<double>(x,4*4);}

C:使用其他手段实现交叉检查

计算一个结果可以存在多个算法,同一个算法可以使用稳定的版本来校验新改进的版本,如:

Public void UsingStd(){    double number = 23214.01;    double result1 = MyMath.旧方法(number1);    double result2 = MyMath.新方法(number1);    Assert.AreEqual<double>(result1,result2);}

E:强制产生错误条件

真实运行环境各种出乎意料的事情都可能发生,如断电,断网等等。在测试中模拟这些情况可以使用Mock对象来实现。

P:性能特性

如数据采集的功能,在十个网站上进行采集工作很正常,那么在1000个网站上或更多的网站上进行采集它的速度如何?是否写个单元测试?

举报/反馈

黑马程序员

6.7万获赞 2.3万粉丝
国内公认的好口碑IT教育培训机构。
黑马程序员官方账号,优质教育领域创作者
关注
0
0
收藏
分享