import { Head, Image, Appear } from 'mdx-deck'; import { CodeSurfer } from 'mdx-deck-code-surfer'; export { default as theme } from './theme';
<title>🧩 Front-end Testing 🧩 by Alessia Bellisario</title>Why the pyramid metaphor?
- Mike Cohn, one of the inventors of Scrum, coined it
- He originally drew it in 2003-4 and described it at a scrum gathering in 2004
Coined by Kent C. Dodds
see: https://twitter.com/kentcdodds/status/960723172591992832?lang=en
- Review testing terms
- What is Enzyme?
- Testing implementation details
- React Testing Library vs. Enzyme
- Test runner: runs tests, e.g. Wallaby, Karma, Jest in jest-runner
- Testing framework: organizes tests (in Jest, think:
describe
= suite,it
= spec), e.g. Jest, AVA, Jasmine, Mocha, etc. - Mocking framework: Jest, Sinon.js
- Assertion library: verify code's behaviour, e.g. Jest, AVA, Chai, ShouldJS
...what about Enzyme?
"Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output."
The API revolves around manipulating ReactComponents via the ReactWrapper returned from find() or the React component itself using instance() rather than DOM nodes (what the end user would be interacting with)
<CodeSurfer title="Enzyme" code={require('!raw-loader!./snippets/enzyme.jsx')} steps={[ { notes: 'use ⬆️ and ⬇️ keys' }, { range: [7, 10], notes: 'shallow render' }, { range: [11, 16], notes: 'test props' }, ]} />
see: setProps utility fn provided by Enzyme
@TODO: define shallow vs mount?
<CodeSurfer title="Enzyme: calling react component methods" code={require('!raw-loader!./snippets/implementationDetails.jsx')} />
- will this test break when there’s a mistake that would break the component in production?
- will this test continue to work when there’s a fully backward compatible refactor of the component?
<CodeSurfer title="Enzyme: calling react component methods" code={require('!raw-loader!./snippets/implementationDetailsWComments.jsx')} steps={[ { notes: 'use ⬆️ and ⬇️ keys' }, { lines: [1, 2, 3, 4, 5, 16], notes: '❌' }, { lines: [7, 8, 9, 10, 11, 16], notes: '❌' }, ]} />
Enzyme | React Testing Library |
---|---|
✅ query elements by class name | ❌ |
✅ shallow rendering | ❌ |
✅ get a component instance |
❌ |
✅ get and set a component's props() /state() |
❌ |
❌ | ✅ test real DOM elements |
❌ | ✅ full support for React's Context API |
❌ | ✅ utils for async DOM manipulations |
❌ | ✅ interact with DOM nodes produced by functional components |
❌ | ✅ encourages accessibility: query elements with accessible selectors |
Even with mount
in Enzyme, the API revolves around manipulating ReactComponents via the ReactWrapper returned from find() or the React component itself using instance() rather than DOM nodes (what the end user would be interacting with).
souce: https://medium.com/homeaway-tech-blog/integration-testing-in-react-21f92a55a894
What about accessing DOM nodes via Enzyme?
Returns the outer most DOMComponent of the current wrapper.
- can only be called on a wrapper of a single node.
- will raise if called on a wrapper of a stateless functional component.
DOMComponent
: The retrieved DOM component.
const wrapper = mount(<MyComponent />);
expect(wrapper.getDOMNode()).to.have.property('className');
Soure: Enzyme docs
- Tests will fail if e.g. form not wired up to input correctly
- RTL provides documentation: "Which query should I use?"
- #1 is Queries Accessible to Everyone: queries that reflect the experience of visual/mouse users as well as those that use assistive technology
- RTL allows us to test real DOM elements, not
ReactWrapper
s or React components, to more accurately test the experience of the end user - For this reason it pushes us away from testing implementation details which can give us false positives (tests that fail when we change the implementation) or false negatives (e.g. unit testing component props but a typo breaks the component)
- It also encourages accessibility by providing queries that reflect the experience of visual/mouse users as well as those using assistive technology
- Better developer experience: handling async behaviour is easier and debugging is a breeze compared to Enzyme
- Hooks: Enzyme doesn't play nicely with functional components, so RTL is more future-proof
- Styled Components v4: we're currently prevented from upgrading because of a compatibility issue with Enzyme
🔼 Thanks 🔼