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

发表于:2021-7-30 10:27

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:江水    来源:掘金

分享:
  JEST
  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: {"\\.[jt]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。

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号