Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest - Snapshot Testing入门笔记 #27

Open
jerryni opened this issue Jun 1, 2018 · 1 comment
Open

Jest - Snapshot Testing入门笔记 #27

jerryni opened this issue Jun 1, 2018 · 1 comment

Comments

@jerryni
Copy link
Owner

jerryni commented Jun 1, 2018

hello world

在线 demo: https://github.com/facebook/jest.git

  • jest: yarn;
  • jest/examples/snapshot :1. yarn; 2. yarn test;

jest/examples/snapshot里的目录结构:

├── Clock.react.js
├── Link.react.js
├── __tests__
│   ├── __snapshots__
│   │   ├── clock.react.test.js.snap
│   │   └── link.react.test.js.snap
│   ├── clock.react.test.js
│   └── link.react.test.js
├── node_modules
└── package.json

实例

运行下面的测试代码:

import React from 'react';
import Link from '../Link.react';
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer
    .create(<Link page="http://www.facebook.com">Facebook</Link>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

将生成如下的snapshot文件:

exports[`renders correctly 1`] = `
<a
  className="normal"
  href="http://www.facebook.com"
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
>
  Facebook
</a>
`;
  • 这个snapshot文件应该被commit上来,放在代码旁边,也作为review的一部分;本身可读性很强;
  • 在后面的测试过程中,就是对比新生成的snapshot和老的snapshot; 如果一样就pass,否则就报错;你必须修复这个bug或者,如果你的实现改了,那么你就要更新这个snapshot;
  • 更新所有失败的snapshot test:jest --updateSnapshot或简写 jest -u; 可以通过jest --testNamePattern=<regex>;指定匹配模块; 如jest -t=anchor.*page, anchor.*page可以匹配到'renders as an anchor when no page is set'这个模块;
  • 交互模式: 在jest —watch模式下,输入 i,可以进入交互模式;
  • 动态的数据,比如 new Date(),由于每次的值都不一样,所以需要进行修正 ; 可以如下修复:
it('will check the matchers and pass', () => {
  const user = {
    createdAt: new Date(),
    id: Math.floor(Math.random() * 20),
    name: 'LeBron James',
  };

  expect(user).toMatchSnapshot({
    createdAt: expect.any(Date),
    id: expect.any(Number),
  });
});

最佳实践

  • 把snapshot当成代码对待
  • 每次生成的截图最好都一样,比如有Date.now()的方法,如果要让它一样,那么可以通过重写方法Date.now = jest.fn(() => 1482363367071);
  • 测试名称命名方式最好跟结果有关联,这样出错的时候就可以看得更清楚:
exports[`<UserName /> should render null`] = `null`;

exports[`<UserName /> should render Alan Turing`] = `
<div>
  Alan Turing
</div>

后续参考资料

基础:Snapshot Testing · Jest
由来:Jest 14.0: React Tree Snapshot Testing · Jest
初印象:https://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/
视频推荐:Use Jest’s Snapshot Testing Feature from @kentcdodds on @eggheadio

@jerryni
Copy link
Owner Author

jerryni commented Nov 7, 2018

一个实战的内部组件库配置参考和说明

module.exports = {
  'moduleFileExtensions': [
    'js',
    'vue'
  ],
  'moduleDirectories': [
    'node_modules',
    'packages'
  ],
  'moduleNameMapper': { // 相当于webpack里的alias
    '^packages/(.*)$': '<rootDir>/packages/$1',
    '^docs/(.*)$': '<rootDir>/docs/examples-docs/$1',
    '^examples-dist/(.*)$': '<rootDir>/docs/examples-dist/$1',
    '^test/(.*)$': '<rootDir>/test/$1'
  },
  'transform': { // 相当于webpack里的loader
    '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
    '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css'
  },
  'transformIgnorePatterns': [ // 不转化的东西,这里可以排除掉转化的库,比如vant
    '/node_modules/(?!vant)'
  ],
  'snapshotSerializers': [
    '<rootDir>/node_modules/jest-serializer-vue'
  ],
  'collectCoverageFrom': [ // 代码覆盖率考虑的文件
    'packages/**/*.{js,vue}',
    '!**/lib/**',
    '!**/ajax/**'
  ],
  'coverageDirectory': 'test/unit/coverage'
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant