跳到主要内容

Jest 22: Refinements & Custom Runners

· 阅读需 8 分钟

Today we are announcing a new major version of Jest which refines almost all parts of Jest to provide a more solid testing foundation. Together with the Jest community we made a number of changes across the board that will help you get more out of Jest. We are also graduating the custom runners feature out of the experimental stage and added a new package, jest-worker, for parallelizing work across multiple processes. We have compiled a list of highlights below but make sure to check out the (as always) massive changelog.

Good bye Node 4 & welcome JSDOM 11

With this release we are dropping support for Node 4, mainly because one of our main dependencies, JSDOM, ended their support. Jest now comes out of the box with JSDOM 11 which features better support for SVGs, requestAnimationFrame, URL and URLSearchParams built in, and much more.

Custom Runners + Easy parallelization with jest-worker

In Jest 21 we introduced the concept of custom Jest runners. Since then, Rogelio, one of Jest's core contributors, built a number of useful runners: If you have many existing tests written using another framework but you'd like to immediately benefit from Jest's features, check out jest-runner-mocha. If you have a large codebase that needs linting, you may get a significant speedup if you run eslint within Jest using jest-runner-eslint.

To gain more of fine-grained control over heavy tasks parallelization (e.g. transforming files or crawling the file system), we designed a new library perfectly suited for the job. We developed a modern, Promise-based module with an approachable API, called jest-worker, that allows you to delegate to child processes those intensive functions. As jest-worker, like any other Jest package, is a part of the Jest platform, you can use it however you like even without ever using Jest itself. You'll find more in the documentation here.

To get a better understanding of custom runners and Jest as a platform, make sure to check out Rogelio's talk from Reactive Conf 2017: Jest as a Platform.

Codeframe in test failures

In order to more easily identify which assertion is failing your test, we've added a code frame showing the context where the assertion is in order to focus on your own code. See the following example test:

test('some test', () => {
function someFunctionWhichShouldThrow() {
if (false) {
throw new Error();
}

return 'success!';
}

expect(someFunctionWhichShouldThrow).toThrow();
});

In Jest 21, we would display the following error:

failure in Jest 21

In Jest 22, we have added a codeframe, giving more context to the failing assertions. We have also cleaned up the stack trace to remove more clutter than ever.

failure in Jest 22

Easier testing of errors thrown in async code

You can now use toThrow and toThrowErrorMatchingSnapshot on promise rejections in the same way you can on synchronous errors.

async function throwingFunction() {
throw new Error('This failed');
}

test('asynchronous rejection', async () => {
await expect(throwingFunction()).rejects.toThrowErrorMatchingSnapshot();
});

Asynchronous test environments

When Puppeteer, a way of programmatically interacting with a real Chromium Browser, was announced by the Google Chrome team in August, many wanted to be able to use Jest to write their tests running them in Chrome. The community have helped us out making this possible by allowing asynchronous test environments. We are still working on making this experience as good as possible, but please see this guide for how to use Puppeteer with Jest, starting today.

Experimental Leak Detection

We added an experimental --detectLeaks setting to Jest that will let you know if your internal environment instance is leaked after a test execution. It will also warn you when your test suite tries to require a file after the test has finished, meaning you forgot to wait for all async operations or left something not properly cleaned. This will however not discover leaks in user land code, only in test land code; although the technology used behind it can help you (see jest-leak-detector). If you are reporting a bug about Jest's memory usage, please provide a repro where --detectLeaks will make the test suite fail. We started building a better sandboxing mechanism for Jest but it's not ready yet to be enabled by default. If you'd like to help, please reach out to us on discord!

Watch Mode Refinements

When using watch mode, there is now a way to focus only on tests that previously failed. In this mode, Jest will not re-run previously passing tests which should help you iron out all test failures. Additionally, we added a plugin system to watch mode. By adding modules to watchPlugins in your configuration you can extend the features of the watch mode.

Babel 7 support

Jest uses Babel under the hood to power code coverage and advanced mocking features. With Jest 22, it also supports the upcoming Babel 7. You'll find more in the documentation here.

Mock function improvements

There has been a couple of changes to mock functions in Jest 22, making them even easier to use. Firstly, we added a mockName property allowing you to name your mocks, which is useful in assertion failures. We have also made the Jest mock function serializable in pretty-format, meaning that you can snapshot test mocks. In Jest 21, expect(jest.fn()).toMatchSnapshot() would serialize to [Function], in Jest 22, you might get something like this:

test('my mocking test', () => {
const mock = jest.fn().mockName('myMock');

mock('hello', {foo: 'bar'});

expect(mock).toMatchSnapshot();
});

// Serializes to:

exports[`my mocking test 1`] = `
[MockFunction myMock] {
"calls": Array [
Array [
"hello",
Object {
"foo": "bar",
},
],
],
}
`;

Highlights from Jest 21

Jest 21 was released back in September, and we unfortunately never got around to write a blog post. So here is a quick summary of the main changes in version 21:

  1. Use expect and jest-mock in the browser: Michael Jackson donated his excellent expect package to the Jest project. As part of that transition, the Jest core team, with much help from Kenneth Skovhus, made both jest-matchers (renamed to expect) and jest-mock work in browsers. This means that while you cannot use Jest itself in browsers (yet), you can use its awesome assertions and mocks for instance as replacements for Chai and Sinon running in Mocha tests. If you are migrating from earlier expect to the new Jest-powered expect, you can use jest-codemods to automate the migration.
  2. MIT License: We changed Jest's license to MIT. Yay!
  3. Fail test suites on async errors: Jest used to have a bug that made it crash when errors were thrown in certain parts of async code. This was fixed by community contributors.
  4. Faster startup: With Jest 21 we fine tuned Jest's startup to be more than 50% faster. The large overhead of Jest when running it on a small and fast test was always an issue for us and now this shouldn't be a reason to hold you back from using Jest any longer.

Jest Community

The community around Jest is working hard to make the testing experience even greater. These are separate projects from the main Jest project, but we want to highlight some of our personal favorites here.

  • jest-image-snapshot – custom matcher to compare images with snapshots by American Express developers
  • ts-jest – all you need to successfully run Jest within TypeScript project by @kulshekhar
  • jest-codemods – migrate your tests from other frameworks to Jest with ease
  • jest-plugins – a new community project oriented around simplifying setting up test environment for specific tools, like React, or providing some handy utilities

We'd also like to announce that recently we launched a new place for high quality Jest additions – jest-community. It's a new GitHub organization already featuring our favorite projects, like vscode-jest, jest-extended, to name a few, curated by Jest maintainers and collaborators. We've even migrated our eslint-plugin-jest there, and already see some great contributions, which are published independently at a faster pace.

Jest Community

Community projects under one organisation are also a great way for us to experiment on things like automated releases, which we'd like to explore for Jest as well. They also enable us to share some common things between them, like the shape of the README for example (thanks to the webpack Community for the idea), making it easier to learn and use for all of us.

If you have something awesome to share, feel free to reach out to us! We'd love to share your project here.