Back to all blogposts

Test automation best practices. Optimizing your web applications is easy like 1, 2, 3...

Marcin Basiakowski

Marcin Basiakowski

Head of Quality Assurance

When creating automated tests, it is often necessary to repeat certain steps to test a given functionality. In the following article, I would like to share with you my approach to test automation best practices. This method significantly reduces the problems and risks resulting from the implementation of tests using only UI elements.

Many software development projects that I have dealt with included the implementation of tests only on the UI layer. This translated into the duplication of basic steps (related to, for example, registering a new user) and had several disadvantages, most notably:

  • the duration of testing was noticeably extended,
  • if an error was found in the UI layer at the beginning of the test scenario, the test implementation made it absolutely impossible to test the functionalities available at a later stage.

To illustrate the structure of the automated testing and its implementation, I will use code snippets in JavaScript. But you can use it in any other programming language (Python, C #, Java, etc.) and framework (Cypress, Protractor, Selenium WebDriver or others) of your choosing. So let’s get down to business.

Continuous Integration for E2E tests (1/4): producing beautiful reports with Cypress and Mochawesome

Optimizing test automation – the action plan

Step 1: Get to know your application as early as possible. In full!

When starting a new project and testing tasks, it sometimes happens that you only pay attention to the application layer that comes into contact with the end-users. However, it’s worth thinking about what’s going on in the backend. There, you most often deal with applications based on REST API. Knowing this, you can go a step further and analyze the API documentation available in a tool called Swagger (btw. a final proof that IT people have swagger too! 🕺). Having the UI layer in one hand and the API in the other, you can start designing E2E tests.

Step 2: Prepare the E2E test architecture, also for API.

When writing code, regardless of whether it is a new application or an automated test, it is good to take care of its order, use good practices and design patterns. Among the automated tests, the most popular of them is Page Object Pattern, but nothing will stop you from using a different approach (e.g. Screenplay Pattern is also quite popular). The most important thing is that the adopted approach allows you to easily improve the existing code with new tests without the need for constant refactoring.

If you decide on implementing automated tests using the Page Object Pattern, you can create the following structure:

In the endpoints directory, put the implementation of support for all endpoints that you will use in your automated test. In pages – implementation of methods related to functionality on individual pages in the application’s UI. Finally, divide the integration directory into two subdirectories: api and ui, where you will place integration tests for the appropriate layers.

💡 Read more: How to make everybody happy with your product? By testing software requirements

Step 3: Implement automated tests for single functionalities, without dependencies.

Imagine a financial application with a registration screen, login and history of all transactions. Our goal is to implement scenarios that will cover the following functionalities:

  • New user registration,
  • Logging in with an existing account,
  • Viewing transaction history.

Create the files in the endpoints directory…

…in which you’ll include support for endpoints used for registration and logging.

Next, create the files in the pages directory…

…in which you will implement support for each process using the UI layer only.

INB4: I deliberately don’t provide a ready implementation in the above files. Not because I’m protecting my precious test automation method Gollum style. Much depends on the selected framework, test automation tools, your programming experience and knowledge of test automation best practices – this way you can adjust the code to your preferences and possibilities.

What interests us the most here is the implementation of integration tests. In the case of API, you can arrange integration tests in a fairly simple way. First, create the specification files for the API…

…by filling them with content. Start with, registrationAPI.spec.js

 …and then loginAPI.spec.js using the registration and login endpoint.

This set allows you to verify the registration and login process via API. As you can see, both test scenarios are completely independent of each other.

Thank you, next. Prepare tests for UI:

This implementation looks a bit similar to the API but apart from endpoints, you also use pages. For registrationUI.spec.js:

Similarly for loginUI.spec.js:

For testing the functionality related to displaying the history, in order not to duplicate the login process, try to use the login endpoint that, for example, returns an accessToken. It’s quite likely that you just need to set it in a cookie in your application to view the page as a logged-in user.

The transactionHistoryUI.spec.js test code could therefore look like this:

If you wanted to implement a test verifying the details of a specific transaction, you would first add support for a new endpoint to obtain a transaction list via API. Then, on the UI layer, you would implement a new page that would receive the ID of a specific transaction as input and then display its details.

GraphQL vs REST – the battle of API designs

Are you a tech manager in need of talented software developers and QA specialists? 👀

As the no. 1 software development company in Poland, we’re here to help you. Consult your project with our Quality Assurance experts during a free, 1-hour conultations.

Do you rely on API in E2E tests for UI?

What we managed to achieve here, apart from the architecture that is very easy to maintain, is the code of automated tests where each test on the UI layer verifies only the part of the application from the user side for which it was defined.

All previous stages in a given scenario were handled exclusively on the API layer. Firstly, it shortens the duration of the tests, and secondly, reduces the risk of their instability.

Thanks to this approach, you are able to easily implement subsequent test cases while maintaining the principle of full independence of each automated test. An additional advantage of this solution is the ability to connect UI and API tests separately in the deployment process of both applications.

Of course, I am aware that we are not able to use the API for every functionality, but where possible, I think it is worth reaching for a similar solution. As you could see for yourself, test automation best practices advantages cannot be denied.

Good luck! 🤞

Adding new functionalities to your app? Minimise the risk with feature testing

State of Frontend 2024

👨‍💻 Help the Frontend community! Answer the State of Frontend 2024 global survey. Takes less than 10 mins.

I want to help

The Software House is promoting EU projects and driving innovation with the support of EU funds

What would you like to do?

    Your personal data will be processed in order to handle your question, and their administrator will be The Software House sp. z o.o. with its registered office in Gliwice. Other information regarding the processing of personal data, including information on your rights, can be found in our Privacy Policy.

    This site is protected by reCAPTCHA and the Google
    Privacy Policy and Terms of Service apply.

    We regard the TSH team as co-founders in our business. The entire team from The Software House has invested an incredible amount of time to truly understand our business, our users and their needs.

    Eyass Shakrah

    Co-Founder of Pet Media Group


    Thank you for your inquiry!

    We'll be back to you shortly to discuss your needs in more detail.