Jest and Enzyme
Jest and Enzyme are pretty cool! Frontend unit testing for React App!
They are frontend testing tools that allow you to test and assert DOM elements, simulate user actions in unit testing, which I once thought could only be done in end to end testing using Selenium! Jest/Enzyme and Selenium can certainly compliment each other to provide reliable, efficient automated frontend testing!
What is Jest? Enzyme?
Jest is a general purpose unit testing framework which provides test runners, assertion library, spies, mocks, coverage. A pretty comprehensive all-in-one testing framework which is kind of equivalent to Mocha (test runner) + Chai (assertion library) + Sinon (spies, mocks) + Istanbul (coverage).
Having been developed by Facebook, Jest works well with React App although it also works for other apps. I personally have only tried Snapshot testing on React App so it will be interesting to find out how Snapshot testing works on apps of other tech stack.
Enzyme is a testing utility for React Apps developed by Airbnb. It provides API wrappers that makes it easier to assert, manipulate, and traverse your React Components’ DOM. Enzyme can work with any testing framework, such as Jest or Mocha.
3 Types of Rendering
Jest and Enzyme both provide APIs for rendering the React components. There are 3 different types of rendering: shallow, mount and render.
Shallow: Renders only the current component. It is useful in isolating testing to the current component and not testing/ asserting the children component nested within.
Mount: Renders the full component in JSDom (a headless browser) and useful when full lifecycle is required to fully test the component.
Render: Renders the component into full HTML. Snapshot testing by default is rendered into static HTML.
For all 3 type of rendering, the utilities dependent on by the component all need to be mocked, even in Shallow rendering.
Snapshot Testing
I found snapshot testing the most eye-catching feature of Jest. It allows you to save a HTML DOM snapshot of the React component in the first run. All the subsequent test runs will be comparing the subsequent snapshots with this first snapshot to determine whether there has been any DOM (UI) changes in the component.
One of the trickiest part in getting started is Jest mocking. How to mock dependent utilities?
Scenario1 :A component that depends on SettingsUtil to make Ajax GET/POST calls
Scenario2: A component that contains children elements imported from a 3rd party library, React-bootstrap-table.
Jest.mock
could be used in both scenarios. Notice that the mocked utils need to appear before the import of the component (Selfreflection)!! It returns either a function or an object, which will be consumed when rendering Selfreflection.
Watch Out..
I learn by example. I love learning technologies and tools with good documentations, resources and LOTS of examples. There are many ‘Hello World’ snapshot testing examples on the net, but not many comprehensive, detailed examples that teach you how to test/ mock for typical apps that we build. The Jest documentation explains the basics but can be further improved…
Snapshot update by jest -u
or npm test — -u
(if you set npm test
to jest)
. It updates ALL snapshots! no update to individual snapshot as at 2017 March 10. Be careful when you update snapshots as it may give you false positives if there happens to be a faulty component when you wanted to update snapshot for another component.
When running jest —- watch
, the change in the component will also lead to auto update of the snapshot file.
Snapshot testing and Enzyme cannot be used in the same test suite. They should be structured in different files.
Also, frontend design may change more frequently than you expected throughout the project, it is better to gauge whether it is worthwhile or which part of logic should be tested with priority at the current project phase.
Some examples on localstorage mocking, spying:
https://github.com/EngineerFocus/FocusPro/tree/master/client/src/__test_
Some good references for getting started with Jest and Enzyme:
Trouble Shooting (Mocking)
https://github.com/facebook/jest/issues/936
http://stackoverflow.com/questions/39633919/cannot-mock-a-module-with-jest-and-test-function-calls
https://gist.github.com/evansiroky/89deb7759ae487abb5fed6d1dfdfce84