前端自動(dòng)化測(cè)試:Jest 測(cè)試框架應(yīng)用
Jest : https://jestjs.io/zh-Hans/是 Facebook 出品的一個(gè) JavaScript 開源測(cè)試框架。
相對(duì)其他測(cè)試框架,其一大特點(diǎn)就是就是內(nèi)置了常用的測(cè)試工具,比如零配置、自帶斷言、測(cè)試覆蓋率工具等功能,實(shí)現(xiàn)了開箱即用。
Jest 適用但不局限于使用以下技術(shù)的項(xiàng)目:Babel、TypeScript、 Node、 React、Angular、Vue 等。
Jest 主要特點(diǎn):
零配置
自帶斷言
作為一個(gè)面向前端的測(cè)試框架, Jest 可以利用其特有的快照測(cè)試功能,通過比對(duì)UI 代碼生成的快照文件,實(shí)現(xiàn)對(duì) React 等常見前端框架的自動(dòng)測(cè)試。
Jest 的測(cè)試用例是并行執(zhí)行的,而且只執(zhí)行發(fā)生改變的文件所對(duì)應(yīng)的測(cè)試,提升了測(cè)試速度。
測(cè)試覆蓋率
Mock 模擬
快速體驗(yàn) Jest
安裝 Jest 到項(xiàng)目中:
npm install --save-dev jest//math.jsfunctionadd (a, b) {return a * b}functionsubtract (x, y) {return x - y}module.exports= {add,subtract}
//test.js ==> math.test.jsconst { add, subtract } =require('./math')test('測(cè)試加法', () => {expect(add(1,2)).toBe(3)})test('測(cè)試減法', () => {expect(subtract(2,1)).toBe(1)})
//package.json{"scripts":{"test":"jest"}}
jest 命令會(huì)運(yùn)行項(xiàng)目中所有以 .test.js 結(jié)尾的文件
最后運(yùn)行測(cè)試命令:
npm run test
解析:
jest 找到項(xiàng)目中所有以 .test.js 結(jié)尾的文件并運(yùn)行
jest 會(huì)給測(cè)試文件提供 test、expect 等全局函數(shù),所以在測(cè)試文件中可以直接使用
jest 為測(cè)試結(jié)果提供了良好的日志輸出
解決 vscode 中 jest 代碼提示問題
npm i -D @types/jest注意:@types/jest 必須安裝到項(xiàng)目的根目錄,并且以根目錄的方式在 vscode 中打開,否則不生效。或者說只要是 vscode 打開的項(xiàng)目根目錄有 @types/jest 這個(gè)包就可以了。
配置文件
npx jest--init配置文件生成選項(xiàng):
是否使用 ts ;
使用哪種測(cè)試環(huán)境;
使用 jest 收集測(cè)試覆蓋率報(bào)告;
使用那種引擎檢測(cè)覆蓋率:v8 處于實(shí)驗(yàn)性階段,建議 Node v14 后使用,babel 較為成熟
每次測(cè)試時(shí),是否自動(dòng)清除 mock 實(shí)例;
詳細(xì)配置信息參考:https://jestjs.io/docs/zh-Hans/configuration。
//jest.config.js/** For a detailedexplanation regarding each configuration property, visit:*https://jestjs.io/docs/en/configuration.html*/module.exports= {// 自動(dòng) mock 所有導(dǎo)入的外部模塊// automock: false,// 在指定次數(shù)失敗后停止運(yùn)行測(cè)試// bail: 0,// The directory where Jest should store its cached dependencyinformation// cacheDirectory:"/private/var/folders/5h/_98rffpj1z95b_0dm76lvzm40000gn/T/jest_dx",// 在每個(gè)測(cè)試之間自動(dòng)清除 mock 調(diào)用和實(shí)例clearMocks:true,// 是否收集測(cè)試覆蓋率信息// collectCoverage: false,// 一個(gè) glob 模式數(shù)組,指示應(yīng)該為其收集覆蓋率信息的一組文件// collectCoverageFrom: undefined,// 測(cè)試覆蓋率報(bào)錯(cuò)文件輸出的目錄coverageDirectory:"coverage",// 忽略測(cè)試覆蓋率統(tǒng)計(jì)// coveragePathIgnorePatterns: [// "/node_modules/"// ],// 指示應(yīng)該使用哪個(gè)提供程序檢測(cè)代碼的覆蓋率,默認(rèn)是 babel,可選 v8,但是 v8 不太穩(wěn)定,建議Node 14 以上版本使用// coverageProvider: "babel",// A list of reporter names that Jest uses when writingcoverage reports// coverageReporters: [// "json",// "text",// "lcov",// "clover"// ],// An object that configures minimum threshold enforcement forcoverage results// coverageThreshold: undefined,// A path to a custom dependency extractor// dependencyExtractor: undefined,// Make calling deprecated APIs throw helpful error messages// errorOnDeprecated: false,// Force coverage collection from ignored files using an arrayof glob patterns// forceCoverageMatch: [],// A path to a module which exports an async function that istriggered once before all test suites// globalSetup: undefined,// A path to a module which exports an async function that istriggered once after all test suites// globalTeardown: undefined,// A set of global variables that need to be available in alltest environments// globals: {},// The maximum amount of workers used to run your tests. Canbe specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPUamount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2workers.// maxWorkers: "50%",// An array of directory names to be searched recursively upfrom the requiring module's location// moduleDirectories: [// "node_modules"// ],// An array of file extensions your modules use// moduleFileExtensions: [// "js",// "json",// "jsx",// "ts",// "tsx",// "node"// ],// A map from regular expressions to module names or to arraysof module names that allow to stub out resources with a single module// moduleNameMapper: {},// An array of regexp pattern strings, matched against allmodule paths before considered 'visible' to the module loader// modulePathIgnorePatterns: [],// Activates notifications for test results// notify: false,// An enum that specifies notification mode. Requires {notify: true }// notifyMode: "failure-change",// A preset that is used as a base for Jest's configuration// preset: undefined,// Run tests from one or more projects// projects: undefined,// Use this configuration option to add custom reporters toJest// reporters: undefined,// Automatically reset mock state between every test// resetMocks: false,// Reset the module registry before running each individualtest// resetModules: false,// A path to a custom resolver// resolver: undefined,// Automatically restore mock state between every test// restoreMocks: false,// The root directory that Jest should scan for tests andmodules within// rootDir: undefined,// A list of paths to directories that Jest should use tosearch for files in// roots: [// "<rootDir>"// ],// Allows you to use a custom runner instead of Jest's defaulttest runner// runner: "jest-runner",// The paths to modules that run some code to configure or setup the testing environment before each test// setupFiles: [],// A list of paths to modules that run some code to configureor set up the testing framework before each test// setupFilesAfterEnv: [],// The number of seconds after which a test is considered asslow and reported as such in the results.// slowTestThreshold: 5,// A list of paths to snapshot serializer modules Jest shoulduse for snapshot testing// snapshotSerializers: [],// The test environment that will be used for testing// testEnvironment: "jest-environment-jsdom",// Options that will be passed to the testEnvironment// testEnvironmentOptions: {},// Adds a location field to test results// testLocationInResults: false,// The glob patterns Jest uses to detect test files// testMatch: [// "**/__tests__/**/*.[jt]s?(x)",// "**/?(*.)+(spec|test).[tj]s?(x)"// ],// An array of regexp pattern strings that are matched againstall test paths, matched tests are skipped// testPathIgnorePatterns: [// "/node_modules/"// ],// The regexp pattern or array of patterns that Jest uses todetect test files// testRegex: [],// This option allows the use of a custom results processor// testResultsProcessor: undefined,// This option allows use of a custom test runner// testRunner: "jasmine2",// This option sets the URL for the jsdom environment. It isreflected in properties such as location.href// testURL: "http://localhost",// Setting this value to "fake" allows the use offake timers for functions such as "setTimeout"// timers: "real",// A map from regular expressions to paths to transformers// transform: undefined,// An array of regexp pattern strings that are matched againstall source file paths, matched files will skip transformation// transformIgnorePatterns: [// "/node_modules/",// "\\.pnp\\.[^\\/]+$"// ],// An array of regexp pattern strings that are matched againstall modules before the module loader will automatically return a mock for them// unmockedModulePathPatterns: undefined,// Indicates whether each individual test should be reportedduring the run// verbose: undefined,// An array of regexp patterns that are matched against allsource file paths before re-running tests in watch mode// watchPathIgnorePatterns: [],// Whether to use watchman for file crawling// watchman: true,};
Jest CLI Options
參考:https://jestjs.io/zh-Hans/docs/cli
指定測(cè)試文件運(yùn)行
"scripts":{"test":"jest ./math.test.js"},
Jest 監(jiān)視模式
--watchAll 選項(xiàng):監(jiān)視文件的更改并在任何更改時(shí)重新運(yùn)行所有測(cè)試。
"scripts": {"test": "jest --watchAll"},
Jest API
在測(cè)試文件中,Jest 將所有這些方法和對(duì)象放入全局環(huán)境中。無需要求或?qū)肴魏蝺?nèi)容即可使用它們。但是,如果喜歡顯式導(dǎo)入,則可以:
import { describe, expect, test } from'@jest/globals'Test 函數(shù)
test 函數(shù)別名:it(name, fn, timeout)。
test(name,fn, timeout)
test.concurrent(name, fn, timeout)
test.concurrent.each(table)(name, fn, timeout)
test.concurrent.only.each(table)(name, fn)
test.concurrent.skip.each(table)(name, fn)
test.each(table)(name, fn, timeout)
test.only(name, fn, timeout)
只運(yùn)行當(dāng)前測(cè)試用例
test.only.each(table)(name, fn)
test.skip(name,fn)
test.skip.each(table)(name, fn)
test.todo(name)
創(chuàng)建 global-api.test.js 測(cè)試文件,注意,測(cè)試文件中必須有一個(gè)測(cè)試用例,如果沒有則直接報(bào)錯(cuò)。
test('should ', () => {console.log('test--api')})
test('should ', () => {console.log('test--api')})test('should1 ', () => {console.log('test--api1')})// 上面兩個(gè)不運(yùn)行test.only('should2 ', () => {console.log('test--api2')})
Expect 匹配器
在編寫測(cè)試時(shí),通常需要檢查值是否滿足某些條件。Expect 讓我們可以訪問許多“匹配器”,以驗(yàn)證不同的內(nèi)容。
test('two plus two is four', () => {expect(2+2).toBe(6)expect({ name:'jack' }).toEqual({ name:'jack' })expect('Christoph').toMatch(/stop/)expect(4).toBeGreaterThan(3)expect(4).toBeLessThan(5)})
完整的匹配器列表查看:https://jestjs.io/zh-Hans/docs/expect
describe 函數(shù)
describe 創(chuàng)建一個(gè)將幾個(gè)相關(guān)測(cè)試組合在一起的塊。
const myBeverage = {delicious:true,sour:false,};describe('my beverage', () => {test('is delicious', () => {expect(myBeverage.delicious).toBeTruthy();});test('is not sour', () => {expect(myBeverage.sour).toBeFalsy();});});
分組最直觀的就是在測(cè)試提示中,有更加友好的信息輸出。
describe(name,fn)
describe.each(table)(name, fn, timeout)
describe.only(name,fn)
describe.only.each(table)(name, fn)
describe.skip(name,fn)
describe.skip.each(table)(name, fn)
推薦閱讀:
前端自動(dòng)化測(cè)試:測(cè)試到底測(cè)什么?
Vite 的插件機(jī)制:插件應(yīng)用和基本使用
前端工程化中的重要環(huán)節(jié)——自動(dòng)化構(gòu)建
更新不易,點(diǎn)個(gè)“在看”和“贊”吧(●'?'●)!
