精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Jest:給你的 React 項目加上單元測試

開發(fā) 前端
單元測試(Unit Testing),指的是對程序中的模塊(最小單位)進行檢查和驗證。比如一個函數、一個類、一個組件,它們都是模塊。

大家好,我是前端西瓜哥。

Jest 是一款輕量的 JavaScript 測試框架,它的賣點是簡單好用,由 facebook 出品。本文就簡單講講如何使用 Jest 對 React 組件進行測試。

為什么需要單元測試?

單元測試(Unit Testing),指的是對程序中的模塊(最小單位)進行檢查和驗證。比如一個函數、一個類、一個組件,它們都是模塊。

使用單元測試的優(yōu)點:

  • 更好地交付高質量代碼。代碼不可能沒有 bug,測試能幫你找出來;
  • 更容易重構。我們不愿意去重構代碼,不去還技術債,很大原因是測試覆蓋率不足,害怕遺漏一些邊邊角角的邏輯,導致線上發(fā)生重大事故;
  • 可以用測試描述模塊功能。注釋和文檔容易忘記修改,但測試用例的描述永遠是準確的,因為不對就無法通過測試;
  • 可測試性好的代碼,往往可維護性更好。比如某個模塊很難測試,是因為它和其他模塊高度耦合,此時你需要替換為依賴注入的方式來管理模塊依賴。

Jest 判定測試腳本

Jest 需要 確認哪些是測試文件,默認判斷測試文件的邏輯是:

  • __tests__? 文件夾下的 .js  .jsx、.ts 、.tsx 為后綴的文件。
  • test.js? 、spec.js 或其他文件后綴  .jsx、.ts 、.tsx。

可以通過設置  Jest 配置文件的 testMatch 或 testRegex 選項進行修改,或者 package.json 下的 "jest" 屬性。

Jest 基本使用

我們先寫一個簡單的函數,作為被測試的模塊。

function sum(a, b) {
return a + b;
}
export default sum;

然后我們用 Jest 來做測試。

import sum from './sum';

test('1 + 1 應該等于 2', () => {
expect(sum(1, 1)).toBe(2);
});

然后執(zhí)行 jest 命令,得到測試結果。

圖片

test 方法創(chuàng)建了一個測試的作用域,該方法有三個參數:

  1. 測試的描述。
  2. 我們寫測試代碼的函數。
  3. 測試超時時間,默認為 5 秒,有些測試是異步的,我們需要等待。

test 方法有一個別名叫做 it,二者的功能是一致的,只是語義不同。通常用 test,但在某些情況下更適合用 it。這種情況就是 it 可以和描述語句拼成一句話的時候,比如:

it('should be true', () => { /* 測試內容 */});

it 方法和后面的 should be true 拼成了一句主語為 it 的句子,語義更好。

我們通常使用 expect 來測試一個模塊的邏輯是否符合預期。expect 會將模塊返回的結果封裝成一個對象,然后提供非常豐富的方法做測試。

比如 toBe 就可以做 Object.is 的對比測試。

// sum(1, 1) 的結果是否為 2
expect(sum(1, 1)).toBe(2);

expect 的實現思路大致為:

function expect(value) {
return {
toBe(comparedValue) {
if (Object.is(value, comparedValue)) {
// 記錄測試成功
} else {
// 記錄測試失敗
}
},
// 其他 API
toBeTruthy() { /* ... */ },
// ...
}
}

利用了閉包。

還有一些其他的 toXX API,我們稱為 matcher。比如:

  • toEqual:對對象進行深遞歸的 Object.is 對比。
  • toBeTruthy:是否為真值。
  • not:對結果取反,比如expect(val).not.beBe(otherVal) 表示兩值不相等才通過測試。
  • toContain:數組中是否含有某個元素。
  • toBeLessThan:是否小于某個值,可以做性能測試,執(zhí)行某個函數幾千次,時間不能高于某個值。

更多 API 可以看文檔:

??https://jestjs.io/docs/expect。??

