4

We're having a discussion at work about Enzyme shallow renders and the time per test to re-run shallow on each test. Be it methods, clicks, selector lengths, etc., I'm suggesting that our tests might run faster if we shallow render the component one time before the tests run versus each time.

Are there any experts who can point out which way would be faster and if there are any pitfalls in either way? These examples are using the AVA runner (and slightly contrived for the sake of discussion).

For example, here's one way (A)...

import TagBox from '../TagBox';
const props = { toggleValue: sinon.spy() };
let wrapper = {};

test.before(t => {
    wrapper = shallow(<TagBox />);
});

test('it should have two children', t => {
    t.is(wrapper.children().length, 2);
});

test('it should safely set props', t => {
    wrapper.setProps({...props});
    t.is(wrapper.children().length, 2);
});

test('it should call when clicked', t => {
    wrapper.setProps({...props});
    wrapper.find({tagX : true}).last().simulate('click');
    t.true(props.toggleValue.calledOnce);
});

And here's the other (B)...

import TagBox from '../TagBox';

test('it sets value to null ...', t => {
    const props = {multiple: false};
    const wrapper = shallow(<TagBox {...props} />);
    t.is(wrapper.state('currentValue'), null);
});

test('it sets value to [] if multiple', t => {
    const props = {multiple: true};
    const wrapper = shallow(<TagBox {...props} />);
    t.deepEqual(wrapper.state('currentValue'), []);
});

test('it does not use value if ...', t => {
    const props = = {value: 3};
    const wrapper = shallow(<TagBox {...props} />);
    t.is(wrapper.state('currentValue'), null);
});

// etc. etc.

Notice that in test B, there is a new shallow wrapper for each test when essentially nothing has changed but props.

Over the course of 100 tests, what would you expect to be the difference in time to completion?

Also is there any chance shallow rendering once (test A) in the higher scope would pollute the test state?

4m1r
  • 12,234
  • 9
  • 46
  • 58

2 Answers2

3

Shallow renderer is designed to be fast, because it renders only single component. So, usually you will not get any performance troubles, when you create new component for each test.

Also, your example A can work incorrectly if TagBox component has inner state. That't why example B is more preferable way to write tests.

just-boris
  • 9,468
  • 5
  • 48
  • 84
1

The shallow is probably not your problem here since it's designed to be the fastest way to render a component without cascading all of it's children renders.

You may consider changing your test running engine then, AVA is kinda slow compared to Jest for example. I did this change a year ago and it is a LOT faster. Jest also provides in it's base kit more useful stuff like mocking functions of example.

More here: https://facebook.github.io/jest/

Gustavo
  • 58
  • 1
  • 6