Components are reusable bits of code that, when written well, work and function independently from each other. If you want to be confident that components are working properly, you need to test them. Conveniently, Cypress has designed their testing framework to include component testing.

This tutorial illustrates the differences between end-to-end (E2E) and component testing, and what to consider when using these methods. After learning what makes component tests unique, you will learn how to use Cypress for component testing.

Prerequisites

To follow along easily, you will need:

To keep things simple, the focus of this tutorial will be on testing an already developed React component. The React component you’ll be testing can be found in the cloned repository under src/components/App.js.

In the next section, we will look at component testing and how it compares to end-to-end testing.

What is component testing?

A component is a distinguishable part of a software program. Forms, calls to action, and site search fields are examples of web application components. Web components can be anything from a simple call to action button to a full registration form submission.

Component testing is also known as program or module testing. The process consists of independently verifying and validating the functionality, performance, and compliance to requirements of a specific component from the main application. Component testing is limited to a particular component and is made simple by testing individual features instead of entire systems.

Component testing vs end-to-end testing

End-to-end (E2E) tests validate whether the flow of an application from start to finish proceeds as expected. E2E tests involve testing integrations with third-party APIs and services. Critical functionality gets tested throughout the application. Cypress uses a browser to run end-to-end tests, simulating the way that users interact with an application. Basic end-to-end testing for an application might include user registration, confirmation email, login, profile update, and logout.

End-to-end tests are more comprehensive, slower, and more prone to flakiness than component tests. Component tests are specialized, quick, and reliable. Because of their scope, end-to-end tests often require a complex setup phase. No complicated configurations are needed for component tests.

End-to-end tests in Cypress can be written by developers, specialized testing engineers, or a quality assurance team. Usually, the component developers themselves write component tests. Developers can easily verify a component’s required functionality while building it.

As you are writing the actual component tests later in the tutorial, you will notice that the initialization command in Cypress end-to-end tests is cy.visit(url). Component tests use cy.mount(<MyComponent />).

A well-tested app includes both end-to-end and component tests, with each set of tests specializing in the tasks they perform best.

Advantages of component testing include:

  • Detects module flaws
  • Components are tested on their own, not as part of the whole application
  • Limited scope makes tests quick and dependable
  • Reduces development time
  • Easy to set up specific scenarios
  • Doesn’t depend on external systems

To learn more about different testing methods, visit our guide to software testing.

Now that you understand Cypress component testing, the next sections will show you how to configure Cypress in an application, how to write tests, and how to run them.

Using Cypress for component testing

To test a React application using Cypress E2E tests, you need to run the app on a local development server while Cypress runs in a separate terminal. Cypress visits your application using the command cy.visit(url) and runs assertions on the loaded page.

The latest versions of Cypress include a built-in development server, eliminating the need for a local development server when performing component tests. The built-in server in Cypress is in charge of mounting and rendering the component in the browser. It only mounts and renders the component separate from the main application.

Testing in Cypress overview

This illustration shows that Cypress runs component tests in this order:

  • Mounts the component with the cy.mount() command
  • Renders the component
  • Uses Cypress commands to test component attributes

Any failure of a specified assertion causes a test to fail.

Writing component tests

This section details how to configure Cypress and write tests for the newsletter subscription component in the cloned project. The project already contains the tests, but we’ll explain how to create them in this section.

The first step to writing Cypress tests for a project is to install Cypress as a development dependency. This example project already has Cypress, but if you’re following along with a project of your own, install Cypress with:

npm install cypress --save-dev

This installs Cypress locally as a dev dependency for the project.

To open the Cypress for the application, enter:

npx cypress open

This command opens the Cypress launchpad.

Select Component Testing

Select testing option

Next, you’ll see an option to select a browser. Select Chrome and then click Start Component Testing in Chrome

Select a browser

If you’re adding new tests to a project, Cypress then generates configuration files for the testing type you selected. If you’re writing tests from the ground up, select New Spec.

