概念

jest是Facebook出品的一个JavaScript开源测试框架。内置了零配置、自带断言、测试覆盖率工具等,实现了开箱即用。

jest的主要特点

  • 零配置
  • 自带断言
  • 快照测试功能,可以对常见前端框架进行自动化测试
  • jest测试用例是并行执行的,而且只执行发生改变的文件所对应的测试,提升了速度
  • 测试覆盖率
  • Mock模拟

安装使用

npm i -D jest
npm i -D @types/jest

配置文件

初始化jest默认文件

$ npx jest --init
npx: 332 安装成功,用时 29.723 秒The following questions will help Jest to create a suitable configuration for your project√ Would you like to use Jest when running "test" script in "package.json"? ... yes
√ Would you like to use Typescript for the configuration file? ... no
√ Choose the test environment that will be used for testing » jsdom (browser-like)
√ Do you want Jest to add coverage reports? ... yes
√ Which provider should be used to instrument code for coverage? » babel
√ Automatically clear mock calls, instances and results before every test? ... yes

生成jest.config.js配置文件,并有jest的所有注释的配置文件

/** For a detailed explanation regarding each configuration property, visit:* https://jestjs.io/docs/configuration*/module.exports = {// All imported modules in your tests should be mocked automatically// automock: false,// Stop running tests after `n` failures// bail: 0,// The directory where Jest should store its cached dependency information// cacheDirectory: "C:\\Users\\Alvin\\AppData\\Local\\Temp\\jest",// Automatically clear mock calls, instances and results before every testclearMocks: true,// Indicates whether the coverage information should be collected while executing the testcollectCoverage: true,// An array of glob patterns indicating a set of files for which coverage information should be collected// collectCoverageFrom: undefined,// The directory where Jest should output its coverage filescoverageDirectory: "coverage",// An array of regexp pattern strings used to skip coverage collection// coveragePathIgnorePatterns: [//   "\\\\node_modules\\\\"// ],// Indicates which provider should be used to instrument code for coverage// coverageProvider: "babel",// A list of reporter names that Jest uses when writing coverage reports// coverageReporters: [//   "json",//   "text",//   "lcov",//   "clover"// ],// An object that configures minimum threshold enforcement for coverage 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 array of glob patterns// forceCoverageMatch: [],// A path to a module which exports an async function that is triggered once before all test suites// globalSetup: undefined,// A path to a module which exports an async function that is triggered once after all test suites// globalTeardown: undefined,// A set of global variables that need to be available in all test environments// globals: {},// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.// maxWorkers: "50%",// An array of directory names to be searched recursively up from the requiring module's location// moduleDirectories: [//   "node_modules"// ],// An array of file extensions your modules use// moduleFileExtensions: [//   "js",//   "jsx",//   "ts",//   "tsx",//   "json",//   "node"// ],// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module// moduleNameMapper: {},// An array of regexp pattern strings, matched against all module 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 to Jest// reporters: undefined,// Automatically reset mock state before every test// resetMocks: false,// Reset the module registry before running each individual test// resetModules: false,// A path to a custom resolver// resolver: undefined,// Automatically restore mock state and implementation before every test// restoreMocks: false,// The root directory that Jest should scan for tests and modules within// rootDir: undefined,// A list of paths to directories that Jest should use to search for files in// roots: [//   "<rootDir>"// ],// Allows you to use a custom runner instead of Jest's default test runner// runner: "jest-runner",// The paths to modules that run some code to configure or set up the testing environment before each test// setupFiles: [],// A list of paths to modules that run some code to configure or set up the testing framework before each test// setupFilesAfterEnv: [],// The number of seconds after which a test is considered as slow and reported as such in the results.// slowTestThreshold: 5,// A list of paths to snapshot serializer modules Jest should use for snapshot testing// snapshotSerializers: [],// The test environment that will be used for testingtestEnvironment: "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 against all test paths, matched tests are skipped// testPathIgnorePatterns: [//   "\\\\node_modules\\\\"// ],// The regexp pattern or array of patterns that Jest uses to detect 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: "jest-circus/runner",// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href// testURL: "http://localhost",// Setting this value to "fake" allows the use of fake 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 against all source file paths, matched files will skip transformation// transformIgnorePatterns: [//   "\\\\node_modules\\\\",//   "\\.pnp\\.[^\\\\]+$"// ],// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them// unmockedModulePathPatterns: undefined,// Indicates whether each individual test should be reported during the run// verbose: undefined,// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode// watchPathIgnorePatterns: [],// Whether to use watchman for file crawling// watchman: true,
};

