目录
- 测试的考量
- 测试的分类
- 测试的模式
- 测试金字塔
- 单元测试的原则
- 测试的策略
- 测试用例的组织
- 测试的过程
- 参考资料
测试的重要性尽人皆知,这里从做点小小的总结
测试的考量
1. 测试的时机
不是东西做出来再测,而是测好了东西才能出来 各个大小公司,独立的测试团队都在削减人员,不是测试不重要,而是需要全员从一开始就要做测试, 全过程测试, 早期注重单元测试和组件测试, 后期注重集成测试和端到端测试。在一个迭代尽量做一个相对完整的功能, 及时做集成, 而不是最后再一起做集成测试
(个人以为独立专业的测试团队还是很有必要的, 自己测自己写的东西, 很难发现意想不到的问题)
2. 测试的效率
讲究有效性,稳定性和性能,一定要自动化,跨越多个组件的端到端测试必须有,可是不宜多,而且应该是聚焦在于功能性,无需过度测试,有必要才测, 代码对测试友好, 也就是易于测试。 测试要讲究有效性,稳定性和性能。
从思维定势的角度来看, 单元测试可以自己做, 组件测试和集成测试最好换位思考, 结对测试或交由测试专家来做
3. 测试的度量
测试要有覆盖率,哪怕仅作参考 性能测试更要有数据,比如 CPS TPS QPS 最耗时间的函数等在测试过程中收集到的度量数据
4. 测试的对象
测试到底测什么?
测试目的要明确, 检查点是先定义好. 哪些值, 状态, 还是行为要检查?
测试范围更要定义清楚, 单元,组件,系统内部还是端到端的用户操作?
测试的分类
- 黑盒测试
- 白盒测试
- 手工测试
- 自动测试
- 冒烟测试
- 回归测试
- 探索性测试
- 单元测试
- 组件测试
- 消费者测试
- 集成测试
- 端到端测试
- 压力测试
- 异常测试
测试的模式
Mike Clifton 曾经总结过测试的若干模式, 可以参看原文, 回头找时间翻译一下
Pass/Fail Patterns 通过/失败测试模式
Data Driven Test Patterns 数据驱动测试模式
Data Transaction Patterns 数据处理事务测试模式
Collection Management Patterns 集合管理测试模式
- The Collection-Order Pattern
- The Enumeration Pattern
- The Collection-Constraint Pattern
- The Collection-Indexing Pattern
Performance Patterns 性能测试模式
Process Patterns 流程处理测试模式
Simulation Patterns 仿真测试模式
- Mock-Object Pattern
- The Service-Simulation Pattern
- The Bit-Error-Simulation Pattern
- The Component-Simulation Pattern
Multithreading Patterns 多线程测试模式
Stress-Test Patterns 压力测试模式
Presentation Layer Patterns 展现层测试模式
测试金字塔
因为越往上测试的实现和维护成本就越高, 测试速度也越慢, 所以提倡多写单元测试, 少写端到端的测试, 少写不等于不写, 上层的测试着重测一些主要的路径, 不需要面面俱到, 不然费时费力
单元测试的原则
有本书单元测试之道总结了若干单元测试的原则, 先来回顾一下
Pragmatic Unit Testing by Andrew Hunt and David Thomas
FIRST 原则
- Fast 快速的
- Isolated 隔离
- Repeatable 可重复
- Self-Validating 自验证
- Timely 及时的
参见 https://github.com/ghsukumar/SFDC_Best_Practices/wiki/F.I.R.S.T-Principles-of-Unit-Testing (ottinger, langr)
Right-BICEP 测试原则
英文 | 中文 |
---|---|
Right - Are the results right? | 结果是否正确? |
B - are all the boundary conditions correct? | 所有的边界条件测试结果正确吗 |
I - can you check the inverse relationships? | 有没有检查反向关系 |
C - can you cross-check results using other means? | 能不能用其他方法交叉检查结果? |
E - can you force error conditions to happen? | 能不能强制错误情况发生? |
P - are performance characteristics within bounds? | 性能特性在不在允许范围之内? |
CORRECT 检查原则
英文 | 中文 |
---|---|
C - Conformance - does the value conform to an expected format? | 一致性 - 值是否符合预期的格式? |
O - Ordering - is the set of values ordered or unordered as appropriate? | 排序 - 值的集合是否根据需要进行排序或无序? |
R - Range - is the value within reasonable minimum and maximum values? | 范围 - 值是否在合理的最小值和最大值范围之内? |
R - Reference - does the code reference anything external that isn't under direct control of the code itself? | 引用 - 代码是否引用了不受代码本身直接控制的外部依赖? |
E - Existence - does the value exist (e.g. is not null, non-zero, present in a set)? | 存在 - 值是否存在(例如,不为null,非零,是否存在于集合中)? |
C - Cardinality - are there exactly enough values? | 基数 - 是否有足够的值? |
T - Time (absolute and relative) - is everything happening in order? At the right time? In time? | 时间(绝对和相对) - 一切事件是否有序? 是否在正确的时间? 是否及时? |
测试相关框架与库
林林总总, 不胜枚举, C++的googletest, gmock, Java的 Junit, TestNG, Mockito, PowerMock, JavaScript 的 Qunit, Python 的 unittest, Lua 的 luaunit, 等等
其实他们都是脱胎于 JUnit , 使用起来也是大同小异
测试的策略
测试要分类,分组,而且要能快速定位和诊断测试的失败之处
在开始系统级测试之前, 最好能列一个测试矩阵 Test matrix 把所有已知条件, 场景和输入, 或变化的因子列出来, 以免遗漏
Components | Scenario | IE7 | IE8 | IE9 | IE10 | IE11 | Edge | Chrome | Firefox | Opera |
---|---|---|---|---|---|---|---|---|---|---|
Portal | Login | pass | pass | pass | pass | pass | pass | pass | pass | pass |
测试用例的组织
Given-When-Then
BDD | 说明 | 示例 |
---|---|---|
Given | 先决条件 | 广告部定制了企业的服务电话语音为最近一次促销活动广告 |
When | 行为或事件 | 用户拔打 800 服务电话 |
Then | 期待的变化或结果 | 欢迎声后听到最近一次促销广告 |
测试的过程
测试是个大题目, 未尽之言, 在下面两篇总结中详述
参考资料
- 如何写出好的测试
- TestNG 官方文档
- "Pragmatic Unit Testing by Andrew Hunt and David Thomas"
- Clifton 总结的测试的若干模式
- https://martinfowler.com/bliki/GivenWhenThen.html