I am just starting with Jest and Snapshot testing and I was wondering why all examples do "deep rendering" of React components to create snapshots.
Example
const A = () => {
return <div><B /><B /></div>
}
const B = () => {
return <div>This is B</div>
}
// TEST
describe('Test', () => {
it('renders correctly', () => {
const tree = ReactTestRenderer.create(
<A />
).toJSON();
expect(tree).toMatchSnapshot();
});
});
Snapshot:
exports[`Summary DOM rendering renders correctly 1`] = `
<div>
<div>
This is B
</div>
<div>
This is B
</div>
</div>
`;
While this is useful sometimes I think it makes far more sense to have separate tests/snapshots for A and B and to do shallow rendering so if I change B my A snapshots do not need to be updated. So I want my snapshots to look like this:
exports[`Summary DOM rendering renders correctly 1`] = `
<div>
<B />
<B />
</div>
`;
Is there any way to do this? Is this a good idea in the first place? If it is possible why is shallow rendering not the preferred way in the docs?
Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly. A typical snapshot test case renders a UI component, takes a snapshot, then compares it to a reference snapshot file stored alongside the test.
To review your snapshots, run npm run jest-html ( yarn run jest-html ). This launches your default browser and opens the jest-html application. By default, jest-html looks for snapshots under **/*. snap,!
If you test a component using shallow rendering you're not guaranteeing that the component is actually rendering correctly e.g. if any child components are broken, it won't cause the test to fail.
Update(Jan 3, 2018)
Shallowrender has been moved to react-test-renderer
import ShallowRenderer from 'react-test-renderer/shallow'
it('Matches snapshot', () => {
const renderer = new ShallowRenderer()
const result = renderer.render(<A />)
expect(result).toMatchSnapshot()
})
You can use react-test-utils
Shallow Rendering with snapshot testing as well:
import ReactTestUtils from 'react-addons-test-utils';
describe('Test', () => {
it('renders correctly', () => {
const renderer = ReactTestUtils.createRenderer();
expect(renderer.render(<A />)).toMatchSnapshot();
});
});
With that you can create renderer that only renders 1 level deep, that is: it'll only render what's in your component's render()
function, and not render child components.
react-test-renderer
is a different renderer, it renders your component (and the whole tree) to JSON. Currently it has no option to shallow render, it will work just like in the browser and render everything, but to JSON.
They both are good for testing because they don't require a DOM environment and they have different characteristics. You can choose one that suits better your use case.
You can use enzyme to shallow-render your components.
I can't tell you for sure as to why it's not the preferred method in the docs, but my guess would be that it's because the functionality isn't built into the official react-test-renderer
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With