React-virtualized: Migrate to Jest (mostly)

Created on 15 Jan 2017  Â·  8Comments  Â·  Source: bvaughn/react-virtualized

  • Karma + Jasmine + PhantomJS is slow.
  • PhantomJS is unstable. (CI has been failing since b5b8e29 due to PhantomJS crashing in the middle of tests; I am unable to reproduce this behavior locally.)
    Jasmine

I'd love to migrate the whole project to Jest because it's much faster. Unfortunately a couple of components (AutoSizer and CellMeasurer) depend on a more robust browser than JSDOM and currently that's all that Jest supports.

So my proposal for now:

  • Split NPM test:unit script into 2 child tasks: test:unit:jasmine and test:unit:jest
  • Rename all tests that can be run in Jest from *.test.js to *.jest.js
cleanup

Most helpful comment

On a related note, this seems to work for anyone who needs to mock out AutoSizer for snapshot testing:

// __mocks__/react-virtualized.js
import React from 'react';

const reactVirtualized = jest.genMockFromModule('react-virtualized');

const MockAutoSizer = () => {
  return <div />;
};

reactVirtualized.AutoSizer = MockAutoSizer;

module.exports = reactVirtualized;

Then at the top of your test file, do:
jest.mock('react-virtualized');

Update: This doesn't seem to render out the children. I've created a Gist where I'll keep working to find an ideal solution: https://gist.github.com/elevine/69a27e067032c53d64d66f4f56e978cc

All 8 comments

On a related note, this seems to work for anyone who needs to mock out AutoSizer for snapshot testing:

// __mocks__/react-virtualized.js
import React from 'react';

const reactVirtualized = jest.genMockFromModule('react-virtualized');

const MockAutoSizer = () => {
  return <div />;
};

reactVirtualized.AutoSizer = MockAutoSizer;

module.exports = reactVirtualized;

Then at the top of your test file, do:
jest.mock('react-virtualized');

Update: This doesn't seem to render out the children. I've created a Gist where I'll keep working to find an ideal solution: https://gist.github.com/elevine/69a27e067032c53d64d66f4f56e978cc

Thanks for sharing that approach @elevine. 😄 My suggestion for _testing_ RV components in an external project is actually to structure your code like so:

components/MyComponent.js
import React, { PropTypes } from 'react';
import { AutoSizer } from 'react-virtualized';

// Production code uses this for convenience.
export function MyComponent (props) {
  return (
    <AutoSizer>
      {({ width, height }) => (
        <MyComponentImpl
          {...props}
          height={height}
          width={width}
        />
      )}
    </AutoSizer>
  );
}
export default MyComponent;

// Test code imports this and injects explicit size props.
export function MyComponentImpl (props) {
  // Your render logic...
}
MyComponentImpl.propTypes = {
  height: PropTypes.number.isRequired,
  width: PropTypes.number.isRequired
};
components/MyComponent.testjs.js
import { MyComponentImpl } from './MyComponent'

// Inject explicit size props for easier testing
<MyComponentImpl
  {...yourTestProps}
  height={200}
  width={400}
/>

Thank you @bvaughn ! That totally makes sense.

One concept I'm struggling with though is how would you apply that approach as you get higher up in your app's hierarchy. For example, let's say I have a modal with a search input and a list of results that is structured like this:

<MySearchModal>
  <MyModal>
    <MySearchComponent>
      <MySearchBox />
      <MySearchResultsList>
        <AutoSizer>
          <List />
        </AutoSizer>
      </MySearchResultsList>
    </MySearchComponent>  
  </MyModal>
</MySearchModal>

One thought I have is that you can apply your approach to testing MySearchResultsList and use Jest mocking to handle RV components while testing MySearchModal. This way you get coverage for everything. I'd love to hear your input though.

You could use Jest to mock the component (swap the auto-sized with manually sized).

I've also, occasionally, used props like heightForTest and widthForTest and used those _instead of_ the AutoSizer values if present. That's kind of a hack though.

@bvaughn Thanks for all your work!

Jest because it's much faster

Unless I'm missing something, the build now takes around 4 min while it was taking 3 min before.
From my experience at @doctolib jest runs about 7 tests/minutes while mocha + karma handles 21 tests/minutes. I don't understand that performance argument, I guess the value come from somewhere else. Please enlighten me 💡 .

I'd love to learn more about your benchmarking experience with Jest and Mocha. Jest's running of tests in parallel is much faster in my anecdotal experience (within this project).

More to your point though, build times were never a concern for me with this project. Iterating on tests (running in watch mode) was. Jest is _much_ more responsive for the use-case. I'd like to eventually migrate everything to use Jest but...I'm stuck with a few tests in PhantomJS because of lack of certain JSDom layout features.

I'd love to learn more about

We have around 1800+ tests, we have tried to migrate to Jest, but that was way too slow.
We reverted to our Mocha + Karma + PhantomJS test suite.

Iterating on tests (running in watch mode) was.

I guess that's what I was looking for! We haven't looked at the iterating response time.
That point needs more investigation from my part. Thanks.

No problem. That's interesting to learn! I'm not using Mocha so that may
also account for some of the difference in our impressions.

I've been really impressed by Jest's mocking and snapshot functionalities.
I hope to take advantage of both going forward.

Also worth pointing out that PhantomJS has been crashing for me in CI
environment for weeks. Could not reproduce locally. Overall seemed very
flaky. Despite its limitations, JSDom seems more robust.

Given its limitations for that matter- I'm surprised you would see faster
results from Mocha+PhantomJS than from Jest+JSDom just because of the
browsers alone.

Oh well. :grin: Glad you started this conversation either way. It's
interesting.

On Jan 28, 2017 1:04 PM, "Olivier Tassinari" notifications@github.com
wrote:

I'd love to learn more about

We have around 1800+ tests, we have tried to migrate to jest, but that was
way too slow.
We reverted to our Mocha + Karma + PhantomJS test suite.

Iterating on tests (running in watch mode) was.

I guess that's what I was looking for! We haven't looked at the iterating
response time.
That need more investigation from my part. Thanks.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/bvaughn/react-virtualized/issues/539#issuecomment-275874551,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AABznXTzSvMTfwlnvOIx98-fI5wroIfqks5rW61kgaJpZM4Lj-Jm
.

Was this page helpful?
0 / 5 - 0 ratings