单元测试是前端知识体系中重要的一环,是中高级前端必须掌握的基础知识。然而在追求开发效率的日常工作中,单元测试往往没有被重视和应用起来,也没有人要求必须写单元测试。导致许多开发者甚至连如何编写单元测试都不知道。更别提在众多和测试相关的 NPM 包中,理清它们的职责都有哪些?
如果你没写过也完全没写过单元测试,那么请相信,你错过了一个提升代码质量、提升开发自信心的有效工具。
Anyways, 即使你从来没写过测试,也肯定在使用脚手架初始化前端项目时,或者在 github 开源项目里看到过 tests 目录和 test script 脚本。
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
^ Create React App 创建出来的项目
以前不了解没关系,接下来的这一系列文章就是专门为完全没写过测试的同学而编写的,将从零开始带你一步一步掌握单元测试。
第一篇文章作为引入,阅读完你将了解什么是单元测试;单元测试的特点是什么,有哪些好处和局限性;除了单元测试还有哪些测试类型。Let's go。
什么是单元测试?
在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试,是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。 —— 维基百科
别看上面一大段文字描述,其实两个短语就可以解释什么是单元测试:
- 单元:单个程序、函数、过程 很好理解,纯方法,类,或者是一个组件都属于单元的范畴。
- 测试:正确性校验 也就是对被测试的代码进行验证,判断运行结果是否符合预期。
除了单元测试,还有...
除了单元测试,开发者还经常用到的测试类型还有
- 集成测试:相对于单个程序、函数、过程,用于验证多个单元组装在一块后的数据联动和通信等。
- E2E 测试:也叫端对端测试,用于验证跨应用多个模块的用户操作流程。
在很多介绍单元测试的文章中都能看到类型下面的金字塔模型:
先具象化一下理解这三种测试类型的区别,以表单为例。对 <Input /> 或 <Checkbox /> 组件的测试属于单元测试;多个控件组合在一块拼成 Form 表单,对 Form 表单进行测试,验证各个控件能正常联动属于集成测试;使用浏览器模拟真实用户操作,点击登录按钮之后数据能成功写入后端,并成功跳转,就属于 E2E 测试。
结合上方的三种测试类型的金字塔,可以看出,金字塔越往上,依赖项越多,不稳定因数也随着增加,测试范围也越来越泛,写单元测试的时候可以为组件设计各种输入,而端对端测试阶段受限于其他依赖,造测试输入会很困难。从 bug 修复角度上看,端对端测试阶段修复的 bug 的成本要高于修复单元测试阶段出现的 bug。所以,相对而言,单元测试是性价比较高的测试手段。通常建议各类测试所占比例是:单元测试 70%,集成测试 20%,E2E 测试 10%。
安利:单元测试的好处
写单元测试的好处能列举出来非常多,比如:
- 它能帮你在软件开发的早期发现问题,尽早修复,避免雪球越滚越大。
- 通过单元测试可以避免一个的 bug 反反复复出现,通过单元测试它进行封印。
- 结合一些自动化工具,可以避免人力测试,大幅减低重构之后的测试成本。 ...
对我而言,最重要的点是,写单元测试能让我更有信心交付代码。
反安利:单元测试的局限
从👆 三种测试类型对比可以看出,单元测试有它的局限性。由于”目光短浅”,只关注局部,无法保证最终表现。比如👇 的例子:
验证了伞可以正常打开,然鹅真实效果让人头大。
expect(umbrellaOpens).toBe(true)
tests: 1 passed, total
**all tests passed**
总结
这篇文章作为《别说你不会单元测试》系列的第一篇文章,介绍了什么是单元测试、集成测试、端对端测试以及单元测试的好处和局限。
下一篇文章将介绍单元测试中会涉及到的各类名词:断言、测试替身、测试覆盖率、执行环境、测试框架等等。欢迎点赞+关注,这样会让我更有动力写技术博客。