一、测试准则
必须满足AIR原则
A:Automatic(自动化)
I:Independent(独立性)
R:Repeatable(可重复)
可参照27条准则。
引用链接:https://blog.csdn.net/neo_ustc/article/details/22612759
原文链接:https://petroware.no/unittesting.html
如下:
1. 保持单元测试小巧, 快速
2. 单元测试应该是全自动/非交互式的
3. 让单元测试很容易跑起来
4. 对测试进行评估
5. 立即修正失败的测试
6. 把测试维持在单元级别
7. 由简入繁
8. 保持测试的独立性
9. Keep tests close to the class being tested
10. 合理的命名测试用例
11. 只测试公有接口
12. 看成是黑盒
13. 看成是白盒
14. 芝麻函数也要测试
15. 先关注执行覆盖率
16. 覆盖边界值
17. 提供一个随机值生成器
18. 每个特性只测一次
19. 使用显式断言
20. 提供反向测试
21. 代码设计时谨记测试
22. 不要访问预定的外部资源
23. 权衡测试成本
24. 合理安排测试优先次序
25. 为测试失败做好准备
26. 写测试用例重现 bug
27. 了解局限
二、结构规范
目录结构规范:
1.源码存放在src目录,每个功能模块创建单个npm包
2.src同级创建test/unit作为单元测试文件目录
3.test/unit目录下创建源npm包同名文件夹,用于存放单元测试文件
4.src同级创建test/integration作为集成测试文件夹
5.test/integration目录下创建源npm包同名文件夹,用于存放集成测试文件
文件命名规范:
1.test目录下测试文件名同源码文件名同名,后缀以.test.js结尾
2.test/unit和test/integration创建测试文件夹时,参照短横线(kabab-case)规范命名。
3.js和ts文件依照短横线(kabab-case)规范命名,Vue文件依照驼峰(camelCased)规范命名。
4.每个源码文件(如js,ts,vue)对应一个同名.test.js文件。(index文件可以忽略)
三、编码原则
必须符合 BCDE 原则:
B:Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。
C:Correct,正确的输入,并得到预期的结果。
D:Design,与设计文档相结合,来编写单元测试。
E:Error,强制错误信息输入(如:非法数据、异常流程、非业务允许输入等),并得到预期的结果。
避免以下情况:
1)构造方法中做的事情过多。
2)存在过多的全局变量和静态方法。
3)存在过多的外部依赖。
4)存在过多的条件语句。
建议:
1.涉及到的某些扩展模块可以使用mock模拟
2.测试用例不要使用@ignored或者被注释掉,切记切记。
如何编写更好的单元测试
原文链接:https://www.techug.com/post/19-unit-test-code-tips.html
单元测试在最近的工作中使用比较广泛,我已经收集了一些关于如何编写更好的测试类的准则,并且我已经尝试着坚持这些准则多年了。记住,编写糟糕的测试是在浪费时间,并会在以后造成更大的问题。所以最好把这些准则记在心里。
19条建议
1.不应该编写成功通过的单元测试-它们应该被写成不通过的。
可以在几分钟内让任何一组测试通过,但这只是在欺骗你自己。
2.测试类应该只测试一个功能。
你应该用一个功能去测试一个方法。否则,你会违反了单一职责原则。
3.测试类具备可读性。
确保测试类标有注释并且容易理解,就像其他的代码一样。
4.良好的命名规范。
再次测试时应该像其他代码一样-便于人们理解。
5.把断言从行为中分离出来。
你的断言应该用来检验结果,而不是执行逻辑操作的。
6.使用具体的输入。
不要使用任何的自动化测试数据来输入,像date()这些产生的数据会引入差异。
7.把测试类分类,放在不同的地方。
从逻辑的角度看,当没有错误指向特定的问题时这更容易去查找。
8.好的测试都是一些独立的测试类。
你应该让测试类与其他的测试、环境设置等没有任何依赖。这利于创建多个测试点。
9.不要包含私有的方法。
他们都是一些具体的实现,不应该包含在单元测试里。
10.不要连接数据库或者数据源。
这是不靠谱的。因为你不能确保数据服务总是一样的并且能够创建测试点。
11.一个测试不要超过一个模拟(mock对象)。
我们努力去消除错误和不一致性。
12.单元测试不是集成测试。
如果你想测试结果,不要使用单元测试。
13.测试必须具有确定性。
你需要一个确定的预测结果,所以,如果有时候测试通过了,但是不意味着完成测试了。
14.保持你的测试是幂等的。
你应该能够运行你的测试多次而不改变它的输出结果,并且测试也不应该改变任何的数据或者添加任何东西。无论是运行一次还是一百万次,它的效果都应该是一样的。
15.测试类一次仅测试一个类,测试方法一次仅测试一个方法。
组织方法能够在问题出现时检测出来,并帮你确定测试依赖。
16.在你的测试里使用异常。
你在测试里会遇到异常,所以,请不要忽略它,要使用它。
17.不要使用你自己的测试类去测试第三方库的功能。
大多数好的库都应该有它们自己的测试,如果没考虑用mocks去产生一致性的结果的话。
18.限制规则。
当在一些规则下写测试时,记住你的限制和它们(最小和最大)设置成最大的一致性。
19.测试类不应该需要配置或者自定义安装。
你的测试类应该能够给任何人使用并且使它运行。“在我的机器上运行”不应该出现在这。
四、编码规范:
1.test对应每个源码创建单元测试包
2.每个npm包,都要添加descript,描述名为npm包名。
如descript("awp-lib-moment",()=>{});
3.需生成快照文件的单元测试,快照需要每次提交。
4.expect test('') 中描述的是调用和期望输出结果。
如test("Moment.format('yyyyMMdd HH:mm:ss','2019/07/09 17:41:01') 期望输出结果:20190709 17:41:01", () => {});
5.进行参数或属性校验。
校验包含正向和反向校验,即正确类型正确输出和异常类型返回异常信息等。
校验种类包含,参数个数、参数类型等。
6.测试要覆盖实现中的代码的各个分支
7.一个测试方法只测试一个方法,不测试私有方法
8.一个测试类只对应一个被测类.
9.测试用例的变量和方法都要有明确的含义
五、测试维度
编写单元测试,主要参考以下几个方面:
来源链接:https://blog.csdn.net/qq_36505948/article/details/82797240
1.接口功能性测试
接口功能的正确性,即保证接口能够被正常调用,并输出有效数据!
------------------> 是否被顺利调用
------------------> 参数是否符合预期
2.局部数据结构测试
保证数据结构的正确性
------------------> 变量是否有初始值或在某场景下是否有默认值
------------------> 变量是否溢出
3.边界条件测试
------------------> 变量无赋值(null)
------------------> 变量是数值或字符
------------------> 主要边界:最大值,最小值,无穷大
------------------> 溢出边界:在边界外面取值+/-1
------------------> 临近边界:在边界值之内取值+/-1
------------------> 字符串的边界,引用 "变量字符"的边界
------------------> 字符串的设置,空字符串
------------------> 字符串的应用长度测试
------------------> 空白集合
------------------> 目标集合的类型和应用边界
------------------> 集合的次序
------------------> 变量是规律的,测试无穷大的极限,无穷小的极限
4.所有独立代码测试
保证每一句代码,所有分支都测试完成,主要包括代码覆盖率,异常处理通路测试
------------------> 语句覆盖率:每个语句都执行到了
------------------> 判定覆盖率:每个分支都执行到了
------------------> 条件覆盖率:每个条件都返回布尔
------------------> 路径覆盖率:每个路径都覆盖到了
5.异常模块测试
后续处理模块测试:是否包闭当前异常或者对异常形成消化,是否影响结果!
六、测试目标
说明:以下仅作为参考,实际还需要按照各自项目进行评估。
语句覆盖率:>=70%
分支覆盖率:100%
函数覆盖率:100%
行覆盖率: >=80%
执行覆盖率, 业界标准通常在 80% 左右!!