监视模式运行

监视文件的更改并在任何更改时重新运行所有测试

jest --watchAll

需要git支持

jest --watch

使用ES6模块

安装解析依赖

npm i -D babel-jest @babel/core @babel/preset-env

配置babel.config.js

module.exports = {presets: [['@babel/preset-env',{targets: {node: 'current' // node环境的解释}}]]
}

jest全局api

Test函数

test函数的别名:it(name, fn, timeout)

Expect匹配器

it('匹配器', () => {expect(2 + 2).tobe(4);expect({name: 'alvin'}).toEqual({name: 'alvin'});expect('Christoph').toMatch(/stop/);expect(4).toBeGreaterThan(3);expect(3).toBeLessThan(4);
})

describe函数

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

生命周期钩子

afterALl(fn, timeout)
afterEach(fn, timeout)
beforeAll(fn, timeout)
beforeEach(fn, timeout)

jest对象

Jest对象自动位于每个测试文件中的范围内。Jest对象中的方法有助于创建模拟,并让你控制Jest的整体行为。也可以通过import {jest} form '@jest/globals’导入。详细参考: https://jestjs.io/docs/jest-objest

jest对象中有许多的功能函数,例如:模拟定时器:jest.useFakeTimers()

常用匹配器

运行单个的测试文件

npm run test -- expect.spec.js

官方使用文档:https://jestjs.io/docs/using-matchers

Truthiness

test('null', () => {const n = null;expect(n).toBeNull();expect(n).toBeDefined();expect(n).not.toBeUndefined();expect(n).not.toBeTruthy();expect(n).toBeFalsy();
});test('zero', () => {const z = 0;expect(z).not.toBeNull();expect(z).toBeDefined();expect(z).not.toBeUndefined();expect(z).not.toBeTruthy();expect(z).toBeFalsy();
});

Numbers

test('two plus two', () => {const value = 2 + 2;expect(value).toBeGreaterThan(3);expect(value).toBeGreaterThanOrEqual(3.5);expect(value).toBeLessThan(5);expect(value).toBeLessThanOrEqual(4.5);// toBe and toEqual are equivalent for numbersexpect(value).toBe(4);expect(value).toEqual(4);
});test('adding floating point numbers', () => {const value = 0.1 + 0.2;//expect(value).toBe(0.3);           This won't work because of rounding errorexpect(value).toBeCloseTo(0.3); // This works.
});

Strings

test('there is no I in team', () => {expect('team').not.toMatch(/I/);
});test('but there is a "stop" in Christoph', () => {expect('Christoph').toMatch(/stop/);
});

Arrays and iterables

const shoppingList = ['diapers','kleenex','trash bags','paper towels','milk',
];test('the shopping list has milk on it', () => {expect(shoppingList).toContain('milk');expect(new Set(shoppingList)).toContain('milk');
});

Exceptions

function compileAndroidCode() {throw new Error('you are using the wrong JDK');
}test('compiling android goes as expected', () => {expect(() => compileAndroidCode()).toThrow();expect(() => compileAndroidCode()).toThrow(Error);// You can also use the exact error message or a regexpexpect(() => compileAndroidCode()).toThrow('you are using the wrong JDK');expect(() => compileAndroidCode()).toThrow(/JDK/);
});

测试异步代码

回调函数的方式使用

function getData(callback){setTimeout(() => {callback({foo: 'bar'})}, 2000)
}it("异步测试", (done) => {getData(data =>{done()expect(data).toEqual({foo: 'bar'})})
})

promise方式回调

function getData(data){return new Promise((resolve, reject) => {setTimeout(() => {resolve({foo: 'bar'})}, 2000)})
}it("异步promise测试", (done) => {getData().then(data => {done()expect(data).toEqual({foo: 'bar'})})
})it("异步promise直接return", () => {return getData().then(data => {expect(data).toEqual({foo: 'bar'})})
})it("异步promise 使用.resolve、.rejects", () => {return expect(getData()).resolves.toEqual({foo: 'bar'})
})

async和await方式

function getData(){return new Promise((resolve, reject) => {setTimeout(() => {resolve({foo: 'bar'})}, 2000)})
}
it('async和await方式测试异步代码', async () => {const data = await getData();expect(data).toEqual({foo: 'bar'})
})it('async和await方式测试异步代码', async () => {try{await getData();}catch(err) {expect(err).toMatch('hello')}
})test('the data is peanut butter', async () => {await expect(fetchData()).resolves.toBe('peanut butter');
});test('the fetch fails with an error', async () => {await expect(fetchData()).rejects.toMatch('error');
});

mock定时器

function getData(){return new Promise((resolve, reject) => {setTimeout(() => {resolve({foo: 'bar'})}, 2000)})
}// mock 定时器
jest.useFakeTimers()it('timer mock', () => {expect.assertions(1);getData().then(data => {expect(data).toEqual({foo: 'bar'})})jest.runAllTimers()
})

mock functions

function forEach(items, callback){for(let index = 0; index < items.length; index++){callback(items[index], index)}
}it('Mock Function', () => {const items = [1, 2, 3];const mockFn = jest.fn((value, index) => {return value + 1;})//设置所有的返回值都是默认值// mockFn.mockReturnValue(123)//mockFn.mockReturnValueOnce(123)//mockFn.mockReturnValueOnce(456)forEach(items, mockFn)expect(mockFn.mock.calls.length).toBe(items.length)expect(mockFn.mock.calls[0][0]).toBe(1)expect(mockFn.mock.calls[0][1]).toBe(0)
})

user.js

import axios from 'axios';export const getAllUsers = () => {return axios.get('/user.json').then(resp => resp.data)
}

mock-function

import { getAllUsers } from "./user";
import axios from "axios";jest.mock('axios');it('fetch Users', async () => {const users = [{name: 'bob'}]const resp = {data: users}axios.get.mockResolvedValue(resp)const data = await getAllUsers()expect(data).toEqual(users)
})// The mock function was called at least once
// expect(mockFunc).toHaveBeenCalled();// The mock function was called at least once with the specified args
// expect(mockFunc).toHaveBeenCalledWith(arg1, arg2);// The last call to the mock function was called with the specified args
// expect(mockFunc).toHaveBeenLastCalledWith(arg1, arg2);// All calls and the name of the mock is written as a snapshot
// expect(mockFunc).toMatchSnapshot();

mock 函数实现

./foo.js

export default function(){console.log('foo')
}
import foo from './foo'
jest.mock('./foo')foo.mockImplementations(() => {return 123;
})it('mock Implementations', () => {expect(foo()).toBe(123)
})

钩子函数

// 运行每个测试用例之前先执行它,describe作用域
beforEach(() => {console.log('beforeEach')
})// 每个测试用例执行结束后执行,describe作用域
afterEach(() => {console.log('afterEach')
})// 在所有的测试用例之前执行一次
beforAll(() => {console.log('beforAll')
})// 在所有的测试用例执行完后执行一次
afterAll(() => {console.log('afterAll')
})

DOM测试

function renderHtml(){const div = document.createElement('div');div.innerHTML = `<h1>Hello World</h1>`document.body.appendChild(div)
}it('Dom Test', () => {renderHtml()expect(document.querySelector('h1').innerHTML).toBe('Hello World')
})

Vue组件测试

import Vue from 'vue/dist/vue';function renderVueComponent(){document.body.innerHTML = `<div id="app"></div>`new Vue({template: `<div id="app"><h1>{{message}}</h1></div>`,data(){return {message: 'Hello World'}}}).$mount('#app')
}it('测试Vue组件', () => {renderVueComponent()console.log(document.body.innerHTML)expect(document.body.innerHTML).toMatch(/Hello World/);
})

快照测试


it('快照测试', () => {renderVueComponent()// 第一次运行的时候会生成快照文件字符串,下一次运行的时候会和快照文件进行比对expect(document.body.innerHTML).toMatchSnapshot()
})

更新快照的命令

npx jest --updateSnapshot

自动化测试之jest的使用相关推荐

  1. Python+Appium自动化测试之toast定位

    目录 一. 前言 二. 环境 三. toast定位准备与定位方法 1. 准备 2. 定位方法 四. 示例代码 一. 前言 在app自动化测试的过程中经常会遇到需要对toast进行定位,最常见的就是定位 ...

  2. 开启iOS自动化测试之门

    开启iOS appium自动化测试之门 Appium介绍 Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持iOS.Android及FirefoxOS平台. ...

  3. Android自动化测试之MonkeyRunner录制和回放脚本

    Android自动化测试之MonkeyRunner录制和回放脚本(十一) 分类: 自动化测试 Android自动化 2013-02-22 10:57 7346人阅读 评论(2) 收藏 举报 andro ...

  4. Appium+Python安卓自动化测试之启动APP和配置获取

    Appium+Python安卓自动化测试之启动APP和配置获取 本文章未讲述appium+python环境部署,环境部署会新开文章 一.手机连接电脑 1.USB连接电脑和手机,手机上点确认连接(最好用 ...

  5. java appium_Android应用开发之AS+Appium+Java+Win自动化测试之Appium的Java测试脚本封装(Android测试)...

    本文将带你了解Android应用开发AS+Appium+Java+Win自动化测试之Appium的Java测试脚本封装(Android测试),希望本文对大家学Android有所帮助. 一.为什么需要封 ...

  6. Android自动化测试之MonkeyRunner MonkeyDevice MonkeyImage API使用详解 脚本编写 脚本录制回放

    MonkeyRunner 系列文章 MonkeyRunner简介 MonkeyRunner 三大模块 MonkeyRunner API MonkeyDevice API MonkeyImage API ...

  7. IOS在Windows自动化测试之tidevice

    前提安装了一下工具: 1.Windows上配置了Python环境:Python 3.6+ 2.Windows上安装了iTunes IOS在Windows自动化测试之tidevice tidevice地 ...

  8. APP自动化测试之录制脚本:3.运行录制的脚本

    APP自动化测试之录制脚本:3.运行录制的脚本 1.前提 基于win10专业版64位系统+jdk1.8+python3+pycharm+android SDK+appium+unittest.运行录制 ...

  9. [免费视频教程]UI自动化测试之Jenkins配置教程

    [免费视频教程]UI自动化测试之Jenkins配置教程 image 前一段时间帮助团队搭建了UI自动化环境,这里将Jenkins环境的一些配置分享给大家. 背景: 团队下半年的目标之一是实现自动化测试 ...

最新文章

  1. java thread 无法执行_哪位大神帮我讲一下这段代码,为什么线程不能继续执行
  2. IndexedDB使用(基本函数封到Angular2的service里)
  3. RAML用户应遵循的C#与Web API代码生成模式
  4. 我们需要打造有意识的人工智能吗?
  5. SpringCloud 入门教程(十):和RabbitMQ的整合 -- 消息总线Spring Cloud Netflix Bus
  6. ES6新特性_ES6箭头函数以及声明特点---JavaScript_ECMAScript_ES6-ES11新特性工作笔记009
  7. SpringBoot单元测试@Test没有run的解决方法
  8. 牛客题库—软件测试(二)
  9. 基于PCIe的通用信号处理板PCIe-KU040-FMC
  10. Mysteel解读:2022年1-10月份马铃薯淀粉进口数据分析
  11. 在Windows上使用Ubuntu共享的打印机
  12. 程序员学c语言吗,为什么程序员要学C语言
  13. 拉姆达表达式 追加 条件判断 ExpressionFuncT, bool
  14. 看见“信任”,可信计算史上最全解析
  15. KVM安装/libvirt没有启动成功找不到/var/run/libvirt/libvirt-sock
  16. Credit Card Fraud Detection(信用卡欺诈检测相关数据集)
  17. Stable Diffsuion还能用来压缩图像?压缩率更高,清晰度超越JPEG等算法
  18. 5G/4GDTU数传终端 配电自动化无线传输
  19. 苹果官网再降价 没赶上的用户还能退差价
  20. 外卖红包cps菜谱小程序源码

热门文章

  1. MySQL总结(四)——MySQL中sql语句的执行过程
  2. QT Creater 使用
  3. 掌握缓存,不再让你蓝瘦香菇
  4. JavaScript基础测试
  5. CFF 201312-3
  6. 【解决方案】AI+ 云时代 打造智慧港口安防视频云服务平台
  7. 使用java代码实现简单的ID自增的工具类
  8. SpringBoot项目下的mvnw与mvnw.cmd
  9. 深入Java虚拟机(2)——Java的平台无关性
  10. linux bash csh 选择,关于linux:bash vs csh vs others-哪个对应用程序维护更好?