You’ll be presented the option between Create from component and Create new spec. Select Create new spec

Creating a test options

You would give the spec a name, then click the Create Spec button.

Path to spec

Then, you have a specification file that includes sample code. Run the file.

Run spec

Now you can start creating tests for your newsletter subscription form. The test in the example project verifies that these actions happen:

  • The component is installed correctly
  • There is a placeholder in the input field
  • A success message is returned after a subscription

In the spec file we just created, we replaced the generated code with this:

// cypress/component/NewsLetterSubscription.cy.js file

import App from "../.././src/components/App";

describe("NewsLetterSubscription.cy.js", () => {
  describe("NewsLetterSubscription.cy.js", () => {
    it("Check input field for placeholder", () => {
      cy.mount(<App />); // mount the component
      cy.get("input").should("have.attr", "placeholder", "Subscribe to our newsletter"); // check the placeholder in the input field
    });
    it("test newsletter subscription", () => {
      cy.mount(<App />); // mount the component
      cy.get('[data-test="email-input"]').type("test@gmail.com"); // Type email
      cy.get('[data-test="submit-button"]').click(); // Click on submit button
      cy.get('[data-test="success-message"]')
        .should("exist")
        .contains("Thank you for subscribing to our newsletter"); // Check if success message is displayed
    });
  });
});

This test suite first mounts the component with the cy.mount() command. It then checks to see if the input field has a placeholder with some text using the cy.get() function.

When you enter an email address and click the subscribe button, a success message should be returned.

Go to the Cypress browser to make sure that the tests passed.

Passing tests

Congratulations, you have a tested React component! Your next step is to automate your tests in a CI/CD pipeline. For that, you can use CircleCI.

Configuring CircleCI

To get started with CircleCI configuration, create a .circleci folder at the root of the project. Inside it, create a file named config.yml. To make configuration a bit easier, we can use CircleCI orbs in the example project.

Note: Before using the Cypress CircleCI orb in your project, from organization settings, allow the use of uncertified orbs. Settings -> Security -> Allow uncertified orbs.

Enter the following content into the config.yml file:

version: 2.1 # Use 2.1 to make use of orbs and other features
orbs: # An orb is a reusable package of CircleCI configuration that you may share
  # across projects, enabling you to create encapsulated, parameterized commands, jobs, and
  # executors that can be used across multiple projects.
  cypress: cypress-io/cypress@3.1.2
workflows: # Workflows are a declarative way to orchestrate jobs and their run order.
  build:
    jobs:
      - cypress/run: # Run the cypress/run job from the cypress orb
          cypress-command: npx cypress run --headless --component # Run the cypress run command in headless mode

Add the project to GitHub, then log into your CircleCI account. Once you’ve pushed either the example project or your own project to a Github repository, it’s straightfoward to use CircleCI.

Select Projects, then Create Project.

Creating a new project

Select whichever Git hosting platform you pushed the repository to. Then, select your project from the dropdown and click Next.

You’ll be taken to your project page, and you’ll quickly notice there are no runs of your pipeline shown. To run the pipeline for the first time, push a small commit that doesn’t functionally change anything, like changing the name of a test.

After a few minutes, your tests should pass.

Successful workflow

Great! You have successfully set up tests to run whenever you change the code.

Conclusion

In this post, you learned what component testing is, how it differs from E2E testing, and what its benefits are. You also learned how to use Cypress for component testing, configure Cypress in a React project, test components in Cypress tests, and how to run the tests. You finished the project by setting up CircleCI to automatically execute your component tests.

I hope you enjoyed reading this as much as I enjoyed creating it. Until next time, keep learning!


Waweru Mwaura is a software engineer and a life-long learner who specializes in quality engineering. He is an author at Packt and enjoys reading about engineering, finance, and technology. You can read more about him on his web profile.

Read more posts by Waweru Mwaura