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

Switch to Jest #635

Merged
merged 42 commits into from Mar 16, 2017
Merged

Switch to Jest #635

merged 42 commits into from Mar 16, 2017

Conversation

evocateur
Copy link
Member

Jest rocks my socks. It's faster than mocha+nyc, and more accurate in its coverage report.

The --watch mode is a legit dream. (yarn test -- --watch)

Non-scientific comparisons:

mocha jest
yarn test 15s 7s
yarn run coverage 20s 8s

image

You'll notice files we've completely forgotten to cover, which are entirely absent from the nyc output. Have I mentioned it's fast? 🚀

@evocateur
Copy link
Member Author

evocateur commented Mar 2, 2017

CI all failed for a variety of reasons 😭

@evocateur evocateur added the WIP label Mar 2, 2017
@spudly
Copy link
Contributor

spudly commented Mar 2, 2017

+1 on this. When my team switched from AVA to jest our test execution time for a single (large) package went from 5 minutes to 7 seconds.

@bcoe
Copy link
Contributor

bcoe commented Mar 11, 2017

@evocateur this sounds great. Jest uses the same underlying instrumentation logic as nyc, but doesn't rely on source-maps (we've never quite hammered all the kinks out of the source-maps in babel codebases).

@evocateur
Copy link
Member Author

@bcoe Indeed! I'm a big fan of nyc and its underlying utilities.

appveyor.yml Outdated
@@ -23,7 +23,7 @@ test_script:
- node --version
- npm --version
- yarn --version
- yarn run ci
- yarn run ci -- --runInBand
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, the Windows builds have all sorts of impossible-to-debug race conditions with the filesystem operations (fixture copy, etc). With it, it runs super fast (relative to "normal" multi-process Jest runs on Windows).

@@ -1,11 +1,12 @@
#!/usr/bin/env node
"use strict";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got tired of my editor yelling at me with lint errors whenever I opened this file. Easy enough to start linting it automatically, as we no longer support node < v4.

"ci": "npm run lint && npm run test",
"lint": "eslint . --ignore-path .gitignore",
"fix": "npm run lint -- --fix",
"pretest": "npm run lint -- --cache",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty big. Contributors that run tests locally shouldn't have to remember to also yarn run lint to avoid silly lint errors breaking their PR builds.

@@ -51,6 +53,7 @@
"devDependencies": {
"babel-cli": "^6.7.5",
"babel-eslint": "^6.0.2",
"babel-jest": "^19.0.0",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we're using yarn in CI, this is less important. Without it, however, npm 2 (the default for node v4) would fail to run tests because babel-jest wasn't a sibling of jest.

"src/**/*.js"
],
"modulePathIgnorePatterns": [
"<rootDir>/test/fixtures"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jest does aggressive pre-caching of package.json files, apparently, and this was seriously harshing the mellow of a CI process when booting up the tests. So we ignore it. 😎

@@ -21,7 +21,7 @@ export default class FileSystemUtilities {

@logger.logifyAsync()
static mkdirp(filePath, callback) {
mkdirp(filePath, callback);
mkdirp(filePath, { fs }, callback);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing graceful-fs to mkdirp is an effort to minimize race conditions when conducting tons of parallel filesystem operations.

(These were especially noticeable because jest by default tries to run as many tests in parallel processes as possible)

@@ -38,7 +38,7 @@ export default class ImportCommand extends Command {
this.targetDir = path.join(targetBase, externalRepoBase);

try {
if (fs.statSync(this.targetDir)) {
if (FileSystemUtilities.existsSync(this.targetDir)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This didn't need to be a statSync since the result was never used.

@@ -35,7 +35,7 @@ describe("BootstrapCommand", () => {
bootstrapCommand.runPreparations();

bootstrapCommand.runCommand(exitWithCode(0, (err) => {
if (err) return done(err);
if (err) return done.fail(err);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently Jasmine uses this pattern, contra Mocha.

let externalDir;

beforeEach(() =>
Promise.resolve()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This started out as a parallel Promise.all(), but the synchronous process.chdir() inside initFixture()'s promise chain made that non-deterministic, hence the ordering.

describe("public API", () => {
let testDir;

beforeEach(() => initFixture("PackageUtilities/basic").then((dir) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixture used to be initialized for every test in this file, despite over half of them doing another fixture init (for filtering) and ignoring this. Seemed wasteful.

@cpojer
Copy link
Contributor

cpojer commented Mar 17, 2017

Hey, wow, thanks for doing this.

@evocateur
Copy link
Member Author

evocateur commented Mar 17, 2017 via email

@JaKXz
Copy link

JaKXz commented Apr 7, 2017

@evocateur this is great, well done! I'm curious about one statement though:

more accurate in its coverage report [than nyc + mocha]

AFAIK jest uses a lot of istanbul's libs under the hood for collecting coverage information, especially babel-plugin-istanbul. Could you expand / provide examples on how it's more accurate, and I'm hoping that will help us make nyc more accurate :) thanks!

e.g. for files that are not required in tests, you would use nyc's --all flag to see them included in the coverage report. I agree our documentation leaves something to be desired which I am dedicating cycles to improve ATM so your feedback here would definitely help make my work more effective 😄

@evocateur
Copy link
Member Author

@JaKXz Indeed, jest does use istanbul's libs! I didn't mean to disparage nyc at all, but I do recall significant differences in the coverage display, even without --all (or jest's equivalent).

When I spoke to @bcoe about this disparity, I recall he said something about the source maps were causing problems with dynamically-transpiled ES6, or something to that effect. It was a few weeks ago, and I can't remember offhand where the thread was.

More than anything, I think the jest transition yielded more accurate coverage reporting because we are no longer hacking babel-register into mocha, and benefitting from jest's "batteries-included" approach.

@bcoe
Copy link
Contributor

bcoe commented Apr 7, 2017

@evocateur @JaKXz would love to get to the bottom of the source-map discrepancy; @JaKXz we shoudl make an effort to capture discrepancies when possible, and start to get some failing tests in place on nyc.

@lock
Copy link

lock bot commented Dec 27, 2018

This thread has been automatically locked because there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Dec 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants