測試 React 應用
測試 React 應用
測試是一個確保 React 應用穩定性、可維護性的重要步驟。常見的 React 測試方法包括單元測試(Unit Testing)、組件測試(Component Testing)、端到端測試(End-to-End Testing)等。本文將介紹幾種常用的工具和技術來測試 React 應用。
1. 測試工具概覽
- Jest:一個流行的 JavaScript 測試框架,內建於 Create React App 中,專為 React 應用設計,提供快速的單元測試支持。
- React Testing Library:專注於測試 React 組件的行為,而非實現細節。
- Cypress:一個用於端到端測試的框架,適合模擬用戶操作,測試整個應用流程。
2. 使用 Jest 和 React Testing Library 測試 React 組件
2.1 安裝 Jest 和 React Testing Library
在使用 Create React App 創建的應用中,Jest 已經默認安裝。如果你使用的是自定義設置,你需要安裝它們:
1
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
2.2 基本測試
讓我們從一個簡單的 React 組件開始,並編寫測試:
1
2
3
4
5
6
7
8
// Button.js
import React from 'react';
function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>;
}
export default Button;
編寫一個測試來驗證按鈕是否被渲染:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Button.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import Button from './Button';
test('渲染按鈕', () => {
render(<Button>點擊我</Button>);
const buttonElement = screen.getByText(/點擊我/i);
expect(buttonElement).toBeInTheDocument();
});
test('點擊按鈕觸發事件', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>點擊我</Button>);
const buttonElement = screen.getByText(/點擊我/i);
fireEvent.click(buttonElement);
expect(handleClick).toHaveBeenCalledTimes(1);
});
render
:渲染組件。screen.getByText
:從渲染的 DOM 中查找特定文本內容的元素。fireEvent.click
:模擬按鈕點擊事件。expect
:斷言函數,檢查條件是否成立。
3. 測試表單和用戶輸入
假設我們有一個表單組件,可以通過 onSubmit
將輸入的值提交:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Form.js
import React, { useState } from 'react';
function Form({ onSubmit }) {
const [value, setValue] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(value);
};
return (
<form onSubmit={handleSubmit}>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="輸入內容"
/>
<button type="submit">提交</button>
</form>
);
}
export default Form;
測試輸入和提交行為:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Form.test.js
import { render, screen, fireEvent } from '@testing-library/react';
import Form from './Form';
test('提交表單時調用 onSubmit 並傳遞輸入值', () => {
const handleSubmit = jest.fn();
render(<Form onSubmit={handleSubmit} />);
const inputElement = screen.getByPlaceholderText(/輸入內容/i);
const buttonElement = screen.getByText(/提交/i);
fireEvent.change(inputElement, { target: { value: '測試內容' } });
fireEvent.click(buttonElement);
expect(handleSubmit).toHaveBeenCalledTimes(1);
expect(handleSubmit).toHaveBeenCalledWith('測試內容');
});
這個測試模擬用戶在表單中輸入值並提交,並檢查 onSubmit
回調是否被正確調用。
4. Snapshot 測試
Snapshot 測試用於捕獲組件的渲染輸出,並與之前的輸出進行比較,檢查是否有意外的更改。
4.1 創建 Snapshot 測試
1
2
3
4
5
6
7
8
// Button.test.js
import { render } from '@testing-library/react';
import Button from './Button';
test('創建按鈕的 snapshot', () => {
const { asFragment } = render(<Button>點擊我</Button>);
expect(asFragment()).toMatchSnapshot();
});
當你運行測試時,Jest 會生成一個快照文件並將其與未來的渲染進行對比。如果渲染結果變更,測試會失敗,提示你檢查變更是否預期。
5. 使用 Cypress 進行端到端測試
5.1 安裝 Cypress
1
npm install cypress --save-dev
5.2 編寫端到端測試
假設我們有一個待測試的登錄頁面,端到端測試會模擬用戶輸入帳號密碼,點擊登錄按鈕,並驗證登錄成功。
1
2
3
4
5
6
7
8
9
10
11
12
// cypress/integration/login.spec.js
describe('登錄測試', () => {
it('成功登錄', () => {
cy.visit('http://localhost:3000/login'); // 打開應用
cy.get('input[name="username"]').type('user123'); // 輸入用戶名
cy.get('input[name="password"]').type('password123'); // 輸入密碼
cy.get('button[type="submit"]').click(); // 點擊登錄按鈕
cy.url().should('include', '/dashboard'); // 驗證是否成功跳轉
});
});
這段測試將模擬一個完整的登錄過程,並檢查頁面是否正確跳轉到儀表板。
6. 總結
- Jest:用於編寫單元測試和 Snapshot 測試。
- React Testing Library:專注於組件的行為測試,適合測試 UI 和用戶交互。
- Cypress:提供端到端測試,模擬用戶實際操作。
通過這些工具,開發者可以確保 React 應用的功能穩定,並降低引入 bug 的風險。
本文章以 CC BY 4.0 授權