「今天來考試吧!」艾草緩緩開口。
「誒 !!? 考試不是要提前說嗎?還是可以翻書考?」
「你要翻什麼書?」艾草心裡默默唸叨:我可不記得我有勤勞到出教材。
「口頭禪而已,沒事啦!」
「好啦,不用太緊張就是一個小練習而已。只是複習之前有講解過的部分而已啦 ~~」
我害怕的想著:怎麼感覺像從小到大老師口中說的這次考試範圍書裡都有,但考出來都不懂呢 …
今天要來做一個測試的小練習,是撰寫常見的情境,在註冊時常常會有需要打勾確認同意網站相關規定後,註冊按鈕才會從 disabled 狀態切換成可點擊。
正好可以透過昨天有學習到的 Jest DOM 來協助判斷。
首先,先撰寫一個元件 Form , Form 會有 checkbox 跟 button ,且 Form 會使用 React hook useState 來管理是否點擊的狀態,當 checkbox 點擊時我們會透過 setIsChecked 將 checkbox 轉為 true 或 false ,並使用此狀態綁定 button 的 disabled 屬性。
import { useState } from "react";
const Form = () => {
const [isChecked, setIsChecked] = useState(false);
return (
<form>
<label htmlFor="agreeRules">
<input
type="checkbox"
id="agreeRules"
onChange={(e) => setIsChecked(e.target.checked)}
/>
確認同意網站規則嗎?
</label>
<button type="button" disabled={!isChecked}>
送出
</button>
</form>
);
};
export default Form;
接下來在與 Form 同一層級的地方撰寫 Form.test.js 檔案:
並引入 jest 及 React Testing Library 及 Jest Dom ,最後也別忘記引入 Form 元件:
import "jest";
import React from 'react';
import { render, fireEvent, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import Form from "./test";
接下來透過 Jest 的 describe
包覆要測試的內容:
describe('Click the checkbox to change the disabled property of the button', () => {
})
在測試裡,可以先撰寫一開始會顯示的情形:
describe('Click the checkbox to change the disabled property of the button', () => {
test('Unable to press the button at first' ,() => {
render(<Form />);
expect(screen.getByRole('button')).toBeDisabled();
})
})
接下來透過 React Testing Library 的 fireEvent 模擬點擊行為 !
fireEvent 可以幫忙觸發事件,依據官網的使用方式如下:
fireEvent[eventName](node: HTMLElement, eventProperties: Object)
[eventName] 的地方指的是 click 、 change 等操作事件的名稱,而可帶入的兩個參數分別為:
測試事件為 click 所以只需要給定第一個參數即可,並透過 getByRole 選定 checkbox 角色,最後透過 .not.toBeDisabled()
進行斷言:
describe('Click the checkbox to change the disabled property of the button', () => {
test('Unable to press the button at first' ,() => {
render(<Form />);
expect(screen.getByRole('button')).toBeDisabled();
})
test('The button can be turned on when the checkbox is checked' ,() => {
render(<Form />);
fireEvent.click(screen.getByRole('checkbox'));
expect(screen.getByRole('button')).not.toBeDisabled();
})
})
如果想使用 toBeEnabled()
也是可以的!
test('The button can be turned on when the checkbox is checked' ,() => {
render(<Form />);
fireEvent.click(screen.getByRole('checkbox'));
expect(screen.getByRole('button')).toBeEnabled();
})
最後,也可以測試點擊兩次後按鈕是否會恢復禁用:
test('Clicking the checkbox twice disables the button',() => {
render(<Form />);
fireEvent.click(screen.getByRole('checkbox'));
expect(screen.getByRole('button')).not.toBeDisabled();
fireEvent.click(screen.getByRole('checkbox'));
expect(screen.getByRole('button')).toBeDisabled();
})
測試點擊一次及點擊兩次的情況也可以整合成同一個測試即可,這次為了練習先將他們分開撰寫,最後就完成這次測試練習了!
import "jest";
import React from 'react';
import { render, fireEvent, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import Form from "./test";
describe('Click the checkbox to change the disabled property of the button', () => {
test('Unable to press the button at first' ,() => {
render(<Form />);
expect(screen.getByRole('button')).toBeDisabled();
})
test('The button can be turned on when the checkbox is checked' ,() => {
render(<Form />);
fireEvent.click(screen.getByRole('checkbox'));
expect(screen.getByRole('button')).toBeEnabled();
})
test('Clicking the checkbox twice disables the button',() => {
render(<Form />);
fireEvent.click(screen.getByRole('checkbox'));
expect(screen.getByRole('button')).not.toBeDisabled();
fireEvent.click(screen.getByRole('checkbox'));
expect(screen.getByRole('button')).toBeDisabled();
})
})
下一篇會提到另一個可以替代 fireEvent 的函式庫 @testing-library/user-event !
Testing React with Jest and React Testing Library (RTL)
https://ithelp.ithome.com.tw/articles/10248517