Jest 自动化测试框架 笔记
Jest 自动化测试框架 笔记
- Jest 前端自动化测试框架基础入门
- 自动化测试背景及原理
- 前端自动化测试框架Jest
- jest测框架特点:
- 使用Jest 修改自动化测试样例
- 安装 node 环境
- 创建执行的测试文件
- 执行测试用例
- 使用jest测试的疑问
- Jest 的简单配置
- Jest 中的匹配器
- jest 命令行工具的使用
- 异步代码的测试方法
- Jest 中的钩子函数
- jest 中常用的函数
- jest 钩子函数的简单使用
- Jest 中的Mock
- Jest 难点进阶
- snapshot 快照测试
- 使用外部存储式 snapshot
- 使用行内式 snapshot
- mock 深入学习
- mock timers
- ES6 中类的测试
- React 中的 TDD 与单元测试
- 什么是TDD
- TDD 的开发流程(Red-Green Develepment)
- TDD
- React 环境配置 Jest
- 创建 React 项目
- TDD 与 BDD 对比
Jest 前端自动化测试框架基础入门
自动化测试背景及原理
- 目录结构
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>math.js</title></head>
<body><h1>测试math.js 内的方法</h1><script src="./math.js"></script>
</body>
</html>
function add(a, b) {return a + b;
}function minus(a, b) {return a - b;
}function multi(a, b) {return a * b;
}
math.test.js
function expect(result) {return {toBe: function(actual) {if(result !== actual) {throw new Error(`预期值和实际值不相等,预期${actual} 结果却是${result}`);}}}
}function test(desc, fn) {try {fn();console.log(`${desc} 通过测试`)}catch(e) {console.log(`${desc} 没有通过测试 ${e}`)}
}test('测试加法 3 + 7', () => {expect(add(3, 7)).toBe(10);
});test('测试减法 3 - 3', () => {expect(minus(3, 3)).toBe(0);
});test('测试乘法 3 * 3', () => {expect(multi(3, 3)).toBe(9);
});
前端自动化测试框架Jest
- 性能
- 尽可能的功能
- 易用性
jest测框架特点:
- 速度快
- API 简单
jest的API很简单,API数量少,简单的学习就可以使用 - 易配置
在项目中安装jest,通过jest配置文件简单的配置就可以使用jest了 - 隔离性好
jest中会有很多测试文件,但每个测试文件去执行的时候,它的执行环境都是隔离的就会避免不同的测试文件执行的时候之间会产生互相影响。 - 监控模式
使用监控模式可以使得我们更加灵活的使用测试用例。 - IDE整合
jest可以很方便的与ide整合,也就是在编辑器中做前端自动化测试也会变得很简单 - Snapshot
- 多项目并行
- 测试覆盖率
- Mock丰富
使用Jest 修改自动化测试样例
安装 node 环境
https://nodejs.org/download/
- 安装 jest
执行命令
npm init -y
npm install jest@24.8.0 -D
创建执行的测试文件
- 文件目录
- 修改package.json 文件
当运行 npm run test 命令的时候会执行 jest 的命令,jest 命令会找 这个目录下以 test.js 结尾的文件然后去运行这些文件。
"scripts": {"test": "jest"},
math.js
function add(a, b) {return a + b;
}function minus(a, b) {return a - b;
}function multi(a, b) {return a * b;
}// 导出add, minus, multi 方法
module.exports = {add,minus,multi
}
math.test.js
function add(a, b) {return a + b;
}function minus(a, b) {return a - b;
}function multi(a, b) {return a * b;
}// 导出add, minus, multi 方法
// 引入 try 方法是关闭掉浏览器运行时检测没有module方法
try {module.exports = {add,minus,multi}
}catch(e) {}
执行测试用例
- 执行命令 npm run test
- 执行结果
使用jest测试的疑问
jest 这个框架实际上在前端自动化测试中帮助我们完成的实际上两类的内容 单元测试 和 集成测试 。
所谓单元测试就是程序中的一个模块也就是最小单元,而集成测试可以理解为多个模块测试。
Jest 的简单配置
创建 jest.config.js 文件
- 执行命名:
npx jest --init
- jest.config.js 文件中的配置说明
collectCoverage: true, // 启用代码覆盖率
coverageDirectory: null, // 测试覆盖率报告生成的文件夹名
安装bable
npm install -D npm install @babel/core@7.4.5 @babel/preset-env@7.4.5 -D
创建 .babelrc 文件
// .babelrc
{"presets": [["@babel/preset-env", {"targets": {"node": "current"}}]]
}// babel 执行过程
// npm run jest
// jest (babel-jest)
// babel-core
// 取 。babelrc 配置
// 在运行之前,结合babel,先把你的代码做一次转化
// 运行转化的过的测试用例代码
Jest 中的匹配器
监听所有test 文件的变化 实现自动执行
Jest 匹配器: https://jestjs.io/docs/using-matchers
// --------------- 和真假相关的匹配器---------------------
// test('测试 10 与 10 向匹配', () => {// // toBe 匹配器
// const a = {one: 1}
// expect(a).toBe({one: 1});
// });// test('测试 对象内容相等', () => {// // toEqual 匹配器 值匹配内容
// const a = {one: 1}
// expect(a).toEqual({one: 1});
// });// test('测试 toBeNull 匹配器', () => {// // toBeNull 匹配器 值匹配内容是否为空
// const a = null;
// expect(a).toBeNull();
// });// test('测试 undefined 匹配器', () => {// // toBeUndefined 匹配器 值匹配内容是否未定义
// const a = undefined;
// expect(a).toBeUndefined();
// });// test('测试 toBeDefined 匹配器', () => {// // toBeDefined 匹配器 值匹配内容是否已定义
// const a = 1;
// expect(a).toBeDefined();
// });// test('测试 toBeTrythy 匹配器', () => {// // toBeTruthy 匹配器 值匹配内容是否为真
// const a = 1;
// expect(a).toBeTruthy();
// });// test('测试 toBeFalsy 匹配器', () => {// // toBeFalsy 匹配器 值匹配内容是否为假
// const a = false;
// expect(a).toBeFalsy();
// });// test('测试 not 匹配器', () => {// // not 匹配器 值匹配内容取反
// const a = true;
// expect(a).not.toBeFalsy();
// });// --------------- 和数字相关的匹配器---------------------
// test('测试 toBeGreaterThan 匹配器', () => {// // toBeGreaterThan 匹配器 值匹配内容是否大于预期
// const a = 10;
// expect(a).toBeGreaterThan(5);
// });// test('测试 toBeLessThan 匹配器', () => {// // toBeLessThan 匹配器 值匹配内容是否小于预期
// const a = 10;
// expect(a).toBeLessThan(11);
// });// test('测试 toBeGreaterThanOrEqual 匹配器', () => {// // toBeGreaterThanOrEqual 匹配器 值匹配内容是否大于等于预期
// // toBeLessThanOrEqusl 匹配器 值匹配内容是否小于等于预期
// const a = 10;
// expect(a).toBeGreaterThan(10);
// });// test('测试 toBeCloseTo 匹配器', () => {// // toBeCloseTo 匹配器 值匹配内容是小数时,可以解决 浮点精度问题
// const firstNumber = 0.1;
// const secondNumber = 0.2;
// // expect(firstNumber + secondNumber).toEqual(0.3);
// expect(firstNumber + secondNumber).toBeCloseTo(0.3);
// });// --------------- 和字符串相关的匹配器---------------------
// test('测试 toMatch 匹配器', () => {// // toBeLessThan 匹配器 值匹配内容是否包含预期值
// const str = "https://www.baidu.com";
// expect(str).toMatch("baidu");
// });// --------------- 和数组串相关的匹配器---------------------
// test('测试 toContain 匹配器', () => {// // toContain 匹配器 值匹配内容是否包含预期值
// const arr = ['xiaoming', 'xiaolong', 'xiaowen']
// expect(arr).toContain("xiaoming")
// });// --------------- 和异常相关的匹配器---------------------
// 创建一个抛出异常的函数
const throwNewErrorFunc = () => {throw new Error("this is a new error")
}
test('测试 toThrow 匹配器', () => {// toThrow 匹配器 值匹配内容是否包含预异常expect(throwNewErrorFunc).toThrow()
});
jest 命令行工具的使用
1.在VSCode 中使用Ctrl + Shif + P 命令
2.在、然后搜索 install code command 安装
3. 可以在dos 窗口使用 code 命令 打开 vscode
如果在 package.json 中 配置了
"test": "jest --watchAll"
那么在执行 npm run test 命令后会在 jest 命令行中提示一下内容:
Watch Usage› Press f to run only failed tests.› Press o to only run tests related to changed files.› Press p to filter by a filename regex pattern.› Press t to filter by a test name regex pattern.› Press q to quit watch mode.› Press Enter to trigger a test run.
命令解读:
- Press f to run only failed tests.
按下 f 指挥执行失败的测试用例 - Press o to only run tests related to changed files.
按o只运行与已更改文件相关的测试;- package.json 使用的是 : “test”: “jest --wathAll” 就可以使用 o 命令
这个命令会记录你改了哪些文件,如果没有引入一些工具包去记录文件的改变时就会报错;
所以想使用 o 命令,那么就需要使用git 工具来管理我们的代码,使用git来管理我们的代码就可以记录代码的变化,那么就可以比对文件的更变,否则 jest 就无法确定代码改变的地方,实际上 jest -o 命令是跟 git 之间有一个绑定关系的。 - package.json 使用的是 : “test”: “jest --wacth” 那么 jest 的 o 命令就不可以使用,因为 jest 会默认进入 o 命令 模式。
- package.json 使用的是 : “test”: “jest --wathAll” 就可以使用 o 命令
- Press p to filter by a filename regex pattern.
按 p 通过文件名正则表达式模式进行过滤。 - Press t to filter by a test name regex pattern.
按 t 按测试名称正则表达式模式进行筛选。
异步代码的测试方法
// fetchData.js
import axios from 'axios';// export const fetchData = (fn) => {// axios.get("http://www.dell-lee.com/react/api/demo.json").then((response) => {// fn(response.data)
// })
// }export const fetchData = () => {return axios.get("http://www.dell-lee.com/react/api/demo.json");
}
// fetchData.test.js
import { fetchData } from "./fetchData";// test('fetchData 返回结果为 { success: true }', async() => {// const response = await fetchData();
// expect(response).toEqual({// success: true
// })
// })test("fetchData 返回结果为 404", async() => {expect.assertions(1); // 要求下面的代码必须执行一个 expext 方法try {await fetchData();}catch(e) {expect(e.toString()).toEqual("Not Found");}
});
Jest 中的钩子函数
Jest中的钩子函数就是指在 jest 执行过程中的某一些具体时刻会被 jest 自动调用l的一些函数。
关于钩子函数的作用域:
- beforeAll、afterAll 会对同级或子集中的 describe 函数内的 describe 函数进行挂钩操作。
- beforeEach、afterEach 会对同级或子集中的 describe 函数内的所有 test函数进行挂钩操作。
说明:挂钩操作就是指该函数在执行前或执行后要执行的函数。
jest 中常用的函数
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)beforeAll(fn, timeout)
afterAll(fn, timeout)
beforEach(fn, timeout)
afterEach(fn, timeout)test(name, fn, timeout)
test.each(table)(name, fn, timeout)
test.skip();
test.skip.each(table)(name, fn)
test.only(table)(name, fn)
test.only.each(table)(name, fn)
test.todo(name)
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)
jest 钩子函数的简单使用
// Counter.test.js
export default class Counter {constructor() {this.number = 0;}addOne() {this.number +=1;}minusOne() {this.number -= 1;}
}
// Counter.js
import Counter from "./Counter";let counter;describe("钩子函数测试", () => { // 使用 describe 可以很好的对测试用例做一个分组beforeAll(() => {console.log("最近一层的 describe 开始执行时会执行到 beforeAll")counter = new Counter();})afterAll(() => {console.log("最近一层的describe 执行结束时会执行到 afterAll ")})beforeEach(() => {console.log("在同级以及子集中 describe 函数中的每个 test 函数前会执行 beforeEach ")})afterEach(() => {console.log("在同级以及子集中 describe 函数中的每个 test 函数执行结束后会执行 afterEach ")})test("测试 Counter 中的 addOne 方法", () =>{counter.addOne();expect(counter.number).toBe(1);});test("测试 Counter 中的 addOne 方法", () =>{counter.minusOne();expect(counter.number).toBe(0);});});
Jest 中的Mock
jest 中的 mock 使用场景:
- 测试函数是否被执行或函数执行的次数,mock函数可以帮助我们捕获函数的调用
- 可以让我们自由的设置返回结果
- 改变内部函数的实现,
// demo.js
export const runCallback = (callback) =>{callback();
}export const createObject = (classItem) => {new classItem();
}export const getData = () => {return axios.get('/').then(res => res.data);
}
// demo.test.js
import { runCallback, createObject } from "./demo";test("测试 runCallback 函数", () => {const func = jest.fn(() => {return "456"}); // mock 函数可以捕获函数的调用 func.mockReturnValueOnce('xiao') // 让func函数模拟一次返回值为 "xiao"func.mockReturnValueOnce('ming')// func.mockReturnValue("hihi"); // 设置 funcc 模拟函数的返回值为 "hihi"runCallback(func);runCallback(func);runCallback(func);expect(func).toBeCalled(); // 判断 func 函数是否被执行过console.log(func.mock)// expect(runCallback(func)).toBe("hello")
})test("测试 createObject", () => {const func = jest.fn();createObject(func);console.log(func.mock)
})test.only('测试 getDate', async () => {axios.get.mockResolvedValue({data: 'hello'}) // 使用jest 模拟 get方法的返回数据// axios.get.mockResolvedValueOnce({data: 'hello'}) // 模拟一次await getData().then((data) => {expect(data).toBe('hello');});
});/*mock 属性 {calls: [ [], [], [] ], // calls 表示函数被调用的次数以及调用时传入的参数instances: [ undefined, undefined, undefined ], // instances 表示被调用的次数以及每次被调用 this 的执行invocationCallOrder: [ 1, 2, 3 ], // invocationCallOrder 指的是这个函数有可能被多次传入同一个方法或不同的方法中,那么传入的执行顺序就别被记录到invocationCallOrder中results: [ // result 表示被被调用的次数以及每次执行返回的结果{ type: 'return', value: 'xiao' }, // { type: 'return', value: 'ming' },{ type: 'return', value: '456' }]}console.log demo.test.js:21{calls: [ [] ],instances: [ mockConstructor {} ],invocationCallOrder: [ 4 ],results: [ { type: 'return', value: undefined } ]}
*/
Jest 难点进阶
snapshot 快照测试
使用外部存储式 snapshot
snapshot很适合测试 配置文件的测试用例。
实际上在 Vue和 Rect 组件的UI展示使用 snapshot 进行组件的单元测试也会很好用。
实战:
// demo.js
export const generateConfig = () => {return {server: "http://localhost",port: 8000,domain: "localhost",time: new Date()}
}export const generatAnotherConfig = () => {return {server: "http://localhost",port: 8000,domain: "localhost",time: new Date()}
}
// demo.test.js
import { generatAnotherConfig, generateConfig } from "./demo";test("测试 gennerateConfig 函数", () => {expect(generateConfig()).toMatchSnapshot({time: expect.any(Date)});
});test("测试 generateAnthoerConfig 函数", () => {expect(generatAnotherConfig()).toMatchSnapshot({time: expect.any(Date)});
});
说明:
- 使用 snapshot 中的 toMatchSnapshot 函数时 会在 根目录下创建一个
__snapshots__
文件 用来存放 toMathSnapshot 函数的快照文件。 - 当快照文件更变时,执行测试用例会运行失败 可以时 u 命令更新快照文件
snapshots failed from 1 test suite. Inspect your code changes or pressu
to update them. - 如果多个测试用例的快照都发生更变,又不想更新全部配置文件的快照时就可以使用 i 命令 来逐个更新。
Press i to update failing snapshots interactively.
使用行内式 snapshot
安装 prettier@1.18.2
npm install prettier@1.18.2 --save
测试文件:
import { generatAnotherConfig, generateConfig } from "./demo";test("测试 generateAnthoerConfig 函数", () => {expect(generatAnotherConfig()).toMatchInlineSnapshot({time: expect.any(Date)},// 下面的的数据格式就是由 toMatchInlineSnapshot() 函数自动创建的行内式测试快照`Object {"domain": "localhost","port": 8000,"server": "http://localhost","time": Any<Date>,}`);
});
mock 深入学习
mock timers
ES6 中类的测试
之所以对函数做 mock,是因为我们函数的一些执行是能够被追述的,那么时候时候调用了它,调用了几次,每次调用的参数是什么,只有在 jest 中 jest.fn 这样的方式对函数做了包装之后这个函数才是可追述的。有时在 jest 测试中需要发一些 axios 请求,但实际上前端测试之中我们并不是很关注后端返回的接口成功还是失败或数据请求格式对与不对,我们更多的精力是投入到当我们拿到正确或失败的数据后,后面的逻辑或前端的逻辑是否能够正确的运行,所以一般情况下我们对这些数据请求的内容进行 mock。
React 中的 TDD 与单元测试
什么是TDD
Test Driven Development (简称TDD) 测试驱动开发
TDD 的开发流程(Red-Green Develepment)
- 编写测试用例
- 运行测试,测试用例无法通过测试。
- 编写代码,使测试用例通过测试。
- 优化代码,完成开发。
- 重复上述步骤。
TDD
- 长期减少回归 bug。
- 代码质量更好(组织,可维护性)。
- 测试覆盖率高。
- 错误测试代码不容易出现。
React 环境配置 Jest
创建 React 项目
- 安装 react 脚手架工具
npm install create-react-app -g
- 使用 react 脚手架工具创建 jest-react 项目
creact-react-app jest-react
TDD 与 BDD 对比
TDD | BDD |
---|---|
先写测试在写代码 | 先写代码再写测试 |
一般结合单元测试使用,是白盒测试 | 一般结合继承测试,是黑盒测试 |
测试重点在代码 | 测试重点在 UI (DOM) |
安全感低 | 安全感高 |
速度快 | 速度慢 |
Jest 自动化测试框架 笔记相关推荐
- 前端自动化测试框架 Jest 极简教程
前端自动化测试框架 Jest 极简教程 Delightful JavaScript Testing. https://jestjs.io Jest是由Facebook发布的开源的.基于Jasmine的 ...
- 前端自动化测试框架Jest介绍和使用
在实际项目的自动化测试过程中,如果只有这两个方法,很显然,是远远不够的,这时候,就需要我们对之前的方法进行扩充,同时还有很多自动化的机制需要集成进去.这时候 Jest 闪亮登场! Jest 框架介绍 ...
- 【学习笔记】HttpRunner自动化测试框架入门
HttpRunner自动化测试框架入门 文章目录 设计思想和理念 一.Httprunner环境搭建 可以用相关命令**直接生成对应的项目文件夹** 二.Httprunner五个命令 三.一分钟生成用例 ...
- 学习笔记——自动化测试框架的构成
自动化测试框架的构成 一.基础模块 1.底层核心驱动 2.可复用组件 3.对象库 4.配置文件 二.管理模块 1.测试数据管理 2.测试文件管理 三.运行模块 四.统计模块 常用的测试框架 1.模块化 ...
- Robot Framework 自动化测试框架核心指南-初识Robot Framework(学习笔记2)
初识Robot Framework 1.1如何创建一个自动化测试项目 1.1.2 创建测试套件 1.1.3 创建测试用例 1.2 Robot Framework基础关键字 1.2.1 如何搜索Robo ...
- 软件测试笔记_15_Appium自动化测试框架、操作API
移动端Appium等价于web端selenium 一.Appium介绍 Appium 移动端自动化测试框架 用于测试原生应用(纯java).移动端网页应用(html css)和混合型应用(java h ...
- python appium自动化测试框架unittest_Appium基于Python unittest自动化测试 自动化测试框架 -- PO并生成html测试报告...
基于python单元测试框架unittest完成appium自动化测试,生成基于html可视化测试报告 代码示例: #利用unittest并生成测试报告 class Appium_test(unitt ...
- python接口自动化测试框架实战从设计到开发_Python接口自动化测试框架实战 从设计到开发...
第1章 课程介绍(不要错过) 本章主要讲解课程的详细安排.课程学习要求.课程面向用户等,让大家很直观的对课程有整体认知! 第2章 接口测试工具Fiddler的运用 本章重点讲解如何抓app\web的h ...
- 什么是自动化测试框架?这就是自动化测试框架。
无论是在自动化测试实践,还是日常交流中,经常听到一个词:框架.之前学习自动化测试的过程中,一直对"框架"这个词知其然不知其所以然. 最近看了很多自动化相关的资料,加上自己的一些实践 ...
- 如何搭建自动化测试框架
序 今天先聊聊如何搭建自动化测试框架,主要会聊聊一些思路上的东西,从一个最简单的demo到把一个框架该有的组件都搭建好.本文主要以web自动化为例子,使用的语言是js. 一.什么是自动化测试框架 在了 ...
最新文章
- 统计学习基础:数据挖掘、推理和预测_数据挖掘——智能财务进阶之梯(含视频、PPT)...
- 粤东农批项目座谈会 农业大健康·李喜贵:功能性农业差异化加工
- React-navigation之StackNavigator
- 深入学习jQuery选择器系列第四篇——过滤选择器之属性选择器
- Python 简单入门学习笔记
- win10+tensorflow import cv2 bug解决
- TypeError: HashUpdate fail
- php防止跨域提交,PHP防止跨域提交表单的简单示例
- presto .vs impala .vs HAWQ query engine
- java 值班管理_​运维告警的值班管理
- Python类的继承
- 计算机组装拆卸 心得,学习组装电脑的心得体会怎么写?
- 【路由协议】和【应用协议】
- 一枚中级网络工程师的工作日常,能引起多少同行的共鸣啊。
- php获取文件夹下所有文件名(php遍历目录)
- 计算机科学与技术专业考数媒,数字媒体技术研究生院校排名
- 机器人原理及应用 东南大学 王兴松 64讲和48讲 课件
- 根文件系统制作 -- Kernel panic - not syncing
- OCR-Tesseract系列学习——Tesseract for Linux下载与安装
- RT-Thread GD32F4xx enc28j60 + Lwip使用记录
热门文章
- 预充电电路工作原理_预充电阻和预充继电器的工作原理和功用是什么?
- 极客DIY开源方案分享——智能家居你也可以做,何不DIY个自动窗帘升降控制系统?(纪念我的职业生涯处女作、曾获校赛一等奖作品、上古汇编语言编程)
- 串口助手是怎么做出来的 :第一节,串口助手界面的实现及串口通信原理的介绍
- 发送网页内容到onenote_将网页中的信息快速添加到OneNote笔记本的方法
- 为你的域名添加子域名(二级域名)并绑定网站
- Java冒泡排序实现
- java发卡系统_基于java的网络收费验证系统和在线付费发卡
- 股票 - - 常用指标【下】
- 搜狗站长平台 不用审核强制提交sitemap的方法
- 网站版面布局设计原理