Did you know that dead pharaohs can have passports as well? And fly around the world?
Believe it or not, it’s true.
In 1974, Egypt sent a 3.000-year-old body of pharaoh Ramesses II to Paris for preservation and maintenance. But French law required that every person, living or dead, flies with a valid passport. Therefore Egypt was forced to issue the pharaoh a passport. 3.000 years after his death.
Meanwhile in Egypt, one guy tried to took the advantage of it.
This brings us to the main point of this article.
Pyramids.
But not any kind of pyramid, but an automated testing pyramid.
What do pyramids have with testing?
Well, I’m glad you’ve asked.
What is the testing pyramid?
The automated testing pyramid is a visual representation of how to use automated testing in your development process. The idea behind this term is that a pyramid is a really handy tool for understanding or describing how many different tests of each kind you should have.
There are 3 major test levels: unit, integration, and UI level. The testing pyramid suggests that you should have the majority of your tests at the unit level, with fewer tests at the integration level and even fewer at the UI (acceptance criteria or end to end) level.
The testing pyramid is wide at the bottom, so you can get your foundations right with a lot of low-level tests.
You can’t build a great building on a weak foundation. You must have a solid foundation if you’re going to have a strong superstructure.
Gordon B. Hinckley
Then it gradually gets narrower, so as it gets higher you can focus on the higher-level tests that are going to be most useful for your business.
Advocates of the pyramid suggest that having a larger number of unit tests will help ensure that your application is stable and reliable and that having a smaller number of acceptance tests will make it easier to understand what your application is supposed to do. However, some disagree and think that you need more acceptance tests to ensure that the functionality that is implemented works with the rest of the system.
What do I think? I think the pyramid is a pretty good interpretation of how many each kind of test you should have. Unit tests should cover the biggest percentage of the test in your test suite.
The reality, however, is that oftentimes the code you are working with is tightly coupled so it’s impossible to write unit tests at all. In those cases, integration and UI tests are the only weapon you can use to test your application. But the selection of the right testing method for a given project remains one of the most complex problems faced by all developers. You can either choose manual testing or automated testing.
Unit Tests
Unit testing is a vital part of the overall testing pyramid and is used to test small units of code independently to ensure that they work as expected. They are the simplest form of automated tests.
Who should write the unit tests? Unit testing is usually done by developers who have written the code.
Unit testing is vital because it’s the only way to verify that the individual components of an application work correctly. In order to write successful unit tests, the application needs to have a testable architecture. That means that the classes should be decoupled with dependency injection and they should have fewer responsibilities.
Unit testing is an integral part of any successful software development process. It has been proven to save time and money for a number of different industries. It is also important to note that unit testing can be very beneficial for a growing software company.
One way to build a strong unit test suite is by using the practice of test-driven development (TDD). TDD naturally leads to a strong unit test suite because it gives developers no choice but to write tests before code. This means that as new features are added, new tests are created. Unit tests will help developers test small pieces of code. However, unit tests can’t test that isolated pieces work together as expected. That’s where integration tests come into play.
Integration Tests
Integration testing is used to confirm that different parts of an application work together and function as expected.
Due to a number of factors, including the use of open source components and frameworks, and the presence of legacy code, integration tests are frequently used on development projects. In the case of legacy code, integration tests should test the parts of the code that is not possible to test with unit tests.
In terms of complexity, integration tests are more complex than unit tests. And it also takes longer to run a whole test suite of the integration tests than it takes to run unit tests.
Integration tests often check the application’s interaction with the outside world. An example of an integration test would be to see if the application can save and load data to a database or performing a network call.
UI Tests
UI (user interface) tests are a great way to determine if your application meets the requirements of the clients. UI test is also known as end-to-end test (e2e test) or user acceptance test since it covers end-to-end usage of the application. They simulate the interaction that a user would have with the application through the UI layer.
User acceptance criteria are often used to express how the application should be used by an end-user.
What are user acceptance criteria?
User acceptance criteria are a set of rules that the application must meet in order to be accepted by an end-user.
UI tests should be automated as much as possible. Manual testing of the whole application every single time you need to release a new feature would take too long. You can write acceptance tests using the same language as your application, whether it’s C#, Java, or something else. The important thing is to write the tests in an automated fashion so that you can run them at any time to see how your application is doing. And for that, Selenium is one of the most popular choices for writing automated UI tests for web applications.
One drawback of the UI tests is something called flaky tests. Flaky tests are tests that sometimes fail when you run them, but if you re-run them they pass as expected. This often happens because of timing issues.
In conclusion: while UI testing is often ignored or forgotten, it is the responsibility of the product development team to ensure that what is built works for the users. This is the case even if the product is developed by a single person. While developers will find bugs, often the users will find the bugs that will stop them from using the product. And unhappy users won’t continue to pay for a product that has many bugs.
When does it make sense to invert the testing pyramid?
Inverting a testing pyramid means that you have UI tests the most, following by integration tests. In the inverted testing pyramid, there are the fewest unit tests.
The cases where this makes sense is:
- Putting legacy code into test automation – you are trying to add some automated tests to your application, but UI and business logic are tightly coupled. This means that it’s not possible to write unit tests, but you need to start with UI and integration tests. After you decouple UI from business logic, then you might add unit tests.
- Your app mainly calls other API-s – if your application’s logic consists mainly of calling other libraries and/or performing lots of network requests, then it doesn’t make too much sense to write unit tests for it.
- Interaction with the real device – if you are working on an application that will be deployed on a physical device, then you might benefit more from having UI tests that will check the application works fine.
What does the testing pyramid mean for you as a developer?
It means that software quality is a team effort.
You can’t just rely on QA to catch all the bugs all the time, but need to be involved in writing automated tests. That means write a lot of unit tests to check every class works as expected.
After that, check that a feature as a whole works by writing integration tests. And wrap up the test automation cycle with a UI test. Or two.