你可以用 describe 方法將多個相關的 test 組合起來,這樣能讓你的測試用例更好地被組織,測試報告輸出也更有條理。

describe('一個有多個屬性的對象的測試', () => {
test('test 1', async () => {
expect(obj.a).toBeTruthy();
});

test('test 2', async () => {
expect(obj.b).toBeTruthy();
});
});

describe 里面可以嵌套 describe,即組里面還可以有組。

異步測試

如果使用異步測試,需要將 Promise 作為返回值。

test('請求測試', () => {
return getData().then(res {
expect(res.data.success).toBe(true);
})
})

或使用 async / await。

test('請求測試', async () => {
const res = await getData();
expect(res.data.success).toBe(true);
})

也支持回調函數風格的測試,你需要調用函數傳入的 done 函數來表明測試完成:

test('異步測試', done => {
setTimeout(() {
expect('前端西瓜哥').toBeTruthy();
done();
}, 2000);
});

生命周期函數

beforeAll,在當前文件的正式開始測試前執(zhí)行一次,適合做一些每次 test 前都要做的初始化操作,比如數據庫的清空以及初始化。

beforeEach,在當前文件的每個 test 執(zhí)行前都調用一次。

afterAll,在當前文件所有測試結束后執(zhí)行一次,適合做一些收尾工作,比如將數據庫清空。

afterEach,在當前文件的每個 test 執(zhí)行完后都調用一次。

React Testing Library

本文不講解安裝和配置,我們先用 CreateReactApp 來搭建項目,并使用 TypeScript 模板。

yarn create react-app jest-app --template typescript

執(zhí)行單元測試的命令為:

yarn test

CreateReactApp 內置了 Jest,但 Jest 本身并不支持 React 組件的測試 API,需要使用另外一個內置的 React Testing Library 庫來測試  React 組件。

React Testing Library 是 以用戶為角度 的測試庫,能夠模擬瀏覽器的 DOM,將 React 組件掛載上去后,我們使用其提供的一些模擬用戶操作的 API 進行測試。

React Testing Library 的哲學是:

測試的寫法越是接近應用被使用的方式,我們就越有自信將其交付給客戶。

CreateReactApp 預置模板的 App.test.tsx 使用了 React Testing Library。

import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
render(<App);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

Enzyme

另一種比較流行的測試 React 組件的框架是  Enzyme,它的 API 簡潔優(yōu)雅,能夠用類似 JQuery 的語法,對開發(fā)非常友好。Enzyme 由 Airbnd 出品,但目前已經不怎么維護了。

為此,你需要裝一些包:

yarn add -D enzyme enzyme-adapter-react-16

如果你使用了 TS,你還得補上類型聲明。

yarn add -D @types/enzyme @types/enzyme-adapter-react-16

示例:

import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Button from '../button';
Enzyme.configure({ adapter: new Adapter() });
it('Button with children', () => {
const text = 'confirm';
const btn = shallow(<Button>{text}</Button>);
expect(btn.text()).toBe(text);
});

目前(2022.10.25) enzyme 官方只支持到 React 16,Enzyme 已死:

??https://dev.to/wojtekmaj/enzyme-is-dead-now-what-ekl。??

使用 Jest 測試 React 組件

我們先實現一個簡單的 Button 組件。

import { CSSProperties, MouseEvent, FC } from 'react';
import classNames from 'classnames';
import './style.scss';

const clsPrefix = 'xigua-ui-btn';

export type ButtonProps = {
type?: 'primary' | 'default'
size?: 'large' | 'middle' | 'small';
disabled?: boolean;
children?: React.ReactNode;
onClick?: (event: MouseEvent) => void;
style?: CSSProperties;
className?: string;
}

const Button: FC<ButtonProps> = (props) => {
const {
type = 'default',
size = 'middle',
disabled = false,
children,
onClick,
style,
className,
} = props;

const mixedClassName = classNames(
clsPrefix,
`${clsPrefix}-${type}`,
`${clsPrefix}-${size}`,
className
);

return (
<button
style={style}
className={mixedClassName}
disabled={disabled}
onClick={onClick}
>
{children}
</button>
);
};

