1. 程式人生 > 其它 >web前端單元測試入門,以Ant Design Pro為例

web前端單元測試入門,以Ant Design Pro為例

單元測試做什麼

編寫用來做單元測試的js檔案,並執行。

適合對誰做:

  • 存放靜態方法的js檔案,如utils/utils.js
  • 頁面元件,即React Component
    不適合對誰做:
  • 模板自帶的js檔案(不需要做改動,而且這種一般跑單測會有問題)

單元測試檔案的特點:

  • 一般有特定名稱,如*.test.js
  • 一個寫業務程式碼的檔案對應一個寫單測的檔案,如 login.jsx login.test.js

單元測試怎麼做

以一個最新版 ant design pro 模板專案為例。

  1. 安裝需要的庫。
npm install --save @testing-library/react @testing-library/jest-dom
  1. 若干檔案需要配置。
    jest.config.js
module.exports = {
  testURL: 'http://localhost:8000',
  testEnvironment: './tests/PuppeteerEnvironment',
  verbose: false,
  setupFilesAfterEnv: ['./tests/setupTests.js'],
  globals: {
    ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false,
    localStorage: null,
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '^@@/(.*)$': '<rootDir>/src/.umi/$1',
  },
  collectCoverage: true,
  collectCoverageFrom: [
    "src/pages/**/*.{js,jsx}",
    "!**/node_modules/**",
    "!**/vendor/**"
  ]
};

tests\setupTests.js

// do some test init
// react-testing-library 將您的元件顯示為document.body,
// 這將為 jest-dom 新增一個自定義斷言
import '@testing-library/jest-dom';

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(), // Deprecated
    removeListener: jest.fn(), // Deprecated
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
});

const localStorageMock = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  removeItem: jest.fn(),
  clear: jest.fn(),
};

global.localStorage = localStorageMock;
  1. 給頁面元件寫個單測試下
    src\pages\Welcome.jsx
    有改動
import React from 'react';
import { PageContainer } from '@ant-design/pro-layout';
import { Card, Alert, Typography } from 'antd';
import { FormattedMessage } from 'umi';
import styles from './Welcome.less';

const CodePreview = ({ children }) => (
  <pre className={styles.pre}>
    <code>
      <Typography.Text copyable>{children}</Typography.Text>
    </code>
  </pre>
);

export default () => {
  return (
    <PageContainer>
      <Card>
        <Alert
          message='更快更強的重型元件,已經發布。'
          type="success"
          showIcon
          banner
          style={{
            margin: -12,
            marginBottom: 24,
          }}
        />
        <Typography.Text strong>
          高階表格{' '}
          <a
            href="https://procomponents.ant.design/components/table"
            rel="noopener noreferrer"
            target="__blank"
          >
            歡迎使用
          </a>
        </Typography.Text>
        <CodePreview>yarn add @ant-design/pro-table</CodePreview>
        <Typography.Text
          strong
          style={{
            marginBottom: 12,
          }}
        >
          高階佈局{' '}
          <a
            href="https://procomponents.ant.design/components/layout"
            rel="noopener noreferrer"
            target="__blank"
          >
            歡迎使用
          </a>
        </Typography.Text>
        <CodePreview>yarn add @ant-design/pro-layout</CodePreview>
      </Card>
    </PageContainer>
  );
};

src\pages\Welcome.test.js
這個註釋必須保留

/**
 * @jest-environment jsdom
 */

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

it('renders welcome message', () => {
  render(<Welcome />);
  expect(screen.getByText('yarn add @ant-design/pro-table')).toBeInTheDocument();
});
  1. 跑!
npm run test

單元測試達到什麼效果

提升程式碼可維護性、提高測試效率、提升開發人員水平...
(省略10000字)

單元測試遇到的問題

一個業務正常的程式碼檔案,單測跑不過。

解決問題的思路

提供幾個方向:

  • jest.config.js 配置問題。
  • tests\setupTests.js 全域性測試指令碼問題。
  • src\pages\Welcome.test.js 單個的測試指令碼問題。
  • 頁面檔案本身的問題。
  • 頁面檔案引用的庫的問題(umi外掛可能會和Jest不相容)。