Testing React - Setup, Unit, Integration and E2E using Jest and Cypress (feat. GraphQL)

rxassim profile image Assim EL HAMMOUTI Originally published at assim.me on ・4 min read

NOTE: This is a cross-post from my newsletter and Blog. I publish each email one week after it’s sent. Subscribe to get more content like this earlier right in your inbox! 💌

Hi ! This is a guide/cheatsheet that I comeback to read when I want to write tests for a project.

I thought this might help other fellow developers so here you go 😁


Install jest, cypress and helper libraries

yarn add jest @testing-library/react @testing-library/jest-dom -D


In this section we'll configure Jest and Cypress


Let's create a config file for Jest in the root directory:

module.exports = {
  // location.href will have this value
  testURL: 'https://example.com',
  // Add here folders to ignore
  testPathIgnorePatterns: ['/node_modules/'],
  setupTestFrameworkScriptFile: require.resolve(
  // path to components/modules to test
  modulePaths: ['<rootDir>/src'],
  moduleNameMapper: {
    // mock files that jest doesn't support like CSS and SVG files
    '\\.css$': '<rootDir>/test/module-mock.js',
    '\\.svg$': '<rootDir>/test/module-mock.js',
  // collect coverage report from only the js files inside src
  collectCoverageFrom: ['**/src/**/*.js'],
  coverageThreshold: {
    global: {
      // 20 is just an example
      // you can change it to any value you want (below 100)
      statements: 20,
      branches: 20,
      functions: 20,
      lines: 20,

Now create a test folder in the root directory and create setup.js file inside it:

// cleanup helper
import '@testing-library/react/cleanup-after-each'
// custom matchers for jest
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect'

also create a module-mock.js in the same test folder :

module.exports = {}

Code coverage

In package.json add --coverage at the end of your test script:

  "scripts": {
    "test": "jest --coverage"

Watch mode

When coding, use Jest in watch mode to get instant feedback about the tests related to the files you are changing.
To use this feature, add a script to package.json and use it:

  "scripts": {
    "test:watch": "jest --watch"


Install cypress and helpers:

yarn add cypress @testing-library/cypress -D

then add a script to package.json to run cypress:

  "scripts": {
    "cy:open": "cypress open",
    "cy:run": "cypress run", // run all cypress tests
yarn cy:open

Cypress records videos and takes screenshots of the app while running tests.
Let's add the folders that Cypress uses for this to .gitignore



When running cypress open for the first time, it creates a bunch of files and folders inside a folder in the root dir called cypress. It also creates a file in the root dir called cypress.json. That's the configuration file cypress uses.

Let's add a baseUrl to use in our E2E test:

  "baseUrl": "http://localhost:3000"


@testing-library/cypress adds some very handy commands to cypress, let's configure it:

Go to <rootDir>/cypress/support, open index.js and add this line:

import '@testing-library/cypress/add-commands'

Test utils (helpers):

Have a test-utils file that exports a set of tools that are used specifically for the project you are testing.

  • Example:

Export a render method that takes care of adding styled-components ThemeProvider HOC:

import React from 'react'
import {
  render as originalRender,
} from '@testing-library/react'

const theme = {
  colors: {
    red: 'red',

function render(component, renderOptions) {
  const utils = originalRender(
    <ThemeProvider theme={theme}>
  return {
export { render }

Now in your tests, import render from this test-utils file instead of @testing-library/react

Unit test

Write a unit test when you want to test the functionality of ONE function/component:

import React from 'react'
import { render } from '@testing-library/react'
import Paragraph from '../paragraph'

test('renders the text given', () => {
  const { getByText } = render(<Paragraph>Hello</Paragraph>)


Integration test

Write an integration test when you want to test the functionality of several components working togather:

import React from 'react'
import { MockedProvider } from '@apollo/react-testing'
import wait from 'waait'
import { fireEvent } from '@testing-library/react'
import { render } from '../test-utils'
import App, { LOGIN_MUTATION } from '../app'

beforeEach(() => {

test('login as a user', async () => {
  const fakeUser = { id: 123, username: 'fakeuser' }
  const fakeUserCredentials = {
    password: 'stupidpassword123',
  const token =
  const loginMutationMock = jest.fn()
  const loginMutationErrorMock = jest.fn()
  const mocks = [
      request: {
        query: LOGIN_MUTATION,
        variables: {
          username: fakeUserCredentials.username,
          password: fakeUserCredentials.password,
      result: () => {
        return { data: { user: fakeUser, token: token } }
      error: () => {
  const { getByTestId, getByText, getByLabelText } = render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <App />
  // open login form dialog/modal
  // fill out login form
  const usernameNode = getByLabelText(/username/i)
  const passwordNode = getByLabelText(/password/i)
  usernameNode.value = fakeUserCredentials.username
  passwordNode.value = fakeUserCredentials.password
  // submit login form
  fireEvent.click(getByText(/sign in/i))
  // wait for the mocked requests to finish
  await wait(0)
  // assert calls
  // assert login side-effect

End to end test:

Simplest definition : Imagine you've got a robot that obeys your commands, now ask it to test your app as a normal user 🤷‍♂️.

describe('authentication and registration', () => {
  let user

  beforeEach(() => {
    return cy
      .then(u => (user = u))

  it('register as a guest user', () => {
    const user = {
      username: 'user',
      email: 'hello@example.com',
      password: 'password123',

  it('login as a user', () => {
      .getByText(/sign in/i)

I'll try to improve this post and add to it but please feel free to send a PR in case you want to correct/add/edit something ❤️

Posted on by:

rxassim profile



Lead Software Engineer (JS & GraphlQL)


markdown guide