一个完整的项目当然少不了测试,本章我们将搭建项目的测试环境。
安装jest
我们使用jest
作为测试框架,jest上手非常简单。本章节文章组织比较特殊,我们将跟随文档一步步搭建jest单元测试环境。
依赖安装
进入官网=>Getting Started · Jest (jestjs.io),文档非常简洁明了,首先安装依赖:
编写测代码
接着按照文档步骤写测试代码:
添加运行脚本
运行
非常顺利的添加到我们项目中
测试typescript文件
上面我们非常顺利的运行了js的测试,但是我们的项目使用的是typescript,而jest
是不能直接使用typescript的,我们先来处理typescript运行的问题。
测试代码编写
先将上面的测试例子换为typescript格式
// /sum.ts
export default function sum(a: any, b: any) {
return a + b;
}
复制代码
// /sum.test.ts
import sum from "./sum";
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
复制代码
运行后会报如下错误
引入typescript
我们继续查阅文档Getting Started · Jest (jestjs.io)看看该怎么支持typescript。
同样很方便的找到相关文档,这里告诉我们可以通过Babel
来支持typescript,且先需要引入Babel,那么我们先到使用Babel的章节看看。
非常清晰明了,直接按照提示安装依赖,并创建babel.config.js
文件即可。最后安装babel用于处理typescript的插件。
// 安装babel环境
npm install --save-dev babel-jest @babel/core @babel/preset-env
// 安装处理typescript插件
npm install --save-dev @babel/preset-typescript
复制代码
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
targets: {node: 'current'},
}],
'@babel/preset-typescript',
],
};
复制代码
运行npm test
可以看到已经可以成功测试typescript类型的代码了。
测试unified
接下来我们可以将unified
引入测试代码,新建一个测试文件,并引入unified
打印出来
// index.test.ts
import { unified } from "unified";
test('test unified', () => {
console.log(unified)
});
复制代码
不出意外运行后会报如下错误
这个错误很是让人迷惑,明明前面的typescript能够正常运行,为什么这里就有问题了。这里我们来捋一捋前面的过程。
在前面的步骤中,我们使用了babel
,它用于在jest运行时将typescript类型的代码转为javascript,重新看看我们在babel.config.js
中使用的配置:
@babel/preset-env
:用于将高级的js语法编译成低级语法,所以这个暂时没啥用,去掉也不影响。@babel/preset-typescript
: 用于将typescript
转为javascript
。
从上图的报错来看,给出的提示代码应该是已经经过babel转换后的代码,而在之前的文章提过,由于unified
是纯ESM
的形式打包,所以不能用require
的方式来导入unified。所以猜测应该是babel将ts文件转为CommonJS
类型的js,导致引入错误。
我们来验证一下是否是babel转换的问题,先试一下手动转换:
# 安装babel-cli
npm install --save-dev @babel/cli
# 手动转换index.test.ts文件
.\node_modules\.bin\babel ./index.test.ts --out-dir lib --extensions .ts
复制代码
查看转换后的文档,果然跟报错信息长得一样
那么我们可以得到结论,是由于jest执行了带有requireESM
的代码导致的错误。
处理包导入错误
由于前面我们已经使用了babel,那么我们可不可以使用babel将ESM转为CommonJS呢,这样的话所有代码都统一使用CommonJS来执行就不会报错了。经过一番寻找,找到了babel的插件:
文档中说了该插件已经被集成在
preset-env
中,那我们就直接使用吧。
由于jest默认不使用babel转换node_modules下的文件,现在我们就更改配置,将node_modules里的文件加入babel解析。Configuring Jest - transformIgnorePatterns· Jest (jestjs.io)
// jest.config.js
module.exports = {
// jest默认配置为["/node_modules/", "\\.pnp\\.[^\\\/]+$"],不会解析node_modules下内容
transformIgnorePatterns: [],
};
复制代码
再次运行代码后,可以看到测试已顺利运行
整理代码
我们将测试代码放入/test目录,将前面一节开发环境的例子引入,测试我们自己创建的插件
// /test/remarkFootnote.ts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkStringify from "remark-stringify";
import remarkFootnote from '../src/remark/remarkFootnote';
test('remarkFootnote', () => {
const res = unified()
.use(remarkParse)
.use(remarkFootnote)
.use(remarkStringify)
.processSync('# hello unified-md')
console.log(res)
});
复制代码
至此,我们的测试环境就成功搭建起来了,中间遇到的问题相对来说比较复杂,而且解决方案不止这一种。解决复杂问题需要我们将问题简单化,将大问题尽量拆解成细粒度的问题一个个突破。
jest
的其他用法在这里不赘述,感兴趣的同学可以到官网查阅相关文档。