- 测试是什么
- 测试有什么用
- 单元测试、e2e 测试、snapshot 测试的区别
测试就是检查程序的行为是否符合预期的过程。
测试分为两种:手动测试和自动化测试。手动测试就是自己拿鼠标点点点,跟程序进行交互,检查程序的反应是否符合预期。自动化测试就是编写程序来替代手动检查。
user journey: a list of steps that a user can take through an application. eg. open applicationn, fill out form, click submit.
e2e 测试是指从用户的角度出发,将用户的行为自动化,比如用程序模拟用户打开浏览器、填写表单、提交表单等操作。
不足
- 耗时长。打开浏览器、请求网页都是比较耗时的操作。
- debug 难。因此 e2e 测试最好是在 Docker 容器中运行,便于重现 bug。
- 脆弱。指的是即使程序正常运行,e2e 测试还是可能不通过,比如后端接口暂时奔溃可能会导致测试结果不通过。
单元测试把程序拆分成小部分(单元),再对这些部分进行分别测试。一般可测试的单元指的是函数,不过在 Vue 中,可测试单元也包括组件。
优点
- 运行时间快。
- 测试代码天然就是源码的文档。
- 可靠。只要源码的功能不变,单元测试的结果就会保持一致,这点跟 e2e 测试不一样。
不足
- 影响代码重构的效率。如果要重构代码,相应的测试代码也需要更新。(thoughts: 所以写单元测试的时候尽量不要去测试实现细节,这样即使一个模块的实现方式变了,只要它的功能不变,测试就还是有效的。)
- 单元测试把程序拆分成小块来测试,保证了每个部分的行为符合预期,但不保证它们合起来作用也符合预期,这也是为什么我们不能单独依赖单元测试,还需要 e2e 测试的原因。
snapshot 测试就像是“找不同”游戏,它会将当前运行的程序进行“截图”,与之前保存的“截图”进行对比,如果两者不一致则测试不通过。
传统的 snapshot 测试就真的是打开浏览器,加载程序,屏幕截图,对比截图。但这样做的缺点很明显,不同操作系统或者不同版本的浏览器也会影响渲染结果,所以测试结果不完全可靠。
而 jest 的 snapshot 测试则是通过对比 JS 中的**可序列化(serializable)**值,不受操作系统和浏览器的影响。
serializable means any code that can be converted to a string and then back into a value. In reality, it refers to a V8 method. (question: Is it similar to the stringify method of JSON?)
项目中的测试代码组成部分应该是:
- ~10% e2e 测试
- ~30% snapshot 测试
- ~60% 单元测试
还有一种测试叫集成测试(integration tests),但并不太建议在前端使用。
Test-driven development
一个参考的流程:
- 决定需要什么样的组件
- 针对组件写单元测试和源码
- 增加样式
- 增加 snapshot 测试
- 手动测试
- 增加 e2e 测试
100% 的测试覆盖率可能是个伪命题。
达到 100% 测试覆盖率是很“劳民伤财”的,除非是非常重要的应用,比如支付相关的应用,一般我们没必要追求 100% 的覆盖率,而且 100% 的覆盖率也不能保证程序完全没有 bug。
一个基本的概念是,我们应该给组件提供输入,然后测试它的输出是否符合我们的预期。
常见输入
- 组件的 props
- 用户触发的事件,比如鼠标点击
- Vue 中的自定义事件
- Vuex 中的数据
常见输出
- 组件触发了事件
- 组件提供了外部函数而且这个函数在外部被调用了