export default Button;

然后我們創(chuàng)建一個 button.test.tsx 測試文件。我們使用 React Testing Library。

我們寫個測試。

import { render, screen } from '@testing-library/react';
import Button from '../button';

test('Button with children', () => {
const text = 'confirm Btn';
render(<Button>{text}</Button>);

screen.debug();
});

render 方法會將 React 組件掛載到虛擬的文檔樹上。screen.debug() 用于調試,能讓我們看到虛擬樹的完整結構。

<body>
<div>
<button
class="xigua-ui-btn xigua-ui-btn-default xigua-ui-btn-middle"
>
confirm Btn
</button>
</div>
</body>

測試 Button 的文本內容是否正常顯示:

test('Button with children', () => {
const text = 'confirm Btn';
// 渲染 Button 組件
render(<Button>{text}</Button>);

// 找到內容為 text 的元素
const BtnElement = screen.getByText(text);
// 測試元素是否在 Document 上
expect(BtnElement).toBeInTheDocument();
});

測試 Button 的 onClick 能否正常觸發(fā):

test('Button click', () => {
let toggle = false;
render(<Button onClick={() => { toggle = true; }} />);

// 找到第一個 button 元素,然后觸發(fā)它的點擊事件
fireEvent.click(screen.getByRole('button'));
// 看看 toggle 變量是否變成 true
expect(toggle).toBe(true);
});

測試 Button 的 className 是否成功添加:

test('Button with custom className', () => {
const customCls = 'customBtn';
render(<button className={customCls} />);

// 找到按鈕元素
const btn = screen.getByRole('button');
// 元素的 className 列表上是否有我們傳入的 className
expect(btn).toHaveClass(customCls);
});

源碼:

??https://github.com/F-star/xigua-ui/blob/main/src/components/button/??tests/button.test.tsx。

執(zhí)行 yarn test :

圖片

結尾

為了讓代碼更健壯,做模塊的單元測試還是有必要的,Jest 作為流行的測試庫值得一試。

責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2020-03-19 14:50:31

Reac單元測試前端

2021-10-12 19:16:26

Jest單元測試

2017-01-14 23:42:49

單元測試框架軟件測試

2017-09-13 15:05:10

React前端單元測試

2017-09-10 17:41:39

React全家桶單元測試前端測試

2023-07-26 08:58:45

Golang單元測試

2011-05-16 16:52:09

單元測試徹底測試

2011-07-27 17:02:12

Xcode iPhone 單元測試

2009-06-26 17:48:38

JSF項目單元測試JSFUnit

2017-01-16 12:12:29

單元測試JUnit

2017-01-14 23:26:17

單元測試JUnit測試

2021-09-18 15:40:03

Vue單元測試命令

2011-06-14 15:56:42

單元測試

2020-08-18 08:10:02

單元測試Java

2022-05-12 09:37:03

測試JUnit開發(fā)

2017-03-23 16:02:10

Mock技術單元測試

2021-05-05 11:38:40

TestNGPowerMock單元測試

2020-05-07 17:30:49

開發(fā)iOS技術

2011-07-04 18:16:42

單元測試

2024-10-16 16:09:32

點贊
收藏

51CTO技術棧公眾號

