胖蔡
2020年08月15日XUAO测试Javascript,Jest,单元测试,测试80次阅读

Jest 是一个 JavaScript 测试运行器。它允许你使用 jsdom 操作 DOM 。尽管 jsdom 只是对浏览器工作表现的一个近似模拟,对测试 React 组件来说它通常也已经够用了。Jest 有着十分优秀的迭代速度,同时还提供了若干强大的功能,比如它可以模拟 modules 和 timers 让你更精细的控制代码如何执行。Create React App已经集成Jest

配置

保持 create react app 基本配置不变:

  "scripts": {
    "test": "react-app-rewired test --env=jsdom --coverage",
  },

此处多了--coverage,这个命令会打印出当前测试代码的覆盖率,似乎只在配置如下才生效:

  "scripts": {
    "test": "jest --coverage",
  },

运行测试命令,不配置--coverage也是可运行的。
yarn test

安装渲染组件快照模块

测试 CRA 框架下的组件只需要安装react-test-renderer来渲染快照。
yarn add --dev react-test-renderer

测试代码的编写

拿我项目中一个真实的组件来做实例,首先创建一个.jsx组件:

import React, { Component } from 'react'; import LogoMsg from './LogoMsg'; // 多状态组件 // type => loading:加载 empty:无数据 nonet:无网络 404:路由错误 error:其他错误 content:显示子布局 // msg => 错误信息 class Multistate extends Component { constructor(props) { super(props); this.state = {} } render() { var multistate = null; switch (this.props.type) { case "load": case "loading": multistate = (<LogoMsg load msg={this.props.msg || '数据加载中'} />) break; case 'empty': multistate = (<LogoMsg alt="页面空" msg={this.props.msg || '当前页面无数据'} />) break; case "nonet": multistate = this.props.msg || "当前网络异常,请检查网络" break; case "404": multistate = "404 the page is not found."; break; case "error": multistate = (<LogoMsg alt="页面错误" msg={this.props.msg || '存在异常,无法正常访问'} />) break; default: } return (<> { (multistate) ? (<div className={`default-container multistate ${this.props.child ? 'child' : ''}`}> {multistate} </div>) : this.props.children } </>); } } export default Multistate;

这是一个提供页面显示不同状态的布局视图,通过props.type参数控制显示不同的页面内容,似乎路由也能做到,但是架不住我懒。现在用单元测试验证代码逻辑的可行性,创建一个名为Multistate.test.js的文件,Jest会自动寻找.test.js文件执行里面的测试代码。Multistate.test.js编写测试内容:

import React from 'react'; import renderer from 'react-test-renderer'; import Multistate from '../../components/Multistate'; it('Multistate 显示内容', () => { const tree = renderer .create(<Multistate type="content"><div>真正需要的内容</div></Multistate>) .toJSON(); expect(tree).toMatchSnapshot(); }); it('Multistate 显示错误', () => { const tree = renderer .create(<Multistate type="error"><div>真正需要的内容</div></Multistate>) .toJSON(); expect(tree).toMatchSnapshot(); }); it('Multistate 显示空页面', () => { const tree = renderer .create(<Multistate type="empty"><div>真正需要的内容</div></Multistate>) .toJSON(); expect(tree).toMatchSnapshot(); }); it('Multistate 显示加载', () => { const tree = renderer .create(<Multistate type="load"><div>真正需要的内容</div></Multistate>) .toJSON(); expect(tree).toMatchSnapshot(); }); it('Multistate 显示无网络', () => { const tree = renderer .create(<Multistate type="nonet"><div>真正需要的内容</div></Multistate>) .toJSON(); expect(tree).toMatchSnapshot(); }); it('Multistate 显示404', () => { const tree = renderer .create(<Multistate type="404"><div>真正需要的内容</div></Multistate>) .toJSON(); expect(tree).toMatchSnapshot(); }); it('Multistate 什么都不传', () => { const tree = renderer .create(<Multistate><div>真正需要的内容</div></Multistate>) .toJSON(); expect(tree).toMatchSnapshot(); });

共测试7个不同的状态,在控制台运行命令:
yarn test
执行结果如下
执行结果
测试组件时在这里看不出什么问题,我想也许是我的姿势不对,按官方提供的文档来确定,这里应该要出现历史测试比对结果的,但是我一直没有出现。这里有没有没有关系, 测试组件快照时,Jest会在.test.js同目录下创建文件夹__snapshots__,并生成文件Multistate.test.js.snap,文件内容:

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Multistate 什么都不传 1`] = `
<div>
  真正需要的内容
</div>
`;

exports[`Multistate 显示404 1`] = `
<div
  className="default-container multistate "
>
  404 the page is not found.
</div>
`;

exports[`Multistate 显示内容 1`] = `
<div>
  真正需要的内容
</div>
`;

exports[`Multistate 显示加载 1`] = `
<div
  className="default-container multistate "
>
  <div
    className="vertical-layout center empty-container"
  >
    <svg
      className="am-icon am-icon-loading am-icon-lg"
      color="#06BB06"
    >
      <use
        xlinkHref="#loading"
      />
    </svg>
    <div
      style={
        Object {
          "marginTop": "10px",
        }
      }
    >
      数据加载中
    </div>
  </div>
</div>
`;

exports[`Multistate 显示无网络 1`] = `
<div
  className="default-container multistate "
>
  当前网络异常,请检查网络
</div>
`;

exports[`Multistate 显示空页面 1`] = `
<div
  className="default-container multistate "
>
  <div
    className="vertical-layout center empty-container"
  >
    <img
      alt="页面空"
      src="empty.png"
      style={
        Object {
          "height": "139.5px",
          "marginBottom": "10px",
          "width": "168px",
        }
      }
    />
    <div
      style={
        Object {
          "marginTop": "10px",
        }
      }
    >
      当前页面无数据
    </div>
  </div>
</div>
`;

exports[`Multistate 显示错误 1`] = `
<div
  className="default-container multistate "
>
  <div
    className="vertical-layout center empty-container"
  >
    <img
      alt="页面错误"
      src="empty.png"
      style={
        Object {
          "height": "139.5px",
          "marginBottom": "10px",
          "width": "168px",
        }
      }
    />
    <div
      style={
        Object {
          "marginTop": "10px",
        }
      }
    >
      存在异常,无法正常访问
    </div>
  </div>
</div>
`;

Jest会把dom信息保存到Multistate.test.js.snap文件中,从这里可以直观的查看到每种测试结果,发现问题即修改。如果需要删除Multistate.test.js.snap文件信息重新测试只需要在控制台输入命令:yarn test -u 即可。

Would you like to know more?