# TypeScript 工程化:单元测试
单元测试是现代软件工程中必备的环节之一,通常一定规模的团队会有专门的测试人员,但是一些精悍的团队也会选择开发人员自行测试。
虽然 TypeScript 的类型检查和 ESLint 的代码检测已经让我们的代码足够强大,但是这仅仅停留在类型和语法层面,我们无法保证逻辑的正确性,这就需要单元测试来保证我们的逻辑的健壮性了。
# 单元测试工具的选择
在 JS/TS 的世界里有太多的单元测试框架可供选择了,我们逐一进行对比,来选出一个适合我们的框架。
# Mocha

Mocha 可能是当前被使用最多的单元测试工具,他最大的优点就是灵活,它只提供给开发者的只有一个基础测试结构。
然后其它功能性的功能如 assertions, spies,mocks,和像它们一样的其它功能需要引用添加其它库/插件来完成。
它的缺点也是他的优点,我们需要额外的引入众多辅助库和插件,这无形中增加了我们的学习成本和配置成本。
除此之外, Mocha 的另一大亮点是对异步的强大支持,Mocha 毕竟是从一开始为 Node.js 而生的单元测试框架,对浏览器的支持并不如其对服务器做的那么好。
如果你需要一个高度定制的测试框架,Mocha 是非常好的选择。
# Jasmine

相比于 Mocha 需要进行额外配置,另一个比较老牌的测试框架 Jasmine 主打的则是开箱即用,它内置了一些断言库和 mocks 工具,并提供了全局变量非常方便我们的测试。
# Jest
Jest 是一个真正意义上开箱即用的测试框架,它集成了几乎单元测试中我们需要的所有功能,比如:断言、测试覆盖率统计、快照等等一系列功能。
比较友好地支持各种环境,目前前端三大框架都采用了 Jest 作为测试工具,它的优点如下:
- 性能 - 首先 Jest 基于并行测试多文件,所以在大项目中的运行速度相当快(我们在这一点上深有体会,你可以访问这里、这里、这里和这里了解更多)。
- UI - 清晰且操作简单
- Ready-To-Go - 有断言、spies、mocks,和 Sinon 能做的事差不多。和其他库的结合使用也很方便。
- Globals - 和 Jasmine 一样,默认创建全局环境。但这一个特性确实会降低代码灵活性和健壮性,但是非常方便测试者调用。
- 快照测试 - Jest 快照功能由 FB 开发和维护,它还可以平移到别的框架上作为插件使用。 更强大的模块级 mocking 功能 - Jest 允许开发者用非常简单的方法 mock 很重的库,达到提高测试效率的目的。比如可以模拟一个 promise 的 resolve,而不是真的进行网络请求。
- 代码覆盖检查 - 内置了一个基于 Istanbul 的代码覆盖工具,功能强大且性能高。
- 支持性 - Jest 在2016年末2017年初发布了大版本,各方面都有了很大提升。大部分主流 IDE 和工具都已支持
- 开发 - Jest 仅仅更新被修改的文件,所以在监控模式 (watch mode) 下它的运行速度非常快
Jest 正是基于 Jasmine 开发而来,如果你喜欢 Jasmine,那么为什么不用 Jest,他比 Jasmine 更加大而全,更加开箱即用。
# 我们的选择
其实在我们面前有两条路,一条是灵活配置但是学习成本陡峭的 Mocha,另一条是大而全开箱即用,却没那么灵活的 Jest,多数没有特殊要求的情况下我认为 Jest 会更适合我们,测试框架到底是一个工具,我们选择一个几乎不需要配置、开箱即用的框架是可以大大提高我们生产效率的选择。
# Jest 配置
# 安装 Jest
全局安装 Jest:
npm i jest -g
在项目中安装 Jest:
npm i -D jest @types/jest
# 初始化 Jest
我们在项目的根目录下初始化 jest:
jest --init
我们会被问到三个问题,我的选择如下:
- Choose the test environment that will be used for testing? node
- Do you want Jest to add coverage reports? y
- Automatically clear mock calls and instances between every test? y
