前端自动化测试:Jest 测试框架应用

勾勾的前端世界

共 9348字,需浏览 19分钟

 · 2021-06-26

Jest : https://jestjs.io/zh-Hans/是 Facebook 出品的一个 JavaScript 开源测试框架


相对其他测试框架,其一大特点就是就是内置了常用的测试工具,比如零配置、自带断言、测试覆盖率工具等功能,实现了开箱即用


Jest 适用但不局限于使用以下技术的项目:Babel、TypeScript、 Node、 React、Angular、Vue 等。

 

Jest 主要特点:

  • 零配置

  • 自带断言

  • 作为一个面向前端的测试框架, Jest 可以利用其特有的快照测试功能,通过比对UI 代码生成的快照文件,实现对 React 等常见前端框架的自动测试。

  • Jest 的测试用例是并行执行的,而且只执行发生改变的文件所对应的测试,提升了测试速度。

  • 测试覆盖率

  • Mock 模拟

 

快速体验 Jest

安装 Jest 到项目中:

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('测试加法', () => { expect(add(1,2)).toBe(3)})
test('测试减法', () => { expect(subtract(2,1)).toBe(1)})


//package.json{  "scripts":{    "test":"jest"  }}


jest 命令会运行项目中所有以 .test.js 结尾的文件


最后运行测试命令:

npm run test

 

解析:

  • jest 找到项目中所有以 .test.js 结尾的文件并运行

  • jest 会给测试文件提供 test、expect 等全局函数,所以在测试文件中可以直接使用

  • jest 为测试结果提供了良好的日志输出

 

解决 vscode 中 jest 代码提示问题

npm i -D @types/jest


注意:@types/jest 必须安装到项目的根目录,并且以根目录的方式在 vscode 中打开,否则不生效。或者说只要是 vscode 打开的项目根目录有 @types/jest 这个包就可以了。

 

配置文件

npx jest--init


配置文件生成选项:

是否使用 ts ;

使用哪种测试环境;

使用 jest 收集测试覆盖率报告;

使用那种引擎检测覆盖率:v8 处于实验性阶段,建议 Node v14 后使用,babel 较为成熟

每次测试时,是否自动清除 mock 实例;


详细配置信息参考: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= { // 自动 mock 所有导入的外部模块 // automock: false,
// 在指定次数失败后停止运行测试 // bail: 0,
// The directory where Jest should store its cached dependencyinformation // cacheDirectory:"/private/var/folders/5h/_98rffpj1z95b_0dm76lvzm40000gn/T/jest_dx",
// 在每个测试之间自动清除 mock 调用和实例 clearMocks:true,
// 是否收集测试覆盖率信息 // collectCoverage: false,
// 一个 glob 模式数组,指示应该为其收集覆盖率信息的一组文件 // collectCoverageFrom: undefined,
// 测试覆盖率报错文件输出的目录 coverageDirectory:"coverage",
// 忽略测试覆盖率统计 // coveragePathIgnorePatterns: [ // "/node_modules/" // ],
// 指示应该使用哪个提供程序检测代码的覆盖率,默认是 babel,可选 v8,但是 v8 不太稳定,建议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

指定测试文件运行

  "scripts":{    "test":"jest ./math.test.js"  },


Jest 监视模式

--watchAll 选项:监视文件的更改并在任何更改时重新运行所有测试。

 "scripts": {   "test": "jest --watchAll"  },


Jest API

在测试文件中,Jest 将所有这些方法和对象放入全局环境中。无需要求或导入任何内容即可使用它们。但是,如果喜欢显式导入,则可以:

import { describe, expect, test } from'@jest/globals'


Test 函数

test 函数别名: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)


只运行当前测试用例

  • test.only.each(table)(name, fn)

  • test.skip(name,fn)

  • test.skip.each(table)(name, fn)

  • test.todo(name)

 

创建 global-api.test.js 测试文件,注意,测试文件中必须有一个测试用例,如果没有则直接报错。

test('should ', () => {  console.log('test--api')})

 

test('should ', () => {  console.log('test--api')})test('should1 ', () => {  console.log('test--api1')})
// 上面两个不运行test.only('should2 ', () => { console.log('test--api2')})

 

Expect 匹配器

在编写测试时,通常需要检查值是否满足某些条件。Expect 让我们可以访问许多“匹配器”,以验证不同的内容。

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 函数

describe 创建一个将几个相关测试组合在一起的块。

const myBeverage = {  delicious:true,  sour:false,};
describe('my beverage', () => { test('is delicious', () => { expect(myBeverage.delicious).toBeTruthy(); });
test('is not sour', () => { expect(myBeverage.sour).toBeFalsy(); });});


分组最直观的就是在测试提示中,有更加友好的信息输出。


  • 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)

 

推荐阅读:

前端自动化测试:测试到底测什么?

Vite 的插件机制:插件应用和基本使用

前端工程化中的重要环节——自动化构建

效率提升利器:你还害怕自动化部署吗


更新不易,点个“在看”和“”吧(●'◡'●)!

浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报