什么是測試用例
字面理解來說石景,就是測試一個東西更舞,對于我們前端開發(fā)來說就是測試前端功能畦幢,前端主要分為 html css javascript,一般來說是測試 js疏哗,現(xiàn)在主要通過模塊的形式來開發(fā),對于 react 來說禾怠,html 也屬于 js 的一部分返奉,css 怎么測試,或許你需要判斷渲染的組件吗氏,有沒有className芽偏。
測試用例的作用是什么
舉個例子來說明測試用例的簡單場景
對于剛接觸測試用例的來說,會不會覺得很浪費時間弦讽,我的功能都可以正常運(yùn)行為什么要沒事干去寫測試用例污尉,干點其他的不好嗎膀哲。其實這樣想是正常的,但是到后面開發(fā)某些工具方法或者通用組件的時候就會體現(xiàn)測試用例的重要性了被碗。
例:(環(huán)境搭建后面會提某宪,這里需要先搞定測試用例是什么)
現(xiàn)在有 sum 方法,就是一個簡單的計算锐朴,App 組件兴喂,現(xiàn)在功能正常運(yùn)行,渲染為 3 焚志,預(yù)期很符合我們想要的衣迷。這個測試用例就是用來保證這個函數(shù)的輸入輸出是符合預(yù)期的。
export default function sum(a, b) {
return a + b;
}
function App() {
return (
<div>
{sum(1, 2)}
</div>
);
}
測試用例代碼酱酬,先簡單的看一下大概語法,
// describe 和 test 先不看
describe('測試sum方法', () => {
test('測試 1 + 2 = 3', () => {
// expect 來源于 jest 語法壶谒,expect 就是拿到一個值,這里可以是函數(shù)調(diào)用膳沽,也可以是常量
// toBe() 是判斷方式的一種方式汗菜,
// 按照代碼來理解就是 sum(1, 2) === 3
// jest文檔 https://jestjs.io/docs/en/expect
expect(sum(1, 2)).toBe(3);
});
});
測試用例運(yùn)行結(jié)果
但是到后面功能開發(fā)的時候,可能會使用后臺返回的數(shù)據(jù)來進(jìn)行渲染贵少,如果現(xiàn)在的數(shù)據(jù)是這樣
const testData = {
a: '1',
b: '2'
};
function App() {
return (
<div>
{sum(testData.a, testData.b)}
</div>
);
}
后臺給的數(shù)據(jù)是字符串呵俏,我們確直接使用了,現(xiàn)在得到 '12' 滔灶,肯定是不符合預(yù)期的普碎,有人說可以用 ts 來,雖然 ts 確實可以避免這個問題录平,但是大家知道代碼量也會上升麻车,這里不考慮 ts 在的情況下。
這個時候大家會想到使用Number等轉(zhuǎn)換為數(shù)字的方法來保證功能的正常運(yùn)行斗这,所以現(xiàn)在我們需要來對 sum 進(jìn)行改造动猬,大家要知道改造就有可能出問題,現(xiàn)在我們來進(jìn)行簡單修改一下
export default function sum(a, b) {
return Number(a) + Number(b);
}
測試用例也需要同步添加
describe('測試sum方法', () => {
test('測試 1 + 2 = 3', () => {
expect(sum(1, 2)).toBe(3);
});
test('測試字符串相加', () => {
expect(sum('1', '2')).toBe(3);
});
});
現(xiàn)在功能正常運(yùn)行表箭,但是實際上這里還有問題赁咙,如果給的是 '' undefined null 等這里又會有問題
我們這個功能需要兼容各種場景,并不是只能適用于一個需求免钻,現(xiàn)在我們重新改造方法
const parseValue = value => Number.isNaN(Number(value)) ? 0 : Number(value);
export default function sum(a, b) {
return parseValue(a) + parseValue(b);
}
const testData = {
a: '1',
b: undefined
};
function App() {
return (
<div>
{sum(testData.a, testData.b)}
</div>
);
}
describe('測試sum方法', () => {
test('測試 1 + 2 = 3', () => {
expect(sum(1, 2)).toBe(3);
});
test('測試字符串相加', () => {
expect(sum('1', '2')).toBe(3);
});
test('測試空值相加', () => {
expect(sum(null, undefined)).toBe(0);
expect(sum('', undefined)).toBe(0);
});
});
現(xiàn)在感覺這個看起來可以正常運(yùn)行
但是我們需求總是不同的彼水,比如現(xiàn)在是只支持兩個參數(shù),后面多個參數(shù)也是有可能的极舔,這個時候就需要保證改造的同時支持原來的邏輯不受影響凤覆。到目前為止我們的測試用例仍然是不會出錯的。如果這個方法很復(fù)雜拆魏,別人不小心把 + 改成了 - 或者 * 盯桦,那么這個時候在去執(zhí)行測試用例就能找到問題慈俯,由于新的改動影響到了之前的測試用例,那么說明這次的改動是有問題的拥峦,能及時發(fā)現(xiàn)問題贴膘。
const parseValue = value => Number.isNaN(Number(value)) ? 0 : Number(value);
export default function sum(a, b) {
return parseValue(a) - parseValue(b);
}
所以測試用例就是用來保證功能的正常執(zhí)行,如果測試用例寫的場景較少事镣,改成下面這種也是發(fā)現(xiàn)不了問題的步鉴,如果這里傳入 0.1 + 0.2 === 0.3 嗎
describe('測試sum方法', () => {
test('測試空值相加', () => {
expect(sum(null, undefined)).toBe(0);
expect(sum('', undefined)).toBe(0);
});
});
如果你的方法寫了足夠全的測試用例,即使別人來改造你這個方法璃哟,也能盡快定位問題并回歸功能氛琢,而且測試用例還能定位到?jīng)]有執(zhí)行的代碼,刪除不用的代碼随闪,建議每次 build 的時候運(yùn)行一次測試用例阳似,避免出現(xiàn)問題(我寫的代碼天下第一,沒有bug铐伴,不需要單測)
這里提示第6行代碼沒有被執(zhí)行到撮奏,所以需要考慮方法里面的各種分支也是有用的,打包優(yōu)化也是必備的当宴。
測試用例要寫很多
其實是這樣的畜吊,為了避免線上問題,這是很有必要的户矢,因為很多組件或方法帶來的影響不僅僅只有一個地方玲献。對于一些業(yè)務(wù)頁面,通常變化過快梯浪,編寫成本過高捌年,可以多測試頁面的功能,回歸之前的功能(有問題測試背鍋)來代替測試用例的編寫挂洛,如果你的時間足夠充足可以上 ts + 測試用例(那我有時間為啥不弄點其他的)礼预。
現(xiàn)在我們來進(jìn)行react中的測試用例
這里采用 npx create-react-app test-app 來創(chuàng)建一個項目
腳手架已經(jīng)內(nèi)置了 jest 來進(jìn)行測試,如果你說為什么是 jest 虏劲,哪請去問 create-react-app托酸,
如果你是自己用 webpack 來搭建的項目,或者dva柒巫,請參考
jest配置 https://jestjs.io/docs/en/configuration (這或許會比較麻煩励堡,如果是項目初期可以,如果是項目后期需要加測試用例吻育,需要處理各種環(huán)境問題)
我想這是大家都會的(https://www.html.cn/create-react-app/docs/running-tests/)
- npx create-react-app test-app
- cd test-app
- npm start
- npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
- 在 src/setupTests.js 添加以下代碼
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
來源于 create-react-app 建議
文件名約定
Jest 將使用以下任何流行的命名約定來查找測試文件:
tests 文件夾中帶有 .js 后綴的文件念秧。
帶有 .test.js 后綴的文件淤井。
帶有 .spec.js 后綴的文件布疼。
.test.js / .spec.js 文件(或 tests 文件夾)可以是位于頂級文件夾 src 下任何深度的文件夾中摊趾。
我們建議將測試文件(或 tests 文件夾)放在他們正在測試的代碼旁邊,以便相對路徑導(dǎo)入時路徑更短游两。 例如砾层,如果 App.test.js 和 App.js 位于同一文件夾中,則測試只需從 import App from './App' 而不是很長的相對路徑贱案。 主機(jī)托管的情況下還有助于在大型項目中更快地找到測試肛炮。
基本庫
- 對于斷言庫使用 jest https://jestjs.io/docs/en/configuration ,這個可以用來測試代碼執(zhí)行的結(jié)果宝踪,代碼執(zhí)行了到了什么分支侨糟,什么沒有執(zhí)行到等等。
- 對于 react 測試采用 enzyme瘩燥、react-testing-library
這都是可以用來測試react秕重,只是語法api不同而且,建議了解一下在選擇厉膀,因為測試用例是運(yùn)行在node 環(huán)境下的溶耘,需要一個渲染的環(huán)境,而這個就可以在node環(huán)境里面執(zhí)行你的react代碼服鹅。
- src/utils/sum 下新建文件 index.js index.test.js
export default function sum(a, b) {
return a + b;
}
import sum from './index';
describe('測試sum方法', () => {
test('測試 1 + 2 = 3', () => {
expect(sum(1, 2)).toBe(3);
});
});
-
運(yùn)行 npm test凳兵,如果得到以下信息說明目前環(huán)境沒有問題
目前目錄結(jié)構(gòu)(文件顏色是因為git的關(guān)系)
現(xiàn)在來分析測試用例語法 https://jestjs.io/docs/en/getting-started
// describe 這個是 jest 庫方法,創(chuàng)建一個將幾個相關(guān)測試組合在一起的模塊
// test 運(yùn)行測試的方法企软,等同于 it
test('測試 1 + 2 = 3', () => {
// expect 返回一個 jest 對象庐扫,可以調(diào)用jest匹配器,
// 例如:
// toBe(3) 就是等于 3
// toBe(true) 就是等于 true
// toBe(false) 就是等于 false
// toBeNull 僅匹配 null
// toBeUndefined 僅匹配 undefined
// toBeTruthy 匹配if語句視為真實的任何內(nèi)容
// toBeFalsy 匹配if語句視為假的任何內(nèi)容
expect(sum(1, 2)).toBe(3);
});
// test === it
it('測試 1 + 2 = 3', () => {
expect(sum(1, 2)).toBe(3);
});
是不是很簡單澜倦,就是執(zhí)行前面的代碼邏輯聚蝶,后面來判斷是不是相等,更多api還需要去啃jest文檔藻治。
異步和mock等等
enzyme 對于react我們來新建幾個文件
src/components/Counter index.js index.test.js
import React, { PureComponent } from 'react';
class Index extends PureComponent {
state = {
value: 0
};
addition = () => {
this.setState(({ value }) => ({ value: value + 1 }));
};
subtraction = () => {
this.setState(({ value }) => ({ value: value - 1 }));
};
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.addition}>+</button>
<span>{value}</span>
<button onClick={this.subtraction}>-</button>
</div>
)
}
}
export default Index;
import React from 'react';
import { shallow } from 'enzyme';
import Counter from './index';
describe('測試 Counter 組件', () => {
test('測試渲染內(nèi)容', () => {
// shallow 這個方法返回一個react組件包裝對象碘勉,可以調(diào)用 enzyme 內(nèi)置方法
// 這是一個簡單的淺渲染,就是說只是渲染當(dāng)前組件的內(nèi)容桩卵,假如組件里面套用了很多其他組件验靡,
// 就不會被渲染到,import { mount } from 'enzyme'; 這個可以完整渲染雏节,需要根據(jù)自己場景來胜嗓。
const wrapper = shallow(<Counter />);
// wrapper.debug() 這個打印渲染組件內(nèi)容,可以用來調(diào)試钩乍。
console.log(wrapper.debug());
// wrapper.state() 獲取一個組件的 state辞州,然后在用jest來斷言,就是判斷初始化組件的state.value === 0
expect(wrapper.state().value).toBe(0);
// find('div') 方法是選擇器寥粹,類似于 document.querySelector document.querySelectorAll
// https://enzymejs.github.io/enzyme/docs/api/selector.html
expect(wrapper.find('div')).not.toBeNull();
expect(wrapper.find('button').length).toBe(2);
expect(wrapper.find('span').length).toBe(1);
});
test('測試添加', () => {
const wrapper = shallow(<Counter />);
const additionButton = wrapper.find('button').at(0);
/*
simulate 這個方法是用來主動觸發(fā)一個元素的事件变过,
因為我們在測試用例的環(huán)境里面不可能去手動點擊是吧埃元,
就算可以點擊,也不可能每次跑測試用例來點點點吧媚狰。
這個操作就是 enzyme 會去執(zhí)行 click 事件岛杀,可以傳入兩個參數(shù)
第一個參數(shù)是事件類型,第二個是事件參數(shù)崭孤,比如 { target: { value:'1' } }
然后調(diào)用的方法可以使用這個參數(shù)类嗤,然后我們在重新獲取到最新的state進(jìn)行判斷,
當(dāng)然了如果你調(diào)用兩次哪判斷條件就要改變辨宠,這里會想遗锣,setState 是異步的,
為什么這里立馬觸發(fā)了 setState 就可以獲取到最新值呢嗤形,這或許需要深入研究 enzyme 是怎么實現(xiàn)的黄伊。
*/
additionButton.simulate('click');
expect(wrapper.state().value).toBe(1);
});
test('測試減少', () => {
const wrapper = shallow(<Counter />);
const subtractionButton = wrapper.find('button').at(1);
subtractionButton.simulate('click');
expect(wrapper.state().value).toBe(-1);
});
});
運(yùn)行 npm test -- src/components/Counter/index.test.js,注意別忘了 -- 之間的空格
這是npm 命令傳參派殷,jest 可以接收到這個參數(shù)还最,并且只運(yùn)行這一個文件
現(xiàn)在有一個 計數(shù)器(Counter )組件,一個簡單的內(nèi)部狀態(tài)毡惜,+ - 和展示
但是寫測試用例應(yīng)該從比較底層的組件開始寫拓轻,如果一開始就要以大組件來編寫,可以考慮采用 jest mock 方法來模擬一個簡單的組件经伙。
然后進(jìn)行判斷數(shù)量是不是我們預(yù)期的扶叉,當(dāng)然了也不用逐個判斷,
使用 expect(wrapper.isEmptyRender()).toBeFalsy(); 來判斷是不是返回空也行帕膜,所以有時候即使測試用例
100%覆蓋率也有可能會有問題枣氧,還得看測試用例是怎么去寫的
運(yùn)行 npm test -- --coverage 可以查看覆蓋率,執(zhí)行了那些代碼
并且在package.json添加以下配置垮刹,這代表我們只收集 components 和 utils 下面的文件
https://www.html.cn/create-react-app/docs/running-tests/
"jest": {
"collectCoverageFrom": [
"<rootDir>/src/components/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/utils/**/*.{js,jsx,ts,tsx}"
]
}
如果你在這一步出錯了达吞,請刪除 package-lock.json 或 yarn-lock.json 文件,在刪除 node_modules 文件夾荒典,并重新 cnpm install酪劫,這可能是腳手架的bug
這就是一個簡單的組件渲染,并且我們觸發(fā)了事件∷露現(xiàn)在測試覆蓋率是 100%
Statements覆糟、Branches 、Functions遮咖、 Lines 滩字、Uncovered Line
語句、分支、函數(shù)麦箍、行酗电、未覆蓋線
然后在項目根目錄會生成一個 coverage 文件,里面會有代碼覆蓋率内列。
怎樣看沒執(zhí)行的代碼呢,我們現(xiàn)在注釋掉以下代碼
// test('測試添加', () => {
// const wrapper = shallow(<Counter />);
// const additionButton = wrapper.find('button').at(0);
// additionButton.simulate('click');
// expect(wrapper.state().value).toBe(1);
// });
現(xiàn)在重新生成報告背率,可以看到话瞧,函數(shù)覆蓋率為 60,第10行代碼沒執(zhí)行到
另外用瀏覽器打開 coverage\lcov-report\components\Counter\index.js.html 文件(如果不打開這個文件寝姿,是無法找到函數(shù)的調(diào)用交排,另外將coverage目錄添加到.gitignore里面,防止git提交)饵筑,可以看到紅色的就是沒有被執(zhí)行到的埃篓,這里有一個 addition 方法沒有被執(zhí)行到,第10行代碼沒有被執(zhí)行到根资,需要修改測試用例的執(zhí)行架专。這里可以得知,這個是基于我們寫的測試用例代碼來判斷這個組件的功能玄帕,不是實際應(yīng)用的場景部脚,如果你的功能就這兩個,又被添加了其他方法沒有使用裤纹,那么這個時候把沒有使用的代碼進(jìn)行刪除委刘。
現(xiàn)在添加一個test方法并重新執(zhí)行,可以看到 test 方法標(biāo)紅了鹰椒,這是多余的方法锡移,并且 Funcs 覆蓋率為 83
現(xiàn)在添加兩個生命周期進(jìn)行測試,測試用例不變漆际,說明 componentDidUpdate 是生效了的淆珊,因為我們觸發(fā)了
事件,會去setState奸汇,如果我們沒有去寫按鈕的測試用例套蒂,那么這個方法就是無用的,componentDidCatch 是因為組件沒有被出錯茫蛹,所以沒有被調(diào)用到操刀。
基本上這是一個react簡單的測試用例了,enzyme api還有很多婴洼,寫之前盡量看了文檔在入手骨坑,會少走很多彎路。https://enzymejs.github.io/enzyme/docs/api/
對于網(wǎng)絡(luò)請求,這是我們需要mock的
jest https://jestjs.io/docs/en/bypassing-module-mocks
axios可以參考 https://www.robinwieruch.de/axios-jest
fetch 可以參考 https://medium.com/@rishabhsrao/mocking-and-testing-fetch-with-jest-c4d670e2e167
我們在src下新建services/index.js 文件
需要先 cnpm install --save axios
services/index.js
import axios from 'axios';
export const counterValue = () => {
return axios.get('/counterValue.json');
};
我們繼續(xù)添加一個生命周期 componentDidMount 初始化的時候去網(wǎng)絡(luò)請求數(shù)據(jù)欢唾,并且設(shè)置為我們的初始值且警。
import React, { PureComponent } from 'react';
import { counterValue } from '../../services'
class Index extends PureComponent {
state = {
value: 0
};
async componentDidMount() {
await this.fetchData();
}
componentDidUpdate() {
console.log('更新');
}
fetchData = async () => {
const { data, success } = await counterValue();
success && this.setState({ value: data });
};
addition = () => {
this.setState(({ value }) => ({ value: value + 1 }));
};
subtraction = () => {
this.setState(({ value }) => ({ value: value - 1 }));
};
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.addition}>+</button>
<span>{value}</span>
<button onClick={this.subtraction}>-</button>
</div>
)
}
}
export default Index;
那么這個時候我們的組件有了請求,但實際跑測試用例的時候是不需要去真正的請求的礁遣,所以我們需要自己來偽造這個請求斑芜。修改一下測試用例代碼
import React from 'react';
import { shallow } from 'enzyme';
import axios from 'axios';
import Counter from './index';
// jest 內(nèi)部對 axios 進(jìn)行一些特殊處理
jest.mock('axios');
// 接口成功返回值
const successResult = {
success: true,
data: 2
};
// 接口失敗返回值
const errorResult = {
success: false
};
describe('測試 Counter 組件', () => {
// 在運(yùn)行此文件中的每個測試之前運(yùn)行一個函數(shù)
beforeEach(() => {
// 自己來mock axios.get 的返回值,避免網(wǎng)絡(luò)請求
axios.get.mockReturnValue(new Promise((resolve) => resolve(successResult)));
});
// 注意這里添加了 async 祟霍, 因為我們的組件 componentDidMount 的時候去發(fā)起了請求
// 所以這里需要異步杏头,然后在進(jìn)行后續(xù)操作,如果沒有寫 async await 沸呐,那么這里渲染的就是初始值
test('測試渲染內(nèi)容醇王,初始化接口成功', async () => {
const wrapper = await shallow(<Counter />);
expect(wrapper.state().value).toBe(2);
expect(wrapper.find('div')).not.toBeNull();
expect(wrapper.find('button').length).toBe(2);
expect(wrapper.find('span').length).toBe(1);
});
// 測試接口失敗的渲染
test('測試渲染內(nèi)容,初始化接口失敗', async () => {
axios.get.mockReturnValue(new Promise((resolve) => resolve(errorResult)));
const wrapper = await shallow(<Counter />);
expect(wrapper.state().value).toBe(0);
});
// 觸發(fā)事件也是需要這樣
test('測試添加', async () => {
const wrapper = await shallow(<Counter />);
const additionButton = wrapper.find('button').at(0);
additionButton.simulate('click');
expect(wrapper.state().value).toBe(successResult.data + 1);
});
test('測試減少', async () => {
const wrapper = await shallow(<Counter />);
const subtractionButton = wrapper.find('button').at(1);
subtractionButton.simulate('click');
expect(wrapper.state().value).toBe(successResult.data - 1);
});
});
react-testing-library
https://create-react-app.dev/docs/running-tests
https://testing-library.com/docs/react-testing-library/api#asfragment
在哪之前需要安裝
npm install --save @testing-library/react @testing-library/jest-dom
src/setupTests.js
import '@testing-library/jest-dom/extend-expect';
修改 src/components/Counter/index.js 為之前的代碼
import React, { PureComponent } from 'react';
class Index extends PureComponent {
state = {
value: 0
};
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(prevState);
}
addition = () => {
this.setState(({ value }) => ({ value: value + 1 }));
};
subtraction = () => {
this.setState(({ value }) => ({ value: value - 1 }));
};
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.addition}>+</button>
<span>{value}</span>
<button onClick={this.subtraction}>-</button>
</div>
)
}
}
export default Index;
測試用例
import React from 'react';
// 這里導(dǎo)包的文件修改
import { render } from '@testing-library/react';
import Counter from './index';
describe('測試 Counter 組件', () => {
test('測試渲染內(nèi)容', () => {
// 該render方法返回一個具有一些屬性的對象
// container.querySelector 就是原生js的查找方法崭添,這里來查找到是否有這些元素
// 如果你想判斷 state 或許需要使用 ref 來拿到react實例
// <Counter ref={xxx} /> ref 是你的變量
const { container } = render(<Counter />);
expect(container.querySelector('div')).not.toBe(null);
expect(container.querySelectorAll('button').length).toBe(2);
expect(container.querySelectorAll('span').length).toBe(1);
});
test('測試添加', () => {
const { container } = render(<Counter />);
const additionButton = container.querySelectorAll('button')[0];
// 這里查找到該按鈕寓娩,然后手動觸發(fā)了 .click() 事件,這不是testing-library的方法呼渣,這就是一個
// 原生對象自帶的方法
additionButton.click();
expect(container.querySelector('span').innerHTML).toBe('1');
});
test('測試減少', () => {
const { container } = render(<Counter />);
const subtractionButton = container.querySelectorAll('button')[1];
subtractionButton.click();
// 這里查找到span元素棘伴,判斷 innerHTML 值
expect(container.querySelector('span').innerHTML).toBe('-1');
subtractionButton.click();
expect(container.querySelector('span').innerHTML).toBe('-2');
});
});
這個和 enzyme 或許概念上有些不同,但是兩者都是可以進(jìn)行測試用例屁置,testing-library 不止支持 react排嫌。
對于接口的請求是一樣的 添加 async 和 await 就行
import React, { PureComponent } from 'react';
import { counterValue } from '../../services';
class Index extends PureComponent {
state = {
value: 0
};
async componentDidMount() {
await this.fetchData();
}
fetchData = async () => {
const { data, success } = await counterValue();
success && this.setState({ value: data });
};
addition = () => {
this.setState(({ value }) => ({ value: value + 1 }));
};
subtraction = () => {
this.setState(({ value }) => ({ value: value - 1 }));
};
render() {
const { value } = this.state;
return (
<div>
<button onClick={this.addition}>+</button>
<span>{value}</span>
<button onClick={this.subtraction}>-</button>
</div>
)
}
}
export default Index;
import React from 'react';
import { render } from '@testing-library/react';
import axios from 'axios';
import Counter from './index';
// jest 內(nèi)部對 axios 進(jìn)行一些特殊處理
jest.mock('axios');
const successResult = {
success: true,
data: 2
};
describe('測試 Counter 組件', () => {
// 在運(yùn)行此文件中的每個測試之前運(yùn)行一個函數(shù)
beforeEach(() => {
// 自己來mock axios.get 的返回值,避免網(wǎng)絡(luò)請求
axios.get.mockReturnValue(new Promise((resolve) => resolve(successResult)));
});
test('測試渲染內(nèi)容', () => {
const { container } = render(<Counter />);
expect(container.querySelector('div')).not.toBe(null);
expect(container.querySelectorAll('button').length).toBe(2);
expect(container.querySelectorAll('span').length).toBe(1);
});
test('測試添加', async () => {
const { container } = await render(<Counter />);
const additionButton = container.querySelectorAll('button')[0];
additionButton.click();
// 這里修改為 3
expect(container.querySelector('span').innerHTML).toBe('3');
});
test('測試減少', async () => {
const { container } = await render(<Counter />);
const subtractionButton = container.querySelectorAll('button')[1];
subtractionButton.click();
// 這里修改為 1
expect(container.querySelector('span').innerHTML).toBe('1');
subtractionButton.click();
// 這里修改為 0
expect(container.querySelector('span').innerHTML).toBe('0');
});
});
其他更多的方法調(diào)用請參考官網(wǎng)
https://testing-library.com/docs/react-testing-library/api#render-result
相關(guān)參考
- 如果你需要 redux 測試請參考 https://www.redux.org.cn/docs/recipes/WritingTests.html
- jest官網(wǎng) https://jestjs.io/docs/en/getting-started
- create-react-app測試用例 https://www.html.cn/create-react-app/docs/running-tests/
- react測試用例 https://zh-hans.reactjs.org/docs/testing.html
- enzyme文檔 https://enzymejs.github.io/enzyme/
- react-testing-library文檔 https://testing-library.com/docs/react-testing-library/intro