DEV Community

Cover image for Testing Pyramid a Simple Way to Ensure Code Quality
Nicolas Villavicencio
Nicolas Villavicencio

Posted on • Originally published at samurai-developer.com on

Testing Pyramid a Simple Way to Ensure Code Quality

Mike Cohn introduced the concept of Testing Pyramid in his book “Succeeding with Agile.” It is a visual metaphor used to categorize tests into different layers, each with specific characteristics.

Testing Pyramid by levels

Level 1 : Unit Tests

Located at the base of the Testing Pyramid. The fundamental characteristic of unit tests is that they focus on verifying that each unit of code functions correctly in isolation.

What is a unit : A unit is considered the smallest unit of functionality. For example, in the case of a shopping cart, it can calculate taxes, apply discounts, and calculate the total amount to be paid.

Vladimir Khorikov summarizes it well in his book.

“A test should tell a story about the problem your code helps to solve, and this story should be cohesive and meaningful to a non-programmer.”

The main objective of unit tests is to verify that each unit of code functions correctly in isolation.

To achieve this, we need to test all possible inputs of the unit, considering boundary cases and potential errors.

These tests are called open-box tests because we are familiar with the tested algorithm, allowing us to choose inputs that push the unit to boundary conditions and error cases.

Unit tests focus on identifying and correcting component-level errors before they are integrated into the complete system.

As a characteristic within the Testing Pyramid, unit tests are the tests that we develop the most in a project. They should be fast to execute as they accompany us throughout the development of new features and refactors to ensure that the system continues to function as expected at the unit level.

If we have a set of unit tests that take too long to complete, programmers will tend to run them less frequently, making it more challenging to catch bugs. Moreover, it can lead to their decreasing usage as it adds more time to the development cycle.

Level 2 : Integration Tests

Integration tests aim to verify the correct functioning between our systems and third-party systems.

To identify when we need integration tests, we can use the rule that whenever we need to serialize and deserialize data, we will need to perform some integration tests.

This happens in some of the following cases:

  • Calls made to our REST API services.
  • Readings and writings to databases.
  • Calls to APIs of other applications.
  • Reading or writing to message queues.
  • Reading or writing to a file system.

We can divide integration tests into two categories:

  1. Broad: It aims to bring up all external services interacted with, requiring significant configuration and maintenance of the testing environment.
  2. Narrow: It focuses on interacting with a particular external service, while the other dependencies are mocked.

When we refer to Broad Integration Tests, we are talking about a type of closed-box testing where we don’t know how the algorithm is implemented, and we focus more on testing to verify that we get the expected response for certain inputs.

Narrow integration tests focus on testing different interactions between our service and a single third-party service, using mocks based on a predefined and well-documented definition.

These tests assume that the communication contract between modules is correct and aim to find faults in our system with one of the predefined responses.

Level 3 : End-to-End Testing

End-to-End (E2E) tests are aimed at verifying the functioning and performance of a flow in the application from start to finish, simulating real-use scenarios.

In other words, they check scenarios that users will encounter when using the application as if it were in production.

The objective of End-to-End tests is to ensure that the performance is within an acceptable range. They serve to verify that the application continues to function as expected, and our changes have not broken any critical flows in the application.

On the other hand, this type of test is one of the most challenging to develop, as it requires a significant amount of effort and development time due to involving multiple applications at once.

That is why these types of tests are reserved for essential flows in our application that must not fail or degrade.

Conclusions

Although the concept of the Testing Pyramid has been around for many years, it remains relevant today as it helps us define the types of tests we perform, their objectives, and their characteristics, regardless of the language or programming paradigm used.

It is essential to have a good understanding of these concepts and ensure that everyone in the development team shares the same understanding when discussing each type of test will we need.


Samurai Developer Icon

The post Testing Pyramid a Simple Way to Ensure Code Quality first appeared on Samurai Developer.

Top comments (0)