Optimising Software Testing with the Testing Pyramid
Automated tests are an essential part of continuous integration and deployment as they allow developers to quickly and thoroughly verify that changes are unlikely to cause a regression of existing functionality. The testing pyramid outlines the types of tests that should be included by development teams as well as the relative scale (both in terms of volume and value) of these tests.
Unit Tests
At the base of the pyramid, unit tests should make up the majority of your automated tests. They focus on a specific component, or unit, in isolation and in doing so this narrow scope allows you to focus on a specific area without needing to consider the implications of any dependencies. As such, all dependencies should be mocked to ensure predictable behaviour and outcomes. Because dependencies are mocked you shouldn't need a fully integrated environment to run these tests, which in turn should allow them to run fast, potentially allowing thousands of units tests in a matter of minutes.
You should aim to test all code branches of the component within your unit tests. A good structure for these tests would be to separate them into setting up the data, performing the action, and then verifying the result. A helpful mnemonic for this is "Arrange, Act, Assert", which is based on behaviour driven development's "Given, When, Then".
领英推荐
Integration Tests
In the middle of the pyramid are integration tests, which focus on a logical grouping of components. For mobile apps this could be a screen, for web apps it could be a page and for backends it could be a controller. These tests allow you to verify the entire stack of your application including how they interact with elements outside of your system (database interactions, network requests, etc), although it is fairly common to stub or mock the external interactions to improve the tests performance and ensure predictable results. Due to the increased scope and complexity and longer runtime of integration tests, there should be a lot less integration tests than unit tests.
Integration tests should be used to test specific interactions with your application, and as such should be written using behaviour driven development's "Given, When, Then".
End-to-End Tests
At the top of the pyramid is end-to-end tests. These tests test the standalone application via it's exposed interface (API endpoints or user interface). Whereas integration tests focus on a specific grouping of components, end-to-end tests exercise the entire application following a specific user journey. Because they operate in a fully integrated environment these tests are both the slowest form of test and also the most flaky, requiring increased ongoing maintenance. As such, you should aim to write a minimal amount of these tests. To counterbalance this increased cost of operation, end-to-end tests also provide the greatest amount of certainty that your application is performing as expected.
TL;DR
Automated testing is an essential part of modern software development practices, and the testing pyramid provides a useful framework for organising and prioritising different types of tests. While each type of test has its own strengths and weaknesses, by using a combination of unit, integration, and end-to-end tests, development teams can ensure that changes to an application are thoroughly tested before being deployed while striking a balance between comprehensive testing and efficient use of resources.