Checklist with Best Practices for Writing Automation Tests

Checklist with Best Practices for Writing Automation Tests

If you already have, or you are planning to implement some automation tests for your projects, there are a couple of things that you need to consider to create tests that will be reliable, and maintainable. The goal is to not have some tests that will be poorly written, flaky, or unreliable, and that will increase the maintenance costs.

This checklist might help you in creating some high-quality, and maintainable test scripts. If you already have implemented tests, again check this list to confirm that you have done all the best practices.

1. Use Descriptive Names

You will agree that naming the tests as test1.js, and test2.js is not very helpful and useful. Just imagine what will happen if you have 50 automated tests named test1.js, and test50.js how much time you will need to find the tests you are looking for, how much hard it will be to know what you are covering with those tests, and the reports will also be tough to read.

That’s why you need to have descriptive names for your tests and to make your tests self-explanatory so you will be able to understand what each test does without looking into the code.

So, if you already have some tests or you are planning to make some, make sure that each of them has a descriptive name that states the purpose of the test, and make sure that you follow the naming conventions consistently across your test suite.

Example (loginWithValidCredentials.js):

loginWithValidCredentials():
    # Test implementation

In this example, the test name indicates that it checks if a user can log in with valid credentials.

2. Keep Tests Simple and Focused

When you are writing the tests, make sure that each test is focused on only one functionality or user scenario, and that has one reason to fail. What this means if when you have a test case that checks if the user can log in with valid credentials, that test should only check that.

Or, let’s say you want to test an e-commerce site and want to check if you can add a product to your Favourites list, just do those steps. For example, the steps will be: add the product to your Favourites list, open the list, and check if the products if there.

Don’t mix any other scenarios like buying the product, adding/removing to the cart, etc. Those user scenarios are related to different functionality and they should not be mixed with the Add To Favourites List test.

Example (addProductToFavouritesList.js):

addProductToFavouritesList():
    # Test implementation for adding product to Favourites list

Example (addProductToShoppingCart.js):

addProductToShoppingCart():
    # Test implementation for adding product to Shopping Cart

Here, each test focuses on a specific scenario, making them clear and focused. If you group a couple of test cases in one file, make sure that they are for the same functionality and that their logic is similar, like add, or remove from the Favourites list.

3. Use the Page Object Model (POM)

To improve the readability, reusability, and maintainability of your tests you can use the Page Object Model (POM) pattern that helps you to separate the test logic from the page structure.

The Page Object Model is a design pattern that separates the test logic from the UI elements, making it easier to manage changes in the application. Each page in the application is represented as a class, and the various elements on the page are defined as variables within the class. The interactions with these elements are defined as methods.

Example:

In this example, the LoginPage class has the locators of all the page elements and the methods that are related to that class. The login tests are in separate files that communicate with the methods from the LoginPage class while they are running on the device.

4. Use Assertions Effectively

The assertions are very important for verifying the expected outcomes of your tests. Make sure that you use clear and concise assertions, and be specific about the expected outcomes in every test.

5. Avoid Hardcoding Test Data

Hardcoding the data in every test can make your tests difficult to maintain. To change some set of data you will need to go into the code and check in a lot of places to update the data.

Instead, you can use data-driven testing techniques to separate test data from test logic. In this way, you can easily find and update your test data from a separate file, without changing the test code.

Example:

6. Implement Wait Mechanisms

If you use hard-coded waits in your tests, that could cause the test to run slower and usually, those waits will be longer than it supposed to be.

That’s why you need to use explicit wait to handle the page content to wait until a specific condition is fulfilled and then continue with your test.

Explanation: Use explicit waits to handle dynamic content and ensure that your tests do not fail due to timing issues. Avoid using implicit waits or hard-coded sleep statements.

Bad Example:

  1. Click on the Confirm button.
  2. Wait for 5 seconds. ❌
  3. Get the confirmation message from the pop-up.

Good Example:

  1. Click on the Confirm button.
  2. Wait until the confirmation pop-up is visible.
  3. Get the confirmation message from the pop-up.

7. Use Helper Methods

To improve the code reusability you can write reusable helper methods for common actions. In that way, you can reduce the code duplication and make the tests more readable.

Look for a code that makes some action that is repeated in different tests. Create a method for that piece of code and just call that method in the tests. In that way, when you need to change that piece of code, you will change it in one place and it will reflect in all the tests that are using that.

8. Use Meaningful Comments

Use comments to explain the purpose of complex logic or to provide context for specific test steps. Make sure that you keep the comments brief and to the point.

9. Ensure Tests are Independent

Tests should not depend on each other. Each test should set up its state and clean up after itself to avoid side effects. You can manage this by using setup and teardown methods for setting and cleaning up the state of the test, ensuring that each test runs independently of other tests.

10. Use a Reporter to show the test results

Reporting is a crucial aspect of automation testing. Make sure that you choose a reporter that will best suit your framework and your needs. It is important that you find some easily accessible and understandable reports that will show the test results after every execution.

One example for this purpose is the Extent Report.

Comments

No comments yet. Why don’t you start the discussion?

    Leave a Reply

    Your email address will not be published. Required fields are marked *