• type: 进阶
  • 单元测试
    • 写一个用例
    • 本地执行
      • 执行单个或一组用例
    • 测试 dva 包装组件
  • e2e 测试
    • 写一个 e2e 用例
    • 运行用例
  • watch 模式
  • 测试覆盖率
  • 聚焦和忽略用例
  • 接入集成测试服务
  • 参考链接

    order: 15
    title: UI 测试

    type: 进阶

    UI 测试是项目研发流程中的重要一环,有效的测试用例可以梳理业务需求,保证研发的质量和进度,让工程师可以放心的重构代码和新增功能。

    Ant Design Pro 封装了一套简洁易用的 React 单元测试和 E2E 测试方案,在项目根目录运行以下命令就能运行测试用例。

    1. $ npm run test:all # 执行所有测试

    UI 测试  - 图1

    下面简单介绍如何在项目中书写你的业务测试用例。

    单元测试

    单元测试用于测试 React UI 组件的表现。我们参考了 create-react-app,使用 jest 作为测试框架。

    jest 是一个 node 端运行的测试框架,使用了 jsdom 来模拟 DOM 环境,适合用于快速测试 React 组件的逻辑表现,需要真实浏览器可以参考 E2E 测试部分。

    写一个用例

    比如,我们可以建一个文件 src/routes/Result/Success.test.js 来测试成功页面组件的 UI 表现。

    1. import React from 'react';
    2. import { shallow } from 'enzyme';
    3. import Success from './Success'; // 引入对应的 React 组件
    4. it('renders with Result', () => {
    5. const wrapper = shallow(<Success />); // 进行渲染
    6. expect(wrapper.find('Result').length).toBe(1); // 有 Result 组件
    7. expect(wrapper.find('Result').prop('type')).toBe('success'); // Result 组件的类型是成功
    8. });

    这里使用了 enzyme 作为测试库,它提供了大量实用的 API 来帮助我们测试 React 组件。断言部分沿用了 jest 默认的 jasmine2 expect 语法。

    本地执行

    使用以下的命令将统一搜索和执行 src*.test.js 格式的用例文件。

    1. $ npm test .test.js

    执行单个或一组用例

    1. $ npm test src/routes/Result/Success.test.js # 测试 Success.test.js
    2. $ npm test src/routes # 测试 routes 下的所有用例文件

    测试 dva 包装组件

    被 dva connect 的 React 组件可以使用下面方式进行测试。

    1. import React from 'react';
    2. import { shallow } from 'enzyme';
    3. import Dashboard from './Dashboard';
    4. it('renders Dashboard', () => {
    5. // 使用包装后的组件
    6. const wrapper = shallow(
    7. <Dashboard.WrappedComponent user={{ list: [] }} />
    8. );
    9. expect(wrapper.find('Table').props().dataSource).toEqual([]);
    10. });

    e2e 测试

    端到端测试也叫冒烟测试,用于测试真实浏览器环境下前端应用的流程和表现,相当于代替人工去操作应用。

    我们引入了 puppeteer 作为 E2E 测试的工具,puppeteer 是 Google Chrome 团队官方的无界面(Headless)Chrome 工具。它默认使用 chrome / chromium 作为浏览器环境运行你的应用,并且提供了非常语义化的 API 来描述业务逻辑。

    写一个 e2e 用例

    假设有一个需求,用户在登录页面输入错误的用户名和密码,点击登录后,出现错误提示框。

    UI 测试  - 图2

    我们写一个用例来保障这个流程。在 src/e2e/ 目录下建一个 Login.e2e.js 文件,按上述业务需求描述测试用例。

    1. import puppeteer from 'puppeteer';
    2. describe('Login', () => {
    3. it('should login with failure', async () => {
    4. const browser = await puppeteer.launch();
    5. const page = await browser.newPage();
    6. await page.type('#userName', 'mockuser');
    7. await page.type('#password', 'wrong_password');
    8. await page.click('button[type="submit"]');
    9. await page.waitForSelector('.ant-alert-error'); // should display error
    10. await page.close();
    11. browser.close();
    12. });
    13. });

    更多 puppeteer 的方法可以参考 puppeteer/docs/api.md。

    运行用例

    运行下列命令将执行 src 下所有的 *.e2e.js 用例文件。

    1. $ npm test .e2e.js

    UI 测试  - 图3

    注意,本地测试 e2e 用例需要启动 npm start,否则会报 Failed: navigation error 的错误。

    watch 模式

    1. $ npm test -- --watch

    添加 --watch 配置可以进入 watch 模式,当你修改和保存文件时,Jest 会自动执行相应用例。Jest 的命令行工具也提供了各种方便的快捷键来执行你需要的用例。

    UI 测试  - 图4

    测试覆盖率

    1. $ npm test -- --coverage

    添加 --coverage 配置可以显示项目的测试覆盖率。

    UI 测试  - 图5

    聚焦和忽略用例

    使用 xit() 取代 it() 可以暂时忽略用例,fit() 可以聚焦当前用例并忽略其他所有用例。这两个方法可以帮助你在开发过程中只关注当前需要的用例。

    接入集成测试服务

    如果需要接入 travis、CircleCI、Gitlab CI 等集成测试环境,可以参考本仓库提供的 .travis.yml

    注意 e2e 测试需要集成环境支持 electron,如果不支持,你可以使用 npm test .test.js 单独运行单元测试。

    参考链接

    更多测试技巧和功能请参考以下链接。

    • create-react-app tests
    • jest
    • enzyme
    • puppeteer
    • Using with puppeteer