Skip to content

coryhouse/cypress-react-unit-test

 
 

Repository files navigation

cypress-react-unit-test CircleCI Cypress.io tests renovate-app badge This project is using Percy.io for visual regression testing.

A little helper to unit test React components in the open source Cypress.io E2E test runner v4.5.0+

TLDR

  • 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.

Example component test

Comparison

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

Known problems

See issues labeled v2

Install

Requires Node version 8 or above.

npm install --save-dev cypress cypress-react-unit-test
  1. Include this plugin from your project's cypress/support/index.js
require('cypress-react-unit-test/support')
  1. Tell Cypress how your React application is transpiled or bundled (using Webpack), so Cypress can load your components. See Recipes

  2. ⚠️ Turn the experimental component support on in your cypress.json. You can also specify where component spec files are located. For exampled to have them located in src folder use:

{
  "experimentalComponentTesting": true,
  "componentFolder": "src"
}

Examples

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

Basic examples

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

plus a few smaller sanity specs in cypress/component/basic folder.

Advanced examples

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

Large examples

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

To find more examples, see GitHub topic cypress-react-unit-test-example

Options

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"
    }
  }
}

Code coverage

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
  }
}

Visual testing

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.

Development

See docs/development.md

Migration guide

From v3 to v4

The old v3 master branch is available as branch v3

  • the cy.mount is now simply import { mount } from 'cypress-react-unit-test'
  • the support file is simply require('cypress-react-unit-test/support')

Related tools

Same feature for unit testing components from other frameworks using Cypress

About

Unit test React components using Cypress

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 89.0%
  • TypeScript 8.3%
  • CSS 2.3%
  • HTML 0.4%