How Do We Test Our Front-End Applications in Trendyol GO? (Part 1)

Mehmet Can Boz
Trendyol Tech
Published in
7 min readAug 10, 2022

Under this title, we want to introduce our integration and E2E test infrastructure for frontend applications in Trendyol GO. We used Cypress extensively in this process. The first implementation is for one of the micro-frontend applications for our Trendyol GO Admin Panel project.

Since the structure we designed is comprehensive, we decided to explain it in two parts. In this article, first, we will mention why we started the testing processes for the delivery domain. After, we will talk about how we organize the testing process. Finally, we will introduce Cypress, which is our primary tool in this journey and we will talk about some specific technical choices we made along the road.

Why We Need Tests?

Before starting, let’s talk about why we needed such a process. We have an admin panel project, where Logistics teams manage operational activities under Trendyol GO. This panel contained many workflows and was evolving into an increasingly complex structure. The main purposes of starting this process were to record these workflows and to establish a more solid structure for the development.

When we look at our motivations, the first thing was to spread the test culture to our team. Tests allow you to create a reliable and robust structure from the code you write to the business that is implemented. As we write our tests, our code starts to become cleaner and more scalable. It is important to keep these structures in order since many parts affect each other. It also helps ensure that previously developed features are not broken by new functionality. On the other hand, you will see reactions of the business to the user actions on the front, and in this way, you will also record the business information. Thence, you have the opportunity to transfer this information to the new members of the teams.

How We Worked

Now, let’s talk about how we drew a road map when we started this journey. First of all, dev-in-test and front-end developers met and decided how to start the process. We decided to write both integration and E2E tests at first. We designed integration tests to be an early part of our development. On the other hand, E2E tests would test the project deployed to the staging environment.

When we started to write the tests, we observed that the integration and E2E tests were similar to each other. The reason for this is that Cypress is an E2E test tool at its core but we used it for integration tests by defining the relationship between components and mocking every HTTP request and web socket event. On the E2E side, we decided to proceed with mocks in the same way; otherwise, the project would make many teams dependent on each other at the same time. Therefore, these dependencies would hinder the work we are trying to do by making the project bigger than necessary. We postponed the E2E side to make it comprehensive at a later time and started to focus on the integration part. At the end of the day, the E2E tests will be less in number than integration tests and only cover some happy paths for certain user stories and would hit the back-end services.

At first, we wrote tests for certain views and their sub-actions. After the coverage reached a certain point, we started developing new tasks with tests included and as a part of development itself. Thus, we had a chance to apply TDD.

What is Cypress?

Cypress is a tool that allows us to test any application that can run through the browser. It can work with many popular JavaScript frameworks (React, Vue, Angular). As a result, we can say that Cypress is in a tech stack independent infrastructure.

One of the best things about Cypress is that it’s free (excluding some restrictions) and open source. It provides a virtual interface(Cypress Desktop App) to observe what is the state of the app in test commands. It takes snapshots and videos so you can see what happened before and after test commands. Besides, Cypress has high popularity in the development world. At the time of writing this article, there were approximately 39.3k stars on Github and 4.1 million weekly downloads on npm.

Cypress is very easy to install. It can be set up as a part of the application or as a standalone project. We used the first one for our integration tests and the second one for E2E.

Our Technical Choices

Here we will talk about some choices we made along the way that makes our test architecture more robust and scalable:

- Cypress API

Let’s take a look at Cypress API. To use the Cypress API, all we have to do is type cy. Cypress also has various test commands on its site in great detail. For example, one of the basic commands is the getcommand, which helps choose the element to make an assertion. After selecting the element we want to test, we use various assertion types. These structures vary according to the HTML element. We use the should keyword to make assertions. Cypress uses Chai and Mocha in its infrastructure for assertions.

As seen above, the get element has many selection types. These selection types may turn into some disadvantages in the future. I will explain these disadvantages when explaining the cypress-testing library.

- Cypress Testing Library

We use cypress-testing-library when selecting elements in our infrastructure. This plugin adds role-based selection to Cypress. In this way, we do not select elements with class, id, or even a test-id. These attributes of an element may change in the future and that makes tests more coupled to application code and makes the overall structure more fragile.

All you do is assign these roles to UI elements that you haven’t previously given semantically related roles. If you are already using an advanced design system such as Ant Design or Material-UI, they are already assigned to the correct semantic roles, thus making tests easier. This also applies even if you use your design system or component library. In the end, this practice helps improve the application in terms of accessibility and readability.

- Experimental Session And Origin Flag

We also integrated the experimentalSessionAndOrigin flag in Cypress configuration. Normally, Cypress runs the tests one by one, following each other and sharing the same browser session. This flag enables each block to run in isolation. This means that the page is reset after each block and all active session data is cleared. We think it is better to approach writing tests this way. There is already information on the Cypress site that this option will be introduced by default in future versions.

- Mocking Endpoint

Another very powerful feature that Cypress provides is the intercept method. We use this to mock the REST endpoints that our application uses. We give some options such as method, pathname, hostname, and the name of the fixture file where we keep the response of the endpoint in the fixture folder. It is very easy to use and has a robust selection of options in terms of functionality. For example, let’s say that when we press a button, we send a request to an endpoint. First, we mock the endpoint with the intercept method, then click the button and wait for the endpoint that we created with the label.

There are many advantages to mocking an endpoint. One of them is that you can start to develop tasks in parallel with back-end developers. For example, a field will be added to the endpoint on the back-end, and the front-end team can start its development using mocking without waiting for the actual endpoint. When the back-end team completes the endpoint, the process will be finished without making any changes on the front-end. In this way, it will improve your efficiency and makes the development process independent.

We can also generate our data as we mock the endpoints. In this way, our code becomes more stable in various scenarios against the bugs that will occur. Also sometimes it is hard to use real endpoint data when fixing some annoying bugs.

Another advantage is that you can write your test without connecting to the internet or a remote server.

- Cypress Command

We also use Cypress Commands extensively. This method offers the opportunity to share common functions and structures in tests. We keep the Cypress command structure in the support folder. You can reach the Cypress command with cy.{commandName}.

We also use cypress commands to mock endpoints. Because the application uses the same endpoints on multiple pages. Also, it makes testing easy to read and design.

- Page Object Model

Additionally, we used the Page Object Model in our project. Page Object Model, also known as POM, is a design pattern that helps to avoid code duplication and improve the readability of code. It is a class that represents a page in the web application. You can make some logical functions according to the view of the page. We used POM because we are testing the same pages for different states of the deliveries that Trendyol GO couriers carry. At the bottom, you can see the usage of POM and example of tests.

Conclusion

Testing is crucial to the long-term success of an application, and the practices we talked about help ensure that your application is working properly from start to finish. It can save you from hours of development and helps catch unexpected errors and bugs in production. I advise you to check out the official documentation to learn more about Cypress.

Happy coding…

REFERENCES

--

--