Complete Guide to End-to-End (E2E) Testing with Cypress: Improve the Quality of Your Web Applications

Introduction:

There are several types of tests used in software development to ensure the quality of the final product. These include unit testing, integration testing, static testing, and end-to-end testing.

  • End-to-End Testing (E2E): This test verifies the entire flow of an application from start to finish, simulating user behavior in a real scenario.
  • Integration Tests: They verify the interaction and communication between different components and modules of an application.
  • Unit Tests (unit): They test individual units of code, such as functions or methods, in isolation from the rest of the application.
  • Static Tests: They check the source code for errors and vulnerabilities without running the program, through code reviews and static analysis.

In the application development phase, one of the fundamental practices for ensuring software quality is testing. Among the different types of testing, End-to-End Testing (E2E) stands out for simulating real user behavior when interacting with the application. In this article, we'll explore what E2E testing is, how it works, and how it can benefit application development.

For several years now, the Cypress library has been available. It is one of the most popular tools for carrying out this type of testing because it allows you to do so with the Chrome browser, which is widely used by developers and is known for being fast and secure.

What is End-to-End Testing (E2E)?

The distinctive feature of the E2E test is that it focuses on the functionality of the application from a global perspective, without worrying about the internal details of its implementation. It's not about testing individual functions or methods, as in Unit Testing, or about verifying integration between specific components, as in Integration Testing. Instead, E2E Testing focuses on the final result, ensuring that all components work together effectively to meet user requirements and expectations.

The process of an End-to-End test involves the simulation of typical user actions, such as clicking on buttons, filling out forms, navigating through different pages or interacting with interface elements. These tests are run in an environment similar to that of a real user, using a web browser or a graphical interface, and may involve interactions with databases, web services and other external systems.

The main objective of E2E Testing is to ensure that the application works correctly in all its parts and that the different functionalities are integrated without problems. In addition, these tests can also help identify potential performance, usability, and accessibility issues.

While E2E testing is essential to ensure the quality and proper functioning of an application, it can also be more complex and take longer to configure and execute compared to other types of more focused tests. However, its importance focuses on its ability to provide a global view of the product, allowing developers and quality teams to detect problems and ensure that the application meets the needs of end users.

Advantages of E2E Testing in Cypress

  • Time Travel:Cypress has a “Time Travel” feature that allows developers to see each step of the test as it runs. This unique feature makes it easy to debug and analyze tests, since developers can see exactly what's happening at all times. They can inspect the state of the application at any point during the test execution, making it simple to identify errors and understand problems in the application.
  • Debuggability:Cypress is easy to debug. It offers a visual interface that allows developers to examine application status, variable values, and other important details. This makes it easier to identify and solve problems, improving efficiency and productivity in development.
  • Real time reloads:One of the most outstanding features of Cypress is its real-time refill functionality. Every time changes are made to the test or to the application code, Cypress automatically reruns the affected tests immediately. This allows developers to get instant feedback on the changes made and to check if they introduced any errors in the application.
  • Automatic waiting:Built-in “automatic wait”, which means that there is no need to add explicit pauses or waits in the test to wait for page elements to load or actions to complete. Cypress automatically detects when an action awaits a response from the application and waits until the elements are available and the tasks are completed before continuing with the test. This prevents common unstable test problems and simplifies writing more robust and reliable tests.

Creating an E2E Test with Cypress

This document presents a practical example of how to create an E2E test using the Cypress tool. It shows how to set up the test environment, write the test and run it to verify the functionality of a specific function of the application.

1. For install Cypress in our project, we can use both yarn and npm. In this case, we'll be using npm throughout the process.

npm install cypress --save-dev

2. Before Open the project, we need to configure the scripts in our package.json, where we'll add:


"scripts": {
		//...demás scrips
		"cypress:open": "cypress open"
	},


⚠️ If the scripts are not added, the project must be run with a longer command

./node_modules/.bin/cypress open

3. For execute the project, we need to run the”open mode” which is the following command in the console:

npx cypress open

A window will open, similar to the one shown in the image. It will allow you to configure e2e testing and will show the project we are working on and its current version.

4. After that, the browser will ask us to select where we want to run our project with E2E tests. From there, we can start to see our tests in the folder where we placed them.

5. A Chrome browser window will open to run the tests in Cypress. The image shows the “cypress/e2e” folder where the projects are saved. In this case, there are three subfolders with codes for running the tests.

