Beginning with automated tests using Cypress with ReactJS
Tags: javascript, testing, react, cypress
Published: 2022-06-17 12:59:01

This post is a relate/documentation of a discovery involving automated tests and all the test context within React and JS in general. Its purpose is to instigate the reader to the scope of testing and TDD 

---

## Context - Test Types
Before we start, to test an application in an automated way, there are some types of tests that can be performed, among them we have:

### Unit Test:

Test things at the code level, that is, testing things in the most "micro" way possible.

### Integration test:

Testing things out at a slightly higher level than unitary, verifying that the integration of two or more things is working.

### E2E Test:

Tests and simulates the entire user flow. It is the most expensive test (in terms of time and processing) in the list as it actually simulates the user's navigation. It should be executed when the release of new features and changes ends up altering or creating new possibilities for the user flow.


![Image - Types of Test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwuya486nxf9f12kab2p.png)
_[Image Font](http://www.tecnisys.com.br/noticias/2019/a-piramide-de-automacao-de-testes)_

---

## TDD - Test Driven Development
One of the most important techniques in terms of software development, TDD consists of initially:

- Creating tests for your future code/feature/etc.
- The tests obviously don't pass, as the code/feature/etc doesn't exist yet.
- Develop as little as possible for the tests to pass.
- With the tests passing, refactor the code, improving it.
![TDD](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s18g7g32xcd03iqym9r3.png)
_[Image Font](https://www.ques10.com/p/21787/short-note-on-test-driven-development-tdd/?)_

It is a technique widely used and quite interesting because it ends up bringing security to the developed software. Since the developer always starts by programming the test and something that passes the test, all subsequent refactorings will continue to pass the initial test, bringing a lot of robustness to the code.

In the long run, this is an excellent code maintenance technique, as testing initially will ensure consistency in future code entered.

---

## Tests applied to the Front-End

I started the searches by looking for [E2E tests using react](https://reactjs.org/docs/testing-environments.html#end-to-end-tests-aka-e2e-tests).

The following libraries and technologies were found that can be used:

- [Cypress](https://www.cypress.io/)
- [Playwright](https://playwright.dev/)
- [Jest+Puppeteer](https://pptr.dev/)

---

## My initial opinions and implementations
Cypress → Robust and powerful, it has a lot of interesting stuff, but it's a bit complicated with the details. It has a testing infrastructure with metrics and analytics that is optional and paid, but the framework itself is free. It has a codegen option that records the movements and interactions you are making, transcribing them into code.

Playwright → From the same creators as puppeteer, simpler to configure and even delivering interesting results. It is completely free and has an interesting codegen option too!
My first implementations with Playwright:
![First implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r2qpxzmjryiwwzcweyys.png)

After testing and playing around with Playwright a bit, I turned the focus to Cypress. Here is a screenshot of the tool:
![Cypress - Image 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7po3uqwsdmx5t8x9h2oo.png)

I started by developing some simple tests, the first one, a test to see if the button was clickable and had text:
```jsx

import React from 'react';
import { mount } from '@cypress/react';
import App from './App';

it('Checks if theres a button with Click ME :D', () => {
  mount(<App />);
  cy.contains('Click ME :D').click();
});

```

Next, I made a simple code to check the main screen text as well:

```jsx

import React from 'react';
import { mount } from '@cypress/react';
import App from './App';

it('Checks if theres a link with Learn React in it', () => {
  mount(<App />);
  cy.get('a').contains('Learn React');
});

```

It's super simple to start with the tests at this point, just an `it` to describe what the test will perform and then, in sequence, use `cy` to interact with the elements on the screen. Cypress has some implementations to facilitate our work with asynchronous programming, executing commands whenever the page loaded, making our day-to-day work with the tool much easier.

In addition, Cypress has a very interesting dynamic, recording the tests performed in .mp4 files and opening an interactive page where you can do something similar to the Playwright codegen.

In this repository, I did the same tests that were performed previously. In terms of code, the difference is very small, the biggest difference is in the configuration.

Besides testing, Cypress has integration with Slack:
![Slack Integration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4baref39zq94ndhge2s.png)
And one of its main features in this integration is to confirm that key tests have passed before product launches or new features.

![Github Integration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p2gitmpbcg9eignzigtk.png)

It also integrates with GitHub, being able to run along with the repository's workflow, which makes day-to-day revisions and PRs much easier..

---

## Conclusion

I didn't get to test Playwright much, however, Cypress is an absurdly interesting tool, managing to transform asynchronous tests, with parallelism and repeatability into simple and almost trivial things. In addition, the recordings help a lot when trying to understand what is going wrong with a test.
Finally, unit, integration, and E2E tests are big steps developers need to take to advance their journeys. This was my first step.


--- 


Thanks for reading this far and I hope you've been interested in testing.