关于Jest
框架名称 | 断言 | 快照测试 | 覆盖率报告 | 仿真 | 中文文档 | Github Star | 优点 | 缺点 |
---|---|---|---|---|---|---|---|---|
Jest | √ | √ | √ | √ | √ | 36K | 开箱即用,配置少,文档齐全 | 学习成本较高 |
Mocha | × | × | × | × | × | 20.7K | 灵活,文档齐全 | 配置复杂 |
选择jest的原因:
- 功能全,虽然整体学习成本较高,但可以渐进式使用部分功能
- 配置少,不需要从庞大的生态中挑选插件,开箱即用
- 虽然不像Mocha那样灵活,但是该项目不需要那么高的灵活度
- 有《Vue.js应用测试》讲解vue-jest和jest如何工作、测试的,Vue对jest支持也比较好,有专门的vue-jest模块,相关中文文档也多
项目配置
项目依赖版本:
- jest: "^27.0.6"
- vue-jest: "^3.0.7"(用于vue文件的编译)
- ts-jest: "^27.0.3"(用于ts文件的编译)
- ts-node: "^10.1.0"
- @types/jest: "^24.9.1"
- @vue/composition-api: "^1.0.3"(^1.0.0-beta.10与jest^27.0.6不兼容)
- jest-transform-stub: "^2.0.0"(处理最终结果非JS的文件)
- jest-serializer-vue: "^2.0.2"
配置文件 -- jest.config.ts
// jest.config.ts
import type { InitialOptionsTsJest } from "ts-jest/dist/types"
const config: InitialOptionsTsJest = {
preset: "ts-jest",
// 官方配置集,由于使用了TypeScript,故选用ts-jest
globals: {
"ts-jest": {
tsconfig: "tsconfig.test.json"
// Jest的ts配置文件
}
},
testEnvironment: "jsdom",
// 使用jsdom模拟真实dom
moduleFileExtensions: ["js", "ts", "json", "vue"],
// 如果模块路径不带后缀名,jest会按这个数组从左到右的优先顺序寻找文件
transform: {
"^.+\\.vue$": "vue-jest", // vue-jest把vue文件编译成js
"^.+\\.[tj]sx?$": "ts-jest", // ts-jest把[tj]sx?文件编译成js
".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub" // 处理最终结果非JS的文件,原理是直接返回空字符串,因为最终结果非JS的文件无法测试
},
rootDir: "./",
// jest配置文件或package.json所在路径
testMatch: ["<rootDir>/js/activity/apple-gift-card/test/**/*.+(ts|tsx|js)"],
// Jest使用glob模式来检测测试文件。默认情况下,它会在测试文件夹中查找.js、.jsx、.ts和.tsx文件,以及任何后缀为.test或.spec的文件(例如Component.test.js或Component.spec.js)。它还会找到名为test.js或spec.js的文件。
collectCoverageFrom: [
"<rootDir>/js/activity/apple-gift-card/components/**/**.ts",
"!<rootDir>/js/activity/apple-gift-card/components/useLocation.ts"
],
// 计算测试覆盖率的范围
snapshotSerializers: ["jest-serializer-vue"],
// vue的快照插件
setupFiles: ["<rootDir>/jest-setup.ts"],
// 初始化Jest全局环境
transformIgnorePatterns: ["<rootDir>/node_modules/?!(vuex-composition-helpers)"]
// 由于node_modules默认是已经transpiled的文件,所以会忽略而不走transform的编译链,加快测试速度
// 但有些模块发布时就是Typescript或者ESM语法,node环境无法直接运行,所以要让它走transform的编译链
}
export default config
配置值字符串中的<rootDir>会被替换成rootDir的值,即
"<rootDir>/js/activity/apple-gift-card"
最终会变成"./js/activity/apple-gift-card"
babel配置 -- babel.config.js
// babel.config.js
module.exports = function () {
return {
// ...
env: {
test: {
presets: ["@vue/cli-plugin-babel/preset"]
}
}
}
}
在vue中引入.vue文件会出现
SyntaxError: Unexpected token 'export'
错误
// 原因:虽然在js、ts文件中引入.vue文件可以被vue-jest编译,但在vue中引入.vue文件需要babel引入@vue/cli-plugin-babel/preset进行编译
初始化文件 -- jest-setup.ts
// jest-setup.ts
// 导入顺序有要求:(jsdom ->) @vue/test-utils -> Vue
import VueCompositionApi from "@vue/composition-api"
require("@vue/test-utils")
const Vue = require("vue")
Vue.use(VueCompositionApi)