给 TypeScript 项目编写单元测试的一些小经验
Posted Node地下铁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了给 TypeScript 项目编写单元测试的一些小经验相关的知识,希望对你有一定的参考价值。
用 TypeScript 写软件也快两年了,其中怎么给 TypeScript 写单测也有一些沉淀,今天跟大家分享一下。我们的取向也许没有那么激进,都是用的比较顺手的方式。
用 Mocha 给 TypeScript 编写单测
因为一直都在用 Mocha,所以我们切换到 TypeScript 之后也一直在用 Mocha 来写单元测试,并没有什么深刻的原因。
用 Mocha 编写 TypeScript 的单元测试,依靠两个包 @types/mocha
和 ts-node
。 其中 @types/mocha
是 Mocha 的类型定义,而 ts-node
则让 Node.js 可以直接启动 TypeScript 程序。
我们一般会这么写 mocha.opts
文件:
--require ts-node/register
test/**/*.test.ts
其中 ts-node/register
会让 Node.js 支持直接加载 TypeScript 程序(其实也就是运行时进行了编译而已)。
然后可以在测试的程序里面 import 'mocha';
加载 @types/mocha
里面提供的 mocha 的类型信息,这样 describe 和 it 都有类型提示了。
统计测试覆盖率
我们对于软件质量有一个最简洁的要求,分支覆盖率高于 80%,所以统计分支覆盖率也是个刚性需求了。我们一般使用 NYC 来统计单元测试覆盖率,是 Istanbul 团队提供的 Istanbul 的命令行工具。
通过执行 nyc mocha
来统计测试覆盖率,通常会把这个命令定义为 package.json 中的 script,比如 npm run cov
这样来执行(这样也方便 Lerna 批量来执行)。
我们一般会在 package.json 中这样配置 NYC:
"nyc": {
"include": [
// 要 Include 的文件
"src/*.ts",
"src/**/*.ts"
],
"exclude": [
// 排除掉 typings (其实也早已不用 typings 了),
// 还有编译出来的文件
"typings",
"dist"
],
"extension": [
".ts"
],
"require": [
// 当然 ts-node 也必须加入
"ts-node/register"
],
"reporter": [
"json",
"html"
],
// 打开 --all 标志,让单测尚未引用到的文件也出现到报告里面
"all": true
},
执行 npm run cov
之后,就可以通过 coverage/index.html
查看详细的覆盖率情况了。
Lerna 下统计测试覆盖率
我们喜欢用 Lerna 来统一管理同一个项目下的多个 NPM 包,统计单元测试就变得复杂了,总不能每个子包都执行一次吧?
最初我们编写了一个 Shell 脚本来做这个事情,但直到 lerna 提供了 run 命令就可以简单的在最顶层运行 nyc lerna run cov --concurrency=1
了。
NYC 实际上是通过 spawn-wrapper 来注入子进程(进程树层级深也没关系)的,所以我们通过 lerna run
来执行每个子包下面的 npm run cov
也自然是能统计到单元测试的。
当然最顶层的 NYC 配置也有一些不同:
{
"include": [
// 指定只 Include packages 下的 src 目录
"packages/*/src/*.ts",
"packages/*/src/**/*.ts"
],
"exclude": [
"**/typings",
"**/*.d.ts",
"**/dist",
"**/src/index.ts",
"**/src/domain.ts"
],
"extension": [
".ts"
],
"reporter": [
"json",
"html"
],
"all": true
}
值得注意的是,建议 nyc、ts-node 只在 lerna 项目最顶层安装,这样就不会出现单个包跑和一起跑版本不一样的问题了。
以上是关于给 TypeScript 项目编写单元测试的一些小经验的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jasmine 为私有方法编写 Angular / TypeScript 单元测试
使用 Jasmine 和 TypeScript 进行单元测试
为啥使用 jasmine 对 Node typescript 项目进行 Karma 单元测试会显示包含依赖项的覆盖范围?