前端组件单选测试Jest + Enzyme

技术选型:Jest + Enzyme

Jest

www.jestjs.cn

Jest是Facebook开源的一个前端测试框架,主要用于React和React Native的单元测试,已被集成在create-react-app中。Jest特点:

  1. 易用性:基于Jasmine,提供断言库,支持多种测试风格

  2. 适应性:Jest是模块化、可扩展和可配置的

  3. 沙箱和快照:Jest内置了JSDOM,能够模拟浏览器环境,并且并行执行

  4. 快照测试:Jest能够对React组件树进行序列化,生成对应的字符串快照,通过比较字符串提供高性能的UI检测

  5. Mock系统:Jest实现了一个强大的Mock系统,支持自动和手动mock

  6. 支持异步代码测试:支持Promise和async/await

  7. 自动生成静态分析结果:内置Istanbul,测试代码覆盖率,并生成对应的报告

下面是一个使用Jest进行单元测试的例子:

javascript 复制代码
// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

// sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

Enzyme

enzymejs.github.io/enzyme/

Enzyme是Airbnb开源的React测试工具库库,它功能过对官方的测试工具库ReactTestUtils的二次封装,提供了一套简洁强大的 API,并内置Cheerio,实现了jQuery风格的方式进行DOM 处理,开发体验十分友好。在开源社区有超高人气,同时也获得了React 官方的推荐。

下面是一个使用Enzyme进行单元测试的例子:

javascript 复制代码
import React from 'react';
import { shallow } from 'enzyme';
import MyComponent from './MyComponent';

describe('MyComponent', () => {
  it('renders correctly', () => {
    const wrapper = shallow(<MyComponent />);
    expect(wrapper).toMatchSnapshot();
  });

  it('increments the count when the button is clicked', () => {
    const wrapper = shallow(<MyComponent />);
    const button = wrapper.find('button');
    button.simulate('click');
    expect(wrapper.state('count')).toEqual(1);
  });
});

约定

推荐按照业界通用实践的规范,我们有如下约定:

  • 单元测试的代码放置在 tests 目录下
  • 单元测试文件命名格式使用 xxx.test.ts

相关配置

在项目根目录下创建jest.config.js文件,参数说明可以参考:jestjs.io/docs/en/con...

javascript 复制代码
module.exports = {
  // 块名称的映射关系
  moduleNameMapper: {
    '^#src/(.*)$': '<rootDir>/src/$1',
    '^@tencent/uno-ui': '<rootDir>/../../node_modules/@tencent/uno-ui-v2',
  },
  // 指定哪些文件不需要被收集代码覆盖率
  coveragePathIgnorePatterns: [
    '<rootDir>/.storybook/',
    '<rootDir>/.bin/',
    '<rootDir>/.build/',
    '<rootDir>/.build-docs/',
  ],
  // 指定需要收集代码覆盖率的文件
  collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
  // 指定在运行测试之前需要执行的脚本文件
  setupFilesAfterEnv: ['<rootDir>/src/test/setupTests.ts'],
  // 测试环境
  testEnvironment: 'jsdom',
  // 指定模块解析器,这里指定了一个自定义的解析器用于解决uuid库报错的问题
  resolver: `${__dirname}/src/test/resolver.js`,
};

遇到的问题

因为uuid只提供ESM浏览器导出,而不提供CommonJS导出出现了下面的报错,详情见下面的git链接
github.com/uuidjs/uuid...

javascript 复制代码
  /jest-bug/node_modules/uuid/dist/esm-browser/index.js:1
   ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as v1 } from './v1.js';
                                                                                     ^^^^^^

   SyntaxError: Unexpected token 'export'

   > 1 | import { v4 } from "uuid";
       | ^
     2 | import { nanoid } from "nanoid";
     3 |
     4 | export function getUuid() {

     at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1773:14)

解决办法

github.com/jestjs/jest...
github.com/microsoft/a...

javascript 复制代码
// https://github.com/jestjs/jest/issues/12770
// https://github.com/microsoft/accessibility-insights-web/pull/5421/commits/9ad4e618019298d82732d49d00aafb846fb6bac7
module.exports = (path, options) =>
  // Call the defaultResolver, so we leverage its cache, error handling, etc.
  options.defaultResolver(path, {
    ...options,
    // Use packageFilter to process parsed `package.json` before the resolution (see https://www.npmjs.com/package/resolve#resolveid-opts-cb)
    packageFilter: (pkg) => {
      // This is a workaround for https://github.com/uuidjs/uuid/pull/616
      //
      // jest-environment-jsdom 28+ tries to use browser exports instead of default exports,
      // but uuid only offers an ESM browser export and not a CommonJS one. Jest does not yet
      // support ESM modules natively, so this causes a Jest error related to trying to parse
      // "export" syntax.
      //
      // This workaround prevents Jest from considering uuid's module-based exports at all;
      // it falls back to uuid's CommonJS+node "main" property.
      //
      // Once we're able to migrate our Jest config to ESM and a browser crypto
      // implementation is available for the browser+ESM version of uuid to use (eg, via
      // https://github.com/jsdom/jsdom/pull/3352 or a similar polyfill), this can go away.
      if (pkg.name === 'uuid') {
        delete pkg.exports;
        delete pkg.module;
      }
      return pkg;
    },
  });

相关框架

ts-jest 是 Jest 的 TypeScript 预处理器。

@types/jest 和 @jest/types 是 Jest 的类型声明文件。

jest-environment-jsdom 是 Jest 的一个测试环境,用于在 Node.js 中模拟浏览器环境。

babel-jest 是 Jest 的一个预处理器,用于处理 ES6+ 语法。

enzyme 是一个流行的 React 组件测试工具。

enzyme-adapter-react-16 是适用于 React 16 版本的 Enzyme 适配器。

@types/enzyme 和 @types/enzyme-adapter-react-16 是 Enzyme 的类型声明文件

相关推荐
耶啵奶膘1 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^3 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie4 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic4 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿4 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具5 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
清灵xmf5 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据5 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161775 小时前
防抖函数--应用场景及示例
前端·javascript
334554326 小时前
element动态表头合并表格
开发语言·javascript·ecmascript