【2025春第5节课】jest测试

一 为什么要进行测试

前端测试是确保前端应用程序质量和稳定性的重要环节,以下从测试类型、测试框架和工具等方面介绍:

测试类型

  • 单元测试:专注于测试单个函数、组件或模块的功能。比如,对一个计算购物车总价的函数进行单元测试,确保输入不同的商品价格和数量组合时,都能正确计算出总价。
  • 集成测试:主要验证多个组件或模块之间的交互和集成是否正常。例如,测试一个电商网站中商品列表组件与购物车组件之间的交互,确保添加商品到购物车等操作能正确执行。
  • 端到端测试:模拟用户在真实环境中的操作,从应用程序的入口开始,到最终的输出结果,测试整个流程的完整性和正确性。以登录功能为例,端到端测试会模拟用户在浏览器中输入用户名和密码,点击登录按钮,直到成功登录并跳转到相应页面,检查整个过程是否正常。

测试框架和工具

  • Jest:是一个流行的 JavaScript 测试框架,具有简洁易用、自动模拟、快照测试和并行执行等特点,适用于各种前端项目,尤其是 React、Vue.js 等框架的项目。
  • Mocha:是一个灵活的测试框架,可与各种断言库和测试工具配合使用。它提供了丰富的钩子函数,方便在测试前后执行一些操作,如设置测试环境、清理资源等。
  • Chai :是一个常用的断言库,与 Mocha 等测试框架结合使用,提供了多种断言风格,如expectshouldassert,使测试代码更加易读和灵活。
  • Selenium:主要用于端到端测试,它可以控制浏览器进行自动化操作,模拟用户的各种行为,如点击按钮、输入文本、导航页面等,支持多种浏览器和编程语言。

测试流程

  1. 确定测试策略:根据项目的特点和需求,确定采用哪些测试类型和方法,以及测试的重点和范围。
  2. 编写测试用例:针对每个测试点,编写详细的测试用例,包括输入数据、预期结果和操作步骤等。
  3. 执行测试:使用相应的测试框架和工具,运行测试用例,并记录测试结果。
  4. 分析测试结果:检查测试结果是否符合预期,如果出现失败的测试用例,分析原因并定位问题。
  5. 修复问题:根据分析结果,对发现的问题进行修复,然后重新执行相关测试,直到所有测试用例都通过。
  6. 持续集成和自动化测试:将前端测试集成到持续集成流程中,每次代码提交时自动运行测试,确保代码的质量和稳定性。

二 Jest

由facebook推出的测试框架,具有快速,易于配置,社区完善等特点

安装

方式 代码
npm npm install --save-dev jest
yarn yarn add --dev jest
pnpm pnpm add --save-dev jest

简单单元测试

具体流程

1.创建文件并引入jest

bash 复制代码
mkdir jest-demo && cd 
jest-demo pnpm init
pnpm add --save-dev jest
ws .

创建math.js,math.test.js,并修改package.json

JavaScript 复制代码
//math.js
const sum = (a ,b) => a + b;
module.exports = { sum };
JavaScript 复制代码
//marh.tset.js
const { sum } = require('./math.js')

describe('Math module', () => {

  test('should return sum result when two number plus', () =>{

    //given
    const num1 = 2
    const num2 = 3

    //when
    const result = sum(num1, num2)

    //then
    expect(result).toEqual(5)

  })
})
json 复制代码
{
  "name": "jest.demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "jest": "^29.7.0"
  },
  "scripts": {
    "test": "jest"
  }
}

在控制台输入 pnpm jest

正确

错误

测试的GWT套路

GWT 3A 说明
Given Arrange 准备测试数据,beforeEach,mock模块
When Act 行动
Then Assert 断言 借助Matchers来拓展

常见断言语句

1 .toBe (value)

2 .toEqual(value) 来判断值是否符合预期(和be区别是可以判断对象之间值是否相等)

3 .toBeFalsy() 判断布尔值

4 .toHaveLength(number) 判断数组长度

单元测试的模块依赖

在实际测试中,写代码和单元测试时经常会遇到一些需要替身的对象

比如: 数据库,网络请求 ,存取文件

使用Mock用于替代整个模块

使用Stub模拟特定行为

使用Spy来监听模块行为

测试详例

sezrchName.js

JavaScript 复制代码
import * as services from './services';
const searchNames = (term) => {
   const matches = services.getName().filter((name) =>{
    return name.includes(term)
   })
//只想要三分之一的搜索结果
 return matches.length > 3 ? matches.slice(0,3) : matches;
}

const functionNotTested = (term) =>{
  return ` Hello ${term}`
}

export default searchNames;

searchNames.test.js

JavaScript 复制代码
import searchNames from "./searchNames";
import { getName } from "./services";

jest.mock("./services", () => ({
  getName:jest.fn()
}));

test('should return empty result when not search' ,() => {
    //given
    const keyword = 'Jone ';
    getName.mockImplementation(() => []);
    //when
    const result = searchNames(keyword);
    //then

    expect(result).toEqual([]);

});

test('should return target result when found search' ,() => {
    //given
    const keyword = 'Jone';
    getName.mockImplementation(() => ["Jone","Jill","Ringo","John"]);
    //when
    const result = searchNames(keyword);
    //then

    expect(result).toEqual(['Jone']);

});

test('should not return more than 3 matches' ,() => {
    //given
    const keyword = 'John';
    getName.mockImplementation(() => [
      "Jone",
      "Jill",
      "Ringo",
      "John wick 1",
      "John wick 2",
      "John wick 3",
      "John wick 4",
      "John wick 5"
    ]);
    //when
    const result = searchNames(keyword);
    //then
    expect(result).toHaveLength(3);
});


test('should handle null or undefined as input' ,() => {
   //given
    getName.mockImplementation(() => []);
    //then
    expect(searchNames(undefined)).toEqual([]);
    expect(searchNames(null)).toEqual([]);
});

test('should return search result is  case sensitive' ,() => {
    //given
  getName.mockImplementation(() => ["Jone","Jill","Ringo","John"]);
    //then
  expect(searchNames('john')).toEqual([]);
});

services.js

JavaScript 复制代码
export function getName() {
  return []
}

注意:此时会报错 Cannot use import statement outside a module

安装依赖(详情见官网

bash 复制代码
npm install --save-dev babel-jest @babel/core @babel/preset-env

并在项目根目录添加babel.config.js

JavaScript 复制代码
module.exports = {
  presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};

运行结果

查看多少代码被测试

bash 复制代码
pnpm test --coverage 

根目录下会有一个coverage文件夹里面的html是报告

前端组件化UI测试

测试框架 Test Library

创建项目

bash 复制代码
npx create-react-app my-react-app

App.js

JavaScript 复制代码
import './App.css';
import {useState} from "react";

function App() {
  const [fullName, setFullName] = useState('')
  return (
    <div className="App">
      <input type="text" placeholder={"Type your name"} value={fullName} onChange={(e) => setFullName(e.target.value)}/>
      <p>my name is <span>{fullName}</span></p>
    </div>
  );
}

export default App;

App.test.js

JavaScript 复制代码
import { render, screen } from '@testing-library/react';
import App from './App';
import userEvent from "@testing-library/user-event";

test("should show full name when type" , () =>{
  //given
  const name = "Jone"
  //when
  render(<App />)
  userEvent.type(screen.queryByPlaceholderText("Type your name"),name)
  //then
  expect(screen.getByText(name)).toBeInTheDocument()
})

测试异步代码

JavaScript 复制代码
navigator.geolocation.getCurrentPosition() //chrome API 异步获得当前位置

即代码有延迟,结果延迟返回

推荐使用async和await的语法糖

有三个地方可以进行测试 分别是

1.在Form.js提交前将app.js进行mock

2.也可以在API发送axios方法时进行

3.在浏览器的network中直接进行mock ajax请求

差不多就到这里了,其他的内容比如API Mock测试,前端数据管理测试(比如Redux),UI测试....就不一一讲解了,jest作为了解即可,有兴趣可以自己深入了解,有多余的时间可以去学一下Mock

Jest官方文档
前端自动化测试(这是老学长的课件)
推荐的jest相关文章

相关推荐
学习2年半几秒前
汇丰eee2
前端·spring
代码续发2 分钟前
Vue进行前端开发流程
前端·vue.js
zpjing~.~5 分钟前
CSS &符号
前端·css
冴羽41 分钟前
SvelteKit 最新中文文档教程(19)—— 最佳实践之身份认证
前端·javascript·svelte
拉不动的猪43 分钟前
ES2024 新增的数组方法groupBy
前端·javascript·面试
huangkaihao1 小时前
单元测试 —— 用Vitest解锁前端可靠性
前端
archko1 小时前
telophoto源码查看记录
java·服务器·前端
倒霉男孩1 小时前
HTML5元素
前端·html·html5
柯南二号2 小时前
CSS 学习提升网站或者项目
前端·css
tryCbest2 小时前
Vue2-实现elementUI的select全选功能
前端·javascript·elementui