開始
項目里安裝 Jest
yarn add --dev jest
# or
npm install --save-dev jest
初始化配置文件
在根目錄下生成 jest.config.js 的配置文件,scripts里添加的jest命令會在 jest.config.js 里找配置
npx jest --init
一些報錯原因及處理
不支持es模塊的處理
由於針對的是ui組件庫進行測試不是純函數測試,如果直接運行jest測試的話,會出現報錯 SyntaxError: Cannot use import statement outside a module
Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it. // 要支持 esmodule,還需要加babel插件
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. // node_modules里有不需要轉換的模塊,需要載jest.config.js 配置文件里加transformIgnorePatterns來忽略
• If you need a custom transformation specify a "transform" option in your config. // jest.config.js 配置文件里添加transform來配置編譯器
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. // 如果需要支持css/less等,要在jest.config.js 配置文件里加transform 配置項
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
^^^^^^xxx
SyntaxError: Cannot use import statement outside a module
這是因為jest默認不支持es模塊。
官方支持ESM的配置 Native support for ES Modules
查詢官方文檔中26.x版本關於ECMAScript Modules 的支持,對於這個特性的支持還是實驗性的,目前bug也比較多,而且並未涉及到ts支持的介紹,如果是ts,需要使用ts-jest, 但是 ts-jest 的ESM 支持只有v27++版本可用,所以,如果用的是ts,是不能夠使用 --experimental-vm-modules 特性的。
27.x-next版本ECMAScript Modules介紹里有支持ts,配合ts-jest的27.x-next版本使用,新增了extensionsToTreatAsEsm配置項
ts-jest 的 ESM Support配置文檔
如果使用27.x 還需要注意本地node版本限制 jest@27.0.0-next.4: The engine "node" is incompatible with this module. Expected version "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0". Got "14.13.1"
25.x 版本及以前的不支持 esm 需要使用babel處理es模塊
// babel.config.js
module.exports = {
env: {
test: { // 環境變量為test下的配置
presets: ['@babel/preset-react', ['@babel/preset-env', { targets: {node: "current"}}],'@babel/preset-typescript'],
plugins: [
['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],
['@babel/plugin-transform-runtime'],
['@babel/plugin-transform-modules-commonjs'] // jest不支持es模塊,用babel處理
],
}
}
}
另外如果 import './style.less'
less文件報錯的話,需要使用 identity-obj-proxy 轉換
yarn add identity-obj-proxy --dev
jest.config.js
module.exports = {
testMatch: ['/__tests__/*.[jt]s?(x)'], // __tests__目錄下的 j(t)s(x) 測試文件
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'],
transform: {
// 用 `ts-jest` 處理 `*.ts` 文件
'.*\\.(ts|tsx)$': 'ts-jest',
// 用 `babel-jest` 處理 js
'.*\\.(js|jsx)$': 'babel-jest'
},
moduleNameMapper: { //
'^.+\\.(css|less)$': 'identity-obj-proxy' // 使用 identity-obj-proxy mock CSS Modules
},
transformIgnorePatterns: ['<rootDir>/node_modules/(?!(enzyme))'], // transform編譯忽略哪些文件
collectCoverage: true, // 開啟收集Coverage(測試覆蓋范圍)
coverageDirectory: '<rootDir>/coverage/', // 指定生成的coverage目錄
coveragePathIgnorePatterns: ['<rootDir>/coverage/'] //該路徑下的測試,忽略測試覆蓋率
}
使用babel
yarn add --dev babel-jest @babel/core @babel/preset-env
// babel.config.js
module.exports = {
presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};
使用TypeScript
yarn add --dev @babel/preset-typescript @types/jest
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
};
ts 配置報錯
const Foo = () => <div>foo</div>;
^
SyntaxError: Unexpected token '<'
這里是因為 tsconfig.json 里的配置jsx配置
jsx配置從preserve改成react或者react-jsx
一個參考配置
{
"compilerOptions": {
"baseUrl": "./",
"target": "esnext",
"moduleResolution": "node",
"jsx": "react-jsx",
"esModuleInterop": true,
"experimentalDecorators": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"suppressImplicitAnyIndexErrors": true,
"declaration": true,
"skipLibCheck": true
},
"exclude": ["node_modules/**"]
}