In this same step, an example that is integrated into Cypress will be presented. In it, it is shown that the tests passed successfully. If they failed, it would indicate where the failure occurred.

In addition, we have the”Run mode“in which the test statuses are displayed on the console. To run the tests in headless mode (on the command line), use the following command

npx cypress run

Examples of with code

In order to execute Cypress testing e2e, some codes will be briefly explained and for an app that is in local mode, the code can be modified to any way you want to use it.

Describe in Cypress it is used to group a set of related tests in the same area. It provides a way to organize tests and group them according to their functionality or specific area of the application being tested.

BeforeEach is a block of code that is executed before each test (or test case). In this particular case, it is used to only log in once in the test code.

⚠️ The example given is the same code, but divided into two parts to better explain what each one does.

Part 1:



// cypress/e2e/example.cy.tsx

describe('Login', () => {
beforeEach(() => {
		cy.visit('http://localhost:3000');
		cy.get('.btn-password').click();
		cy.get('.email').type('example@kranio.cl');
		cy.get('.password').type('ASdf1234');
		cy.get('.login-button').click();
});
//...it
//...it
});

⚠️ As a good practice, it is best to set a BaseURL and that's what we call the visit

cy.visit('/');

📌 You can also search directly for the type of element you want in the DOM. For example:

cy.get(Input[placeholder='Username']).type('example@kranio.cl')

For more information on the usability of “get”, see https://docs.cypress.io/api/commands/get

Part 2:



it('Ingresa un numero al input y presiona el buscar', () => {
		cy.origin('http://localhost:3000', () => {
			cy.contains('Aceptar').click();
				cy.get('Input[placeHolder="N° del contenedor"]').type('1234567');
				cy.get('button[type="submit"]').contains('Buscar').click();
		});
	});

Summarizing what the code does:

  • First, an overview of what the code will do is provided. Then, in the section of < http://localhost:3000 >cy.origin (''..), makes sure that the page we are viewing is localhost:3000.
  • Then, look for a button that says “accept”. In this example, it was an alert modal that contained this button.
  • Then, you can see that a container number is added to an input and the search button is pressed, where both are found by their placeholder and their type.

💡 cy.contains This command allows you to find elements that contain specific text and then perform actions on them, such as clicking, typing on them or verifying their presence.

💡 cy.get You can use this command to search for elements based on their selector (such as identifiers, classes, tags, etc.) and then perform various actions on those elements, such as clicking, typing in input fields, or verifying their properties.

Part 3:


it('Se ven las estadisticas', () => {
		cy.origin('http://localhost:3000', () => {
			const totalContainerValue = 10; 
			const totalOsValue = 30;
			const totalPiecesValue = 20;

			cy.contains('Aceptar').click();
			cy.get('h3').should('be.visible'); 
			cy.get('h6').should('be.visible'); 

			cy.get('h6:contains("Total contenedores")').should('be.visible');
			cy.get('h6:contains("Total OS")').should('be.visible');
			cy.get('h6:contains("Total Piezas")').should('be.visible');

			cy.get(`h3:contains(${totalContainerValue})`).should('be.visible');
			cy.get(`h3:contains(${totalOsValue})`).should('be.visible');
			cy.get(`h3:contains(${totalPiecesValue})`).should('be.visible');

		});
	});


💡.should ('be.visible') this line of code is used to ensure that certain elements of the page are visible as intended.

Summarizing what the code does:

  • The props of the component we are testing were passed to this code. The data in them is the same as the data that the user sees. To verify this, we must first accept the alert mode and check if the h3 and h6 are on our website. Then, we can check if the texts are also present.

.skip to be able to pause one or more particular tests. .

Only only this test will run, and all other tests in that test file will be ignored.

✅ For more information on Cypress E2E

Conclusion: To summarize the article, End-to-End (E2E) testing is a fundamental practice in software development to ensure the quality and proper functioning of an application from the perspective of the end user. Unlike other tests that focus on individual components or the interaction between them, E2E testing verifies the entire flow of the application, simulating the actions of a real user.

Ready to improve the quality of your web applications with effective E2E tests?

At Kranio, we have testing experts who will help you implement End-to-End testing strategies using tools such as Cypress, ensuring that your applications work properly in all scenarios. Contact us and discover how we can help you raise the quality of your software.

Karla Cabañas

September 16, 2024