国产激情久久久久久熟女老人av| 午夜久久久久久久| 大片免费在线观看| 国产伦精品一区二区三区视频青涩| 久久影院在线观看| 精品影片一区二区入口| 国产精品久久久久av电视剧| 国产精品你懂的| 亚洲综合在线小说| 欧美激情黑白配| 你懂的一区二区三区| 欧美亚洲高清一区| 美女黄色免费看| 国产51人人成人人人人爽色哟哟| 亚洲一区二区电影| 欧美日韩一区二区精品| 欧洲精品久久| 99草在线视频| 久久久久久黄| 不卡av在线网站| 精品人妻互换一区二区三区| 日韩一区二区三区色| 91福利在线看| 欧美成人高潮一二区在线看| av在线电影网| 美女久久网站| 久久成年人免费电影| 精品少妇一区二区三区免费观| 久草在线资源站资源站| 日本一区二区综合亚洲| 国产精品久久久久av福利动漫| 波多野结衣视频观看| 日韩视频在线一区二区三区 | 亚洲最新av网站| 亚洲精品1区2区| 精品国偷自产在线视频99| 免费观看av网站| 岛国成人av| 欧美一区二区三区色| www.亚洲高清| 亚洲精品在线影院| 精品久久久久久久久久久久久久| 欧美 日韩 国产精品| 黄色国产网站在线播放| 中文字幕欧美激情一区| 日本高清不卡三区| 欧美美女搞黄| 99国产欧美久久久精品| 国产日韩一区欧美| 亚洲精品视频网| 国产一区二区美女诱惑| 成人美女免费网站视频| 中文字幕777| 久久精品三级| 国产精品99久久99久久久二8| 成人精品免费在线观看| 亚洲三级网站| 97在线观看免费高清| 中文乱码人妻一区二区三区视频| 欧美黄视频在线观看| 欧美二区三区91| 蜜桃福利午夜精品一区| 亚洲tv在线| 91精品国产91久久久久久一区二区| 亚洲午夜激情影院| 国产亚洲观看| 欧美成人vr18sexvr| 免费观看黄网站| 一区二区在线视频观看| 亚洲激情 国产| 日b视频在线观看| 欧美男gay| 中文字幕一区二区精品| 911国产在线| 亚洲h色精品| 九九精品视频在线| 亚洲激情视频一区| 久久久青草婷婷精品综合日韩| 51ⅴ精品国产91久久久久久| 中文字幕 人妻熟女| 久久精品国产**网站演员| 亚洲一区二区免费| 免费观看毛片网站| 国产亚洲污的网站| 高清日韩一区| 91 中文字幕| 国产乱人伦偷精品视频免下载| 成人自拍偷拍| 日韩二区三区| 国产精品久久久99| 国产小视频免费| 少妇视频在线观看| 欧美日韩一区二区在线观看| 天美一区二区三区| 日本午夜精品久久久| 伊人久久五月天| 国产一级片免费看| 久久综合影音| 2019国产精品视频| 精品影院一区| 亚洲综合成人在线| 激情网站五月天| 日韩一二三区| 在线精品播放av| 精品在线免费观看视频| 免费一级片91| 国内视频一区| 成人在线视频亚洲| 欧美性极品xxxx做受| 污免费在线观看| 精品一级毛片| 97精品伊人久久久大香线蕉| 国产一区二区三区视频免费观看| 99精品桃花视频在线观看| 综合色婷婷一区二区亚洲欧美国产| 91资源在线观看| 欧美美女bb生活片| 91网页在线观看| 色爱综合区网| 图片区偷拍区小说区| 国产精品免费99久久久| 欧美麻豆久久久久久中文| 日韩人妻精品中文字幕| 高潮精品一区videoshd| 中文字幕久久一区| 韩国成人漫画| 亚洲国产毛片完整版| 国产三级国产精品国产国在线观看| 玖玖在线精品| 久久久久免费网| 国模雨婷捆绑高清在线| 欧美精品黑人性xxxx| 丁香花五月婷婷| 最新亚洲一区| 岛国视频一区| 午夜av在线播放| 欧美精品第一页| 青青草视频成人| 国产欧美日韩一级| 国产精品久久久对白| 青草青在线视频| 91精品国产色综合久久不卡蜜臀 | 日韩久久一区二区三区| 精品国产一区二区三区av性色| 一区二区三区影视| 麻豆成人综合网| 色综合久久久久久久久五月| 欧美色网在线| 在线观看亚洲区| 天堂av免费在线观看| 国产视频视频一区| 国产偷人视频免费| 久久93精品国产91久久综合| 欧美在线视频观看| 欧美午夜黄色| 色偷偷成人一区二区三区91| 国产一区二区三区播放| 亚洲精品乱码日韩| 久久精品国产精品亚洲| 97人妻精品一区二区三区动漫 | 欧美成人r级一区二区三区| 裸体武打性艳史| 国产福利91精品一区二区三区| 在线观看17c| 忘忧草在线影院两性视频| 亚洲国产黄色片| 五月婷婷中文字幕| 久久综合久久鬼色中文字| 欧美视频第三页| 精品一区二区三| 国产欧美日韩免费看aⅴ视频| 日本高清视频在线观看| 91精品婷婷国产综合久久性色 | 国产精品18久久久久久麻辣| 日韩精品黄色| 日韩欧美国产精品一区| 五月天婷婷丁香| 久久精品一区二区三区四区| a在线观看免费视频| 91精品国产成人观看| 不卡视频一区二区| 中文字幕在线视频网站| 在线视频欧美性高潮| 国产精品自产拍| 香蕉加勒比综合久久| 蜜桃传媒一区二区亚洲| 激情文学综合丁香| 国产美女永久无遮挡| 亚洲va久久| 91精品视频免费| 国产在线美女| 中文字幕日韩在线视频| 精品久久久久成人码免费动漫| 欧美日韩免费观看中文| 一级片黄色录像| 成人中文字幕电影| 五月天男人天堂| 超碰97久久国产精品牛牛| 在线观看国产精品91| 国产成人av免费看| 色哟哟精品一区| 国产高潮国产高潮久久久91 | 超碰在线免费公开| 亚洲精品按摩视频| 91九色蝌蚪91por成人| 天天综合网天天综合色| 日本黄色录像视频| 91天堂素人约啪| 手机在线视频一区| 欧美亚洲网站| 国产欧美久久久久| 成人免费在线观看av| 国产精品一区二区三区不卡| 国产69精品久久久久9999人| 亚洲欧洲在线看| 99热精品在线播放| 色狠狠av一区二区三区| 国产在线观看你懂的| 中文字幕欧美区| 三级电影在线看| 国产精品性做久久久久久| 动漫av免费观看| 99在线精品视频在线观看| 91免费视频黄| 日韩激情图片| 国产精品亚发布| av在线天堂| 日韩久久免费视频| 性生交生活影碟片| 欧美日韩aaa| 免费视频网站在线观看入口| 欧美日韩精品二区| www.youjizz.com亚洲| 亚洲女女做受ⅹxx高潮| 日本二区三区视频| 日本一区二区三区在线不卡| 97人妻精品一区二区三区免 | 色呦呦一区二区三区| 日本一级黄色大片| 亚洲一区二区四区蜜桃| 欧美日韩三级在线观看 | 日本学生初尝黑人巨免费视频| 亚洲日本va在线观看| 波多野结衣三级视频| 红桃视频国产一区| 97超碰免费观看| 99久久久久国产精品| 一区不卡字幕| 国产精品久久观看| 在线视频不卡一区二区| 四虎成人av| 杨幂一区欧美专区| 婷婷亚洲综合| 中文字幕精品在线播放| 午夜国产精品视频免费体验区| 大桥未久一区二区三区| 一区二区在线| 久久福利一区二区| 欧美亚洲不卡| 1024av视频| 久久久久久黄| 中文字幕视频在线免费观看| 蜜臀av亚洲一区中文字幕| 91女神在线观看| 国产麻豆精品在线观看| 欧美xxxx日本和非洲| www.在线成人| 久久亚洲AV无码专区成人国产| 国产三级一区二区| 国产精品久久国产精麻豆96堂| **欧美大码日韩| 免费看一级一片| 午夜伦欧美伦电影理论片| 男人日女人网站| 欧美性做爰猛烈叫床潮| 国产男女猛烈无遮挡| 精品美女在线播放| 蜜桃视频在线免费| 日韩视频亚洲视频| 色婷婷在线播放| 欧美亚洲免费电影| 色诱色偷偷久久综合| av一区二区三区在线观看| 青青视频一区二区| 亚洲色图自拍| 伊人精品成人久久综合软件| 青春草在线视频免费观看| 欧美精品91| 欧美 日韩精品| 九一九一国产精品| 无码任你躁久久久久久老妇| 国产亚洲欧美激情| 精品99久久久久成人网站免费 | 24小时成人在线视频| 成人国产一区二区| 亚洲天堂日韩在线| 国产欧美综合一区| 亚洲高清毛片| 欧美女同在线观看| 成人黄色国产精品网站大全在线免费观看| 少妇大叫太粗太大爽一区二区| 国产精品天天摸av网| 天堂资源在线播放| 欧美电影影音先锋| 日本福利片在线| 久久6精品影院| 8av国产精品爽爽ⅴa在线观看| 超碰97国产在线| 日韩欧美一区免费| 免费无遮挡无码永久视频| 国内精品视频一区二区三区八戒| 欧美做受喷浆在线观看| 亚洲欧美韩国综合色| 国产情侣呻吟对白高潮| 亚洲高清在线观看| 黄色免费在线观看网站| 国产成人精品久久久| 国产精品毛片久久久| 秋霞在线一区二区| 日本欧美在线看| 精品人妻一区二区三区香蕉| 一区二区三区欧美视频| 一级片在线观看视频| 国产一区二区美女视频| 成人在线免费视频| 97成人精品区在线播放| 日韩精品一区二区三区中文在线| 亚洲v日韩v欧美v综合| 性8sex亚洲区入口| 国产 xxxx| 亚洲国产另类精品专区| 国产av无码专区亚洲av麻豆| 中文字幕亚洲无线码在线一区| www.成人影院| 久久国产精品99久久久久久丝袜| 激情自拍一区| 国产调教打屁股xxxx网站| 亚洲欧洲国产日韩| 亚洲天堂中文在线| 亚洲图片欧美日产| 午夜精品成人av| 欧美资源一区| 美女视频一区免费观看| 性欧美成人播放77777| 香蕉加勒比综合久久| 隣の若妻さん波多野结衣| 精品亚洲va在线va天堂资源站| 91制片在线观看| 国产精品日韩高清| 亚洲作爱视频| 性久久久久久久久久| 欧美日韩久久久久| 巨骚激情综合| 国产精品第3页| 欧美日韩国产在线观看网站 | 日韩大片欧美大片| 欧美亚洲免费高清在线观看 | 成人精品视频| 色播五月综合网| 亚洲嫩草精品久久| 亚洲欧美激情在线观看| 韩国19禁主播vip福利视频| 欧美日韩一区二区三区四区不卡| 日韩精品 欧美| 久久青草欧美一区二区三区| 亚洲高清视频免费观看| 色噜噜狠狠狠综合曰曰曰| 国产aa精品| 一卡二卡三卡视频| 久久久久久久久久电影| 中文字幕一区二区在线视频 | 开心色怡人综合网站| 欧美电影一区| 亚洲女人在线观看| 亚洲五码中文字幕| 三级视频网站在线| 国产精品久久久久久久久男| 99久久激情| 精品久久久久久无码人妻| 欧美日韩亚洲成人| 95在线视频| 鬼打鬼之黄金道士1992林正英| 99这里有精品| 999福利视频| 精品国产三级电影在线观看| 高潮一区二区| 最新视频 - x88av| 97久久精品人人做人人爽| а中文在线天堂| 久久久久国产视频| 综合国产视频| 97超碰人人看| 欧美性xxxxxxx| 成人短视频在线观看| 国产一区二区三区无遮挡 | 亚洲国产成人av好男人在线观看| 日本福利在线观看| 99在线视频播放| 久久先锋资源| 精品肉丝脚一区二区三区|