第二部分 - 測試篇:給組件加上單元測試css
原文連接html
在第一部分,咱們基於 create-react-app
構建了項目的基礎結構。對於一個組件庫來講,不只要有簡單,實用的組件,每個組件的質量也是相當重要。而單元測試,正是提高軟件質量的一種有效的手段。在本文中,不只會在以前的項目中完成單元測試的配置,還會帶着你們一塊兒走進單元測試的世界~node
本篇文章,是這個系列的第二篇 - 單元測試react
首先,告訴你們一個小祕密,就是我不太喜歡單元測試。它很費時,重構項目會變得很吃力。並且,單元測試沒有一個明確的邊界,有時總會以爲本身的單元測試寫的不夠。並且,代碼也並不會由於單元測試就不會出現 BUG
,即便你的測試覆蓋率達到了💯%。git
值得幸運的是,對於 React
應用來講,單元測試的成本正在逐步下降。github
首先,在 TypeScript
出現以後,咱們不須要去寫大部分的單元測試。npm
舉個簡單的例子,這是 TypeScript
的實現:json
type Props = {
name: string;
};
複製代碼
而下面的這段代碼,是單元測試的版本:api
import React from 'react';
import Component from './Component';
test('does not do something completely embarassing if I forgot to pass a name', () => {
const { getByText } = render(<Component />);
expect(getByText('Name: ')).not.toBeInTheDocument();
});
複製代碼
因此,TypeScript
的類型系統的出現,已經再也不須要這部分的單元測試了。bash
Eslint
會分析代碼,並根據一組規則對其進行檢查。這聽起來也很像測試。而 Prettier
能夠根據一組規則來約束代碼風格。而且,在編寫代碼的時候,配合編輯器就能夠獲得即時的反饋了。
上面所提到的技術,更可能是從語言,代碼質量,代碼風格的角度來提高軟件的質量,但卻沒有像一個用戶同樣來使用咱們的軟件。畢竟,軟件怎麼使用,只有開發者清楚。
除了編寫文檔、註釋、編寫 Demo。單元測試也更像是軟件的一種說明書,爲軟件的使用提供了保障。
和 React 文檔 中所描述的同樣,本文也只是討論:渲染組件樹,在一個簡化的測試環境中渲染組件樹並對它們的輸出作斷言檢查。
由於以前使用的是 react-app-rewired
做爲 Cli 工具,它會對 Jest
的版本有所限制。因此,下面安裝依賴時,有些庫會鎖住版本。
npm i -D ts-jest@24.1.0 @types/jest jest@24.9.0 jest-html-reporter @testing-library/react @babel/preset-env @babel/preset-react
複製代碼
爲了使用安裝的這些依賴,接下來須要修改下 package.json
,增長測試,以及提交以前的校驗。
...
"scripts": {
+ "test": "jest --no-cache",
}
...
"lint-staged": {
"*.{js,ts,tsx}": [
"eslint --fix src/**/*.{ts,tsx}",
+ "jest --bail --coverage --findRelatedTests",
"git add ."
],
"*.{md,css,html,less}": [
"prettier --write",
"git add ."
]
}
複製代碼
最後,還須要給 Jest
增長一個配置文件:jest.config.js
module.exports = {
preset: 'ts-jest',
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
globals: {
'ts-jest': {
babelConfig: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
},
testEnvironment: 'jsdom',
testMatch: [
'<rootDir>/src/**/__tests__/**/*.{ts,tsx,js,jsx,mjs}',
'<rootDir>/src/**/?(*.)(spec|test).{ts,tsx,js,jsx,mjs}',
],
reporters: [
'default',
[
'./node_modules/jest-html-reporter',
{
pageTitle: '測試報告',
},
],
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
collectCoverage: true,
collectCoverageFrom: ['app/react/**/*.{ts,tsx}', '!app/react/__tests__/api/api-test-helpers.ts'],
};
複製代碼
這裏,我須要給以前添加的 EmptyLine
,增長測試用例。
import './style/index.less';
import EmptyLine from './EmptyLine';
export default EmptyLine;
複製代碼
import React from 'react';
export interface IEmptyLineProps {
height?: number;
}
const EmptyLine = ({ height = 20 }: IEmptyLineProps) => {
return <div className="d-empty-line" style={{ height }} />;
};
export default EmptyLine;
複製代碼
import React from 'react';
import { create, act } from 'react-test-renderer';
import EmptyLine from '../EmptyLine';
test('默認高度渲染正常', () => {
const emptyLine = create(<EmptyLine />).toJSON();
expect(emptyLine?.props.style).toEqual(
expect.objectContaining({
height: 20,
}),
);
});
test('自定義高度渲染正常', () => {
let emptyLine: any;
act(() => {
emptyLine = create(<EmptyLine height={30} />);
});
expect(emptyLine.toJSON()?.props.style).toEqual(
expect.objectContaining({
height: 30,
}),
);
});
複製代碼
下面,就是兩個 EmptyLine
常見的使用場景,已經在咱們的單元測試中都覆蓋到了。
須要注意的是,這裏的 EmptyLine.tsx
組件中並無引入樣式,而是在同級的 index.tsx
中引入了樣式。由於,這裏樣式在測試的時候是不支持引入的,會出問題。
運行 npm run test
就能夠看到結果:
當咱們提交代碼,commit
的時候,也會在根目錄生成一個測試報告:
到這裏,咱們給組件庫增長了測試的功能。使咱們的組件庫也變得更加有保障,高大上了起來。最後,在第三章中,咱們會聊聊如何打包,並上傳至 NPM
的事情,敬請期待吧。