单元测试
什么是单元测试
针对一个单独的组件的一组测试,组件是什么呢,它是系统中的最 原子 的行为单元,比如面向过程中函数,而在面向对象中就是相应的类了。下面都以面向对象为例进行讲解。
快速运行
首先要明确一点,单元测试运行得很快,不快的就不是单元测试了。
比如涉及下面内容的测试就不是单元测试:
- 跟数据库交互
- 存在网络通信
- 调用文件系统
- 对环境作特定准备
单元测试的优势是运行快并能帮助我们定位问题所在,这些测试应该和真正的单元测试分开,这样我们就可以知道那些测试是在我们改动代码后能快速运行的。
单元测试与高层测试的区别
单元测试针对某个类进行测试,而高层测试是覆盖某个功能的场景和交互的测试,可以确认一组类的行为。
测试覆盖
这里不详细说单元测试的覆盖率问题了,以路径覆盖率(不懂的可以去自行去恶补一下,目测计算机专业的都应该上过软件测试课)100%为标准,举一个注册用户的例子:
注册功能:用户名和密码不能为空,用户名和密码长度不能小于4位并且不能大于128位。
下面列举下覆盖率为100%的case(下面用 Y 代表符合要求数据,用 N 代表不符合要求数据):

格式:case -- username -- password -- unIsLegal -- pwIsLegal
1 -- N -- Y -- Y -- Y
2 -- Y -- N -- Y -- Y
3 -- Y -- Y -- N -- Y
4 -- Y -- Y -- Y -- Y
5 -- Y -- Y -- Y -- Y
单元测试中需要尽量提高覆盖率,考虑各种可能,如果太低的覆盖率的单元测试就没有存在意义了,因为根本无法保证该组件是否正常。
伪对象(mock)
这里还是以注册用户为例,假如用户传递的注册参数都是正确的情况下,程序最后会向服务器发送注册请求,这里就会存在网络请求,但上面已经提及到涉及网络通信的测试并不是单元测试,那这里该怎么处理呢?
解决方法是创建一个服务器的伪对象(mock),返回一个模拟的正常数据就可以。
但如果数据是假的,这里还算是测试吗?
这里肯定会有很多初学者有疑问的,这里当然还是算单元测试,因为发起网络的请求的已经不属于这个组件(单元)的功能了,而是属于另一个(或多个)单元测试的问题了,这里采用了 分而治之 的方案,单元测试只要保证当前组件(单元)的正确就可以了。假如有一天,注册模块出现一个bug,但注册功能的单元测试是正常执行的,这个时候我们就可以确定bug不是出现注册方法里面,利用这个信息,我们可以更快捷地定位到出现bug的原因了。
后面会针对 iOS SDK 的单元测试进行讲解,有兴趣的可以关注下我,我创建了一个 iOS SDK 开发的群,群号:127548419,有兴趣的可以添加,欢迎大家一起讨论交流。