lsekfe 发表于 2021-8-4 10:10:27

网易云团队前端单元测试技术方案总结(三)


Jest 是 facebook 出的一个完整的单元测试技术方案,集 测试框架, 断言库, 启动器, 快照,沙箱,mock工具于一身,也是 React 官方使用的测试工具。Jest 和 Jasmine 具有非常相似的 API ,所以在 Jasmine 中用到的工具在 Jest 中依然可以很自然地使用。可以近似看作 Jest = JSDOM 启动器 + Jasmine   。
  虽然 Jest 提供了很丰富的功能,但是并没有内置 ES6 支持,所以依然需要根据不同运行时对代码进行转换,由于 Jest 主要运行在 Node 中,所以需要使用 babel-jest 将 ES Module 转换成 CommonJS 。
  Jest 的默认配置:

npm install jest --save-dev
  npx jest --init
  √ Would you like to use Jest when running "test" script in "package.json"? ... yes
  √ Would you like to use Typescript for the configuration file? ... no
  √ Choose the test environment that will be used for testing ? jsdom (browser-like)
  √ Do you want Jest to add coverage reports? ... no
  √ Which provider should be used to instrument code for coverage? ? babel
  √ Automatically clear mock calls and instances between every test? ... yes在 Node 或 JSDOM 下增加 ES6代码的支持
npm install jest-babel @babel/core @babel/preset-env// .babelrc
  {
      "presets": ["@babel/preset-env"]
  } // jest.config.js
  // 下面两行为默认配置,不写也可以
  {
  +    testEnvironment: "jsdom",
  +    transform: {"\\.sx?$": "babel-jest"}
  }使用 Jest 生成测试报告:

 对于 React 和 TypeScript 支持也可以通过修改 babel 的配置解决。
  npm install @babel/preset-react @babel/preset-typescript --save-dev
 // .babrlrc
  {
      "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"]
  } Jest 在真实浏览器环境下测试
  目前 Jest 不支持直接在真实浏览器中进行测试,其默认的启动器只提供了一个 JSDOM 环境,在浏览器中进行单元测试目前只有 Karma 方案能做到,所以也可以使用 Karma + Jest 方案实现,但是不建议这么做,因为 Jest 自身太重,使用 Karma + Jasmine 能达到基本一样的效果。
  另外还有一个比较流行的 E2E 方案 Jest + Puppeteer,由于 E2E不属于单元测试范畴,这里不再展开。
  Jest 工具链总结:
  · Node 环境下测试 : Jest + babel
  · JSDOM 测试 : Jest + babel
  · 真实浏览器测试(不推荐)
  · E2E 测试 : Jest + Puppeteer
  稍作总结
  上面的内容介绍了 chai ,mocha , karma , jasmine 和 jest, 每种工具分别对应一些自己特有的工具链,在选取合适的测试工具时根据实际需要选择, 测试领域还有非常多的工具数都数不过来,下面来看下 React 单元测试的一些方法。
  使用 Jest + Enzyme 对 React 进行单元测试


Enzyme基础配置如下:
npm install enzyme enzyme-adapter-react-16 jest-enzyme jest-environment-enzyme jest-canvas-mock react@16 react-dom@16 --save-dev
 // jest.config.js
  {
  - "testEnvironment": "jsdom",
  +setupFilesAfterEnv: ["jest-enzyme", "jest-canvas-mock"],
  +testEnvironment: "enzyme",
  +testEnvironmentOptions: {
  +    "enzymeAdapter": "react16"
  +},
  }jest-canvas-mock 这个包是为了解决一些使用 JSDOM 未实现行为触发警告的问题。
  上面建立了一个使用 Enzyme 比较友好的环境,可以直接在全局作用域里引用 React , shallow, mount 等 API。此外 Enzyme 还注册了许多友好的断言函数到 Jest 中,如下所示:
toBeChecked()
  toBeDisabled()
  toBeEmptyRender()
  toExist()
  toContainMatchingElement()
  toContainMatchingElements()
  toContainExactlyOneMatchingElement()
  toContainReact()
  toHaveClassName()
  toHaveDisplayName()
  toHaveHTML()
  toHaveProp()
  toHaveRef()
  toHaveState()
  toHaveStyle()
  toHaveTagName()
  toHaveText()
  toIncludeText()
  toHaveValue()
  toMatchElement()
  toMatchSelector()// js/ClassComponent.js
  import React from 'react';
  export default class ClassComponent extends React.PureComponent {
      constructor() {
        super();
        this.state = { name: 'classcomponent' };
      }
      render() {
        return (
              <div>
                  a simple class component
                  <CustomComponent />
              </div>
        );
      }
  }
  // test/hook.test.js
  import HookComponent from '../js/HookComponent';
  describe('HookComponent', () => {
      it ('test with shallow', () => {
        const wrapper = shallow(<HookComponent id={1} />);
        expect(wrapper).toHaveState('name', 'classcomponent');
        expect(wrapper).toIncludeText('a simple class component');
        expect(wrapper).toContainReact(<div>a simple class component</div>);
        expect(wrapper).toContainMatchingElement('CustomComponent');
      })
  })Enzyme 提供了三种渲染组件方法:
  · shallow 使用 react-test-renderer 将组件渲染成内存中的对象, 可以方便进行 props, state 等数据方面的测试,对应的操作对象为 ShallowWrapper,在这种模式下仅能感知到第一层自定义子组件,对于自定义子组件内部结构则无法感知。
  · mount 使用 react-dom 渲染组件,会创建真实 DOM 节点,比 shallow 相比增加了可以使用原生 API 操作 DOM 的能力,对应的操作对象为 ReactWrapper ,这种模式下感知到的是一个完整的 DOM 树。
  · render 使用 react-dom-server 渲染成 html 字符串,基于这份静态文档进行操作,对应的操作对象为 CheerioWrapper。



页: [1]
查看完整版本: 网易云团队前端单元测试技术方案总结(三)