Step-by-Step Next.js Unit Testing Tutorial with Cypress and Testing Library

Unit testing is a crucial part of modern web development, ensuring that your components work correctly and reliably. In this tutorial, we will walk through a step-by-step process to set up and write unit tests for a Next.js application using Cypress and Testing Library. This guide is designed for developers who want to improve their testing skills and ensure high-quality code.

Prerequisites

  • Node.js installed on your machine
  • Basic knowledge of Next.js and React
  • Familiarity with testing concepts
  • Existing Next.js project or create a new one

Make sure you have a Next.js project set up. If not, create one using:

npx create-next-app my-nextjs-app
cd my-nextjs-app

Installing Testing Dependencies

Install Cypress and Testing Library along with their dependencies:

npm install --save-dev cypress @testing-library/react @testing-library/jest-dom @testing-library/user-event

Configuring Cypress

Initialize Cypress in your project:

npx cypress open

This command opens the Cypress Test Runner and creates a cypress folder with default configuration files.

Setting Up Testing Environment

Create a new test file for your component inside cypress/e2e. For example, example.spec.js.

In your Next.js project, ensure your component is ready to be tested. For illustration, let’s assume you have a simple Button component.

Sample Button Component

Create components/Button.js:

export default function Button({ onClick, children }) {
  return (
    
  );
}

Writing the First Test

Open cypress/e2e/example.spec.js and write your first test to verify the button renders correctly.

/// <reference types="cypress" />

import { mount } from 'cypress/react';
import Button from '../../components/Button';

describe('Button component', () => {
  it('renders with correct text', () => {
    const buttonText = 'Click Me';
    mount();
    cy.get('button').should('contain.text', buttonText);
  });
});

Adding User Interaction Test

Test if the button responds to click events. Update your test file:

/// <reference types="cypress" />

import { mount } from 'cypress/react';
import Button from '../../components/Button';

describe('Button component', () => {
  it('calls onClick when clicked', () => {
    const handleClick = cy.stub().as('clickStub');
    mount();
    cy.get('button').click();
    cy.get('@clickStub').should('have.been.called');
  });
});

Running Tests

Start Cypress Test Runner with:

npx cypress open

Select your test file and watch the tests run in the Cypress UI.

Integrating with Next.js

To test components in the context of your Next.js app, you can use mount from cypress/react or set up custom commands. For more complex scenarios, consider using jest with @testing-library/react for unit tests and Cypress for integration or end-to-end tests.

Conclusion

By following this step-by-step guide, you can set up a robust testing environment for your Next.js applications using Cypress and Testing Library. Regular testing helps catch bugs early and improves the overall quality of your codebase. Happy testing!