给 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 项目编写单元测试的一些小经验的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 中的单元测试 [关闭]

如何使用 Jasmine 为私有方法编写 Angular / TypeScript 单元测试

mocha+Typescript的单元测试搭建

使用 Jasmine 和 TypeScript 进行单元测试

为啥使用 jasmine 对 Node typescript 项目进行 Karma 单元测试会显示包含依赖项的覆盖范围?

使用 Jest 和 Typescript 对 VueJ 进行单元测试 - 未安装组件