第二部分 - 测试篇:给组件加上单元测试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
的事情,敬请期待吧。