测试是确保你的 React 应用按预期工作的关键步骤。它帮助你捕捉潜在的问题,确保应用的稳定性和可靠性。
6. 测试
6.1 单元测试
单元测试用于测试应用中的单个组件或函数,确保它们按照预期工作。常用的单元测试库包括 Jest 和 React Testing Library。
-
Jest
Jest 是一个功能全面的测试框架,支持快照测试、模拟函数、测试覆盖率等。
-
安装 Jest
npm install --save-dev jest
-
基本配置
在
package.json
中添加测试脚本:"scripts": { "test": "jest" }
-
编写测试
创建一个简单的测试文件
sum.js
和sum.test.js
:// sum.js function sum(a, b) { return a + b; } module.exports = sum;
// sum.test.js const sum = require('./sum'); test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); });
-
运行测试
npm test
-
-
React Testing Library
React Testing Library 专注于测试组件的行为而不是内部实现,鼓励用户行为驱动的测试。
-
安装 React Testing Library
npm install --save-dev @testing-library/react @testing-library/jest-dom
-
基本用法
创建一个简单的组件和测试:
// Button.js import React from 'react'; function Button({ onClick, children }) { return <button onClick={onClick}>{children}</button>; } export default Button;
// Button.test.js import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import Button from './Button'; test('renders button with text and handles click', () => { const handleClick = jest.fn(); render(<Button onClick={handleClick}>Click me</Button>); const button = screen.getByText('Click me'); expect(button).toBeInTheDocument(); fireEvent.click(button); expect(handleClick).toHaveBeenCalledTimes(1); });
-
运行测试
npm test
-
6.2 集成测试
集成测试用于测试多个组件或系统的交互,以确保它们正确协作。
-
测试组件间的交互
使用 React Testing Library 进行集成测试,模拟用户操作和组件交互。
// Form.js import React, { useState } from 'react'; function Form() { const [name, setName] = useState(''); const handleSubmit = (event) => { event.preventDefault(); alert(`Submitted name: ${name}`); }; return ( <form onSubmit={handleSubmit}> <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> <button type="submit">Submit</button> </form> ); } export default Form;
// Form.test.js import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import Form from './Form'; test('submits the form with user input', () => { render(<Form />); const input = screen.getByRole('textbox'); const button = screen.getByRole('button', { name: /submit/i }); fireEvent.change(input, { target: { value: 'John Doe' } }); fireEvent.click(button); // Expectation for form submission (alert mocking can be added) });
6.3 端到端(E2E)测试
端到端测试用于测试整个应用的工作流程,从用户的角度确保所有部分正常工作。常用的 E2E 测试工具有 Cypress 和 Selenium。
-
Cypress
Cypress 是一个现代的端到端测试工具,具有简单的设置和强大的功能。
-
安装 Cypress
npm install --save-dev cypress
-
基本用法
创建一个简单的测试:
// cypress/integration/spec.js describe('My First Test', () => { it('Visits the app and checks the title', () => { cy.visit('http://localhost:3000'); cy.contains('h1', 'Welcome to React'); }); });
-
运行测试
npx cypress open
-
-
Selenium
Selenium 是一个广泛使用的 E2E 测试工具,支持多种浏览器和语言。
-
安装 Selenium
npm install --save-dev selenium-webdriver
-
基本用法
创建一个简单的测试:
const { Builder, By } = require('selenium-webdriver'); (async function example() { let driver = await new Builder().forBrowser('firefox').build(); try { await driver.get('http://localhost:3000'); let title = await driver.getTitle(); console.log(title); // 打印页面标题 } finally { await driver.quit(); } })();
-
6.4 测试覆盖率
测试覆盖率用于衡量测试的全面性,确保代码的各个部分都被测试覆盖。
-
Jest 测试覆盖率
Jest 内置了测试覆盖率的支持,只需在运行测试时加上
--coverage
参数:npm test -- --coverage
Jest 将生成覆盖率报告,帮助你查看哪些代码行没有被测试覆盖。
6.5 Mocking 和 Stubbing
Mocking 和 stubbing 是测试中的重要技术,通常用于模拟依赖项的行为,以便更好地控制测试环境。
-
Jest 的 Mocking 功能
Jest 提供了强大的 mocking 功能,可以模拟函数、模块和网络请求。
// __mocks__/axios.js const axios = { get: jest.fn(() => Promise.resolve({ data: 'mocked data' })) }; export default axios;
import axios from 'axios'; import { render, screen, waitFor } from '@testing-library/react'; import App from './App'; test('fetches and displays data', async () => { render(<App />); // Ensure the mocked data is displayed await waitFor(() => screen.getByText('mocked data')); });
以上就是测试的核心内容,包括单元测试、集成测试、端到端测试以及相关的技术和工具。测试能够确保你的应用功能正常,并且在将来进行更改时不会引入新的问题。