A little helper to unit test React components in the open source Cypress.io E2E test runner v4.5.0+
- What is this? This package allows you to use Cypress test runner to unit test your React components with zero effort. Here is a typical component testing, notice there is not external URL shown, since it is mounting the component directly.
- How is this different from Enzyme or RTL? It is similar in functionality BUT runs the component in the real browser with full power of Cypress E2E test runner: live GUI, full API, screen recording, CI support, cross-platform, and visual testing. Ohh, and the code coverage is built-in!
- If you like using
@testing-library/react
, you can use@testing-library/cypress
for the samefindBy
,queryBy
commands, see one of the examples in the list below - Read My Vision for Component Tests in Cypress
Feature | Jest / Enzyme / RTL | Cypress + cypress-react-unit-test |
---|---|---|
Test runs in real browser | β | β |
Uses full mount | β | β |
Test speed | π | as fast as the app works in the browser |
Test can use additional plugins | maybe | use any Cypress plugin |
Test can interact with component | synthetic limited API | use any Cypress command |
Test can be debugged | via terminal and Node debugger | use browser DevTools |
Built-in time traveling debugger | β | Cypress time traveling debugger |
Re-run tests on file or test change | β | β |
Test output on CI | terminal | terminal, screenshots, videos |
Tests can be run in parallel | β | β via parallelization |
Test against interface | if using @testing-library/react |
β
and can use @testing-library/cypress |
Spying and mocking | Jest mocks | Sinon library |
Code coverage | β | β |
See issues labeled v4
Requires Node version 8 or above.
npm install --save-dev cypress cypress-react-unit-test
- Include this plugin from your project's
cypress/support/index.js
require('cypress-react-unit-test/support')
- Tell Cypress how your React application is transpiled or bundled (using Webpack), so Cypress can load your components. For example, if you use
react-scripts
do:
// cypress/plugins/index.js
module.exports = (on, config) => {
require('cypress-react-unit-test/plugins/react-scripts')(on, config)
// IMPORTANT to return the config object
// with the any changed environment variables
return config
}
See Recipes for more examples.
β οΈ Turn the experimental component support on in yourcypress.json
. You can also specify where component spec files are located. For example, to have them located insrc
folder use:
{
"experimentalComponentTesting": true,
"componentFolder": "src"
}
import React from 'react'
import { mount } from 'cypress-react-unit-test'
import { HelloWorld } from './hello-world.jsx'
describe('HelloWorld component', () => {
it('works', () => {
mount(<HelloWorld />)
// now use standard Cypress commands
cy.contains('Hello World!').should('be.visible')
})
})
Look at the examples in cypress/component folder. Here is the list in progress
Spec | Description |
---|---|
alert-spec.js | Component tries to use window.alert |
counter-set-state | Counter component that uses this.state |
counter-use-hooks | Counter component that uses useState hook |
emotion-spec.js | Confirms the component is using @emotion/core and styles are set |
error-boundary-spec.js | Checks if an error boundary component works |
pure-component-spec.js | Tests stateless component |
stateless-spec.js | Passes Cypress stub to the component, confirms the component calls it on click |
window-spec.js | In the component test, the spec window and the application's window where the component is running should be the same object |
css | Shows that component with import './Button.css' works |
network | Confirms we can use cy.route to stub / spy on component's network calls |
react-book-by-chris-noring | Copied test examples from React Book and adapted for Cypress component tests |
react-tutorial | Tests from official ReactJS tutorial copied and adapted for Cypress component tests |
stub-example | Uses cy.stub as component props |
styles | Add extra styles to the component during testing using style , cssFile or stylesheets mount options |
toggle-example | Testing a toggle component using Cypress DOM commands |
typescript | A spec written in TypeScript |
unmount | Verifies the component's behavior when it is unmounted from the DOM |
use-lodash-fp | Imports and tests methods from lodash/fp dependency |
document-spec | Checks document dimensions from the component |
styled-components | Test components that use styled-components |
plus a few smaller sanity specs in cypress/component/basic folder.
Spec | Description |
---|---|
app-action-example | App actions against components |
context | Confirms components that use React context feature work |
forward-ref | Tests a component that uses a forward ref feature |
hooks | Tests several components that use React Hooks like useState , useCallback |
lazy-loaded | Confirms components that use React.lazy and dynamic imports work |
material-ui-example | Large components demos from Material UI |
mock-fetch | Test stubs window.fetch used by component in useEffect hook |
mocking-component | Replaced a child component with dummy component during test |
mocking-imports | Stub a named ES6 import using plugin-transform-modules-commonjs with loose: true when transpiled |
react-router-v6 | Example testing a React Router v6 |
renderless | Testing a component that does not need to render itself into the DOM |
set-timeout-example | Control the clock with cy.tick and test loading components that use setTimeout |
testing-lib-example | A spec adopted from @testing-library/react that uses @testing-library/cypress |
timers | Testing components that set timers, adopted from ReactJS Testing recipes |
tutorial | A few tests adopted from ReactJS Tutorial |
portal | Component test for ReactDOM.createPortal feature |
react-bootstrap | Confirms react-bootstrap components are working |
This way of component testing has been verified in a number of forked 3rd party projects.
Repo | Description |
---|---|
try-cra-with-unit-test | Hello world initialized with CRAv3 |
try-cra-app-typescript | Hello world initialized with CRAv3 --typescript |
react-todo-with-hooks | Modern web application using hooks |
test-redux-examples | Example apps copies from official Redux repo and tested as components |
test-react-hooks-animations | Testing React springs fun blob animation |
test-mdx-example | Example testing MDX components using Cypress |
test-apollo | Component testing an application that uses Apollo GraphQL library |
test-xstate-react | XState component testing using Cypress |
test-react-router-v5 | A few tests of React Router v5 |
test-material-ui | Testing Material UI components: date pickers, lists, autocomplete |
test-d3-react-gauge | Testing React D3 gauges |
storybook-code-coverage | Example app where we get 100% code coverage easily with a single integration spec and a few component specs, replacing several tools |
react-loading-skeleton | One to one Storybook tests for React skeleton components. Uses local .babelrc settings without Webpack config |
test-swr | Component test for Zeit SWR hooks for remote data fetching |
emoji-search | Quick component test for a fork of emoji-search |
To find more examples, see GitHub topic cypress-react-unit-test-example
You can pass additional styles, css files and external stylesheets to load, see docs/styles.md for full list.
const todo = {
id: '123',
title: 'Write more tests',
}
mount(<Todo todo={todo} />, {
stylesheets: [
'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css',
],
})
Additional configuration
If your React and React DOM libraries are installed in non-standard paths (think monorepo scenario), you can tell this plugin where to find them. In `cypress.json` specify paths like this:{
"env": {
"cypress-react-unit-test": {
"react": "node_modules/react/umd/react.development.js",
"react-dom": "node_modules/react-dom/umd/react-dom.development.js"
}
}
}
If you are using plugins/cra-v3 it instruments the code on the fly using babel-plugin-istanbul
and generates report using dependency cypress-io/code-coverage (included). If you want to disable code coverage instrumentation and reporting, use --env coverage=false
or CYPRESS_coverage=false
or set in your cypress.json
file
{
"env": {
"coverage": false
}
}
You can use any Visual Testing plugin from these component tests. This repo uses Percy.io visual diffing service as a GitHub pull request check.
The old v3 master
branch is available as branch v3
- the
cy.mount
is now simplyimport { mount } from 'cypress-react-unit-test'
- the support file is simply
require('cypress-react-unit-test/support')
Same feature for unit testing components from other frameworks using Cypress