Unit testing React components in Cypress without CRA and react-scripts

1. Install Cypress

npm install --save-dev cypress @cypress/react

2. Add cypress.json

{
"testFiles": "**/*.spec.js",
"experimentalComponentTesting": true,
"componentFolder": "./src",
"nodeVersion": "system",
"env": {
"webpackFilename": "./webpack.tests.config.js"
}
}
  • experimentalComponentTesting enables unit testing support. Though it says experimental, it’s quite stable now
  • componentFolder is akin integrationFolder and specifies where your unit and integration tests reside. You could keep your unit tests inside your ./src folder and have one to one mapping to your components, i.e. src/Button/Button.js and src/Button/Button.spec.js
  • nodeVersion tells Cypress to use the node version of the system it runs on, and not use the bundled version. This might be necessary if you are using node-sass and other binaries that are platform specific.
  • env.webpackFilename specifies the localtion of the webpack config you want to use for your tests. Cypress will transpile your components on the fly, hence you may need to have a different configuration that what you use to build your project. Think Storybook.

3. Update support bindings

Update ./cypress/support/index.js and import directives needed for Cypress to mount your unit tests into the Cypress DOM.

// ./cypress/support/index.jsimport '@cypress/react/support';

4. Configure the plugins

Update ./cypress/plugins/index.js and tell Cypress how to process your test files.

// ./cypress/plugins/index.jsmodule.exports = (on, config) => {
require('@cypress/react/plugins/load-webpack')(on, config);
return config;
};

5. Write your tests

// ./src/Button.spec.jsimport React from 'react';
import Button from './Button';
import { mount } from '@cypress/react';
describe('Button', () => {
it('should handle onClick', () => {
const onClick = cy.stub().as('onClick');

mount(
<Button onClick={onClick}>Click me</Button>,
);

cy.findByRole('button', { name: 'Click me' }).click();

cy.get('@onClick').should('have.been.calledOnce');
});
});

6. Run your tests

You can now run your tests with ./node_modules/.bin/cypress open or ./node_modules/.bin/cypress run .

7. Rejoice

Running components tests in an actual DOM boosts confidence in the reliability of your tests. You can run them in multiple browsers. You can create functional tests combining multiple components together to see how they interact with each other, how user interacts with them using the mouse and the keyboard, and you can stub your dependencies to avoid complex cy.intercept definitions.

Full-stack developer, passionate about front-end frameworks, design systems and UX.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store