Microservices architecture is a concept that is slowly starting to expand its influence. Using a microservice architectural style involves developing single applications that are able to work together as a suite of small services, each running in its individual process and communicating with lightweight mechanisms.
Contrary to a monolith architecture, a microservices architecture allows its services to be deployed independently by machinery that supports fully automated deployment.
Hence, experts in the industry tackled the rising importance of automated testing for microservices and its future.
What is microservices testing?
A microservice is an autonomous independent service that encapsulates a business scenario, Venkataraman Purushothaman, Automation architect at the U.S. Bank, tells me. It contains the code and state. Usually, a microservice even contains its own data store. Hence, this makes it independently versionable, scalable, and deployable. They are loosely coupled and interacts with other microservices through well-defined interfaces using different protocols. They remain consistent and available in the presence of failure.
Guillermo Toro-Bayona, Software Developer at Nando’s, adds that Microservices is one of many software architecture styles in which the strategy is to have simple, small, and concise pieces of software focusing on solving problems in a particular part of a business domain. These services should be easy to extend, modify, test and deploy in order to increase the speed in which an organisation adapts itself to different changes, caused by either customer needs, new regulations, aggressive business competitors, etc.
Microservices architecture allows organisations to quickly adapt to change and reduce their time to market, by offering a simple and more manageable way to modify the software that supports a particular area of a business model. Usually, microservices go along with a complete strategy of Continuous Integration (CI) and Continuous Deployment (CD), giving the business a flexible way to deploy new versions of services by increasing the cadence of software releases.
Ajay Thakur, Manager Quality Engineering at Publicis Sapiens, also defines microservices as an architectural style that takes every application function and puts it in its own service (provided the function is suited to run as an application) and runs on a container, and these containers communicate over API.
Put it more simply, it is a collection of services that are: loosely coupled, independently deployable, maintainable, testable, and organized around the business feature.
In order to make it clear, let’s take the example of an application (for instance, Amazon), and compare Monolith Vs Microservice. For simplicity, let’s group the website into some basic components like front-end, user profile management, payments, search, etc, as you can see on the figure below:
According to Guillermo, running different types of tests on a microservice increases the confidence of the organisation in releasing software. Indeed, if a service is deployed many times during the day or week, it should be with the guarantee that it will not affect current customers, it will not disrupt business strategies and it will not break other software integration. The only way to increase that confidence in this strategy of continuously releasing software is with testing.
There are many types of tests involved in a microservices architecture. Initially, you can think of some sort of Unit Testing to make sure the service is doing what is expected to do. The microservice functions and algorithms are working as expected with some given input. This is vital to get some confidence that the code is working.
In addition to Unit Testing, you could add another type of test to make sure your microservice is working as a whole, not individual functions or modules in isolation. Integration Testing helps you to test the microservice once all the internal modules are working together. Using mocking tools helps your tests to see how the microservice will react to different integrations and how it will cope with failure and success on those. Depending on the type of integrations you could either simulate failures when trying to connect to a database system over the network or reaching a timeout on an HTTP endpoint of another service, lack of permission on a file system, etc.
Another type of testing is End-To-End Testing, which aims to test the microservice in a bigger picture, testing the microservice as a black box to see if it has fulfilled the business expectations. The microservice and all its integrations are in a controlled environment in which we can observe the behaviour. This type of testing usually covers as many potential flows as possible. A microservice could call third parties, external systems, other microservices in order to solve a particular problem within an organisation. This kind of test verifies the microservice and its integrations are working together to achieve a business goal.
These tests are essential in a microservice architecture in order to give enough confidence to the business that a new release of the service will not disrupt or affect the organisation. There are other types of tests such as load testing, stress testing, contract testing that help to identify other aspects of the microservice and its expected behaviours.
Moreover, Ajay adds that, to effectively test microservices, you must know the concept of ‘TEST PYRAMID’. It’s a great visual depiction of different layers of testing with how much testing on each layer.
The original test pyramid had only three layers (Unit, Service, and UI tests), however, it is not appropriate in the current world of microservice testing and, thus, can be misleading. That is why, it is important to understand your test requirements and build the pyramid based on that, covering all aspects of testing. Hence, here is the test pyramid the most widely used in the industry:
Venkataraman points out that microservices are fine-grained and self-contained in the nature of APIs, these are independent components and are ready to be tested in isolation.
Indeed, there is a requirement to reduce business risk due to early testing of interfaces and their interaction in absence of UI availability. As several new services are been built to support interaction with existing services, there is a need to test all the services across multiple interfacing applications. With microservices breaking things down into components that are easier to design, manage, and deploy, there are a lot more of these smaller APIs to test. Microservices Architecture is for applications, or their components, that are likely to change frequently. Hence, there is always a need to test these services before moving to the next testing phase.
Microservices architecture allows multiple customers to connect from multiple channels (WEB/Android/iOS), this arises a need to test the Microservice endpoints thoroughly for different source systems.
The best approaches
Given the importance of testing in a microservices architecture, testing is vital in different parts of the whole releasing cycle of a microservice.
Indeed, Guillermo underlines that the releasing cycle is usually part of the strategy of Continuous Integration (CI) and Continuous Deployment (CD) pipelines. Within these pipelines, the whole process of compiling, packaging, and installing a microservice is orchestrated in different steps.
Unit Tests are essential once a new version of the software has been released by a developer in order to make sure the code is correct. No new microservice artifacts (such as container images, packages, libraries, etc.) should be produced if the Unit Tests are failing. Integration Tests could also be included as part of these initial steps in order to verify different integrations via mocking tools. Once these two types of tests are successful, the microservice artifact could be released for the next steps in the pipeline.
End-to-End Tests require that the artifact of the microservice is available for testing in a controlled environment where other integrations within the infrastructure could be tested. Once the End-To-End testing is successful, it is a good indicator that the microservice is working as expected. The Continuous Deployment (CD) will be in charge of installing and deploying this new microservice artifact with a good degree of confidence.
For Ajay, here are the best approaches according to the various types of testing:
|Types of Testing
|Mocha, Jest, Junit, etc.
|Component Level Test
|Karate, Supertest, nock, MockServer
|System Integration Test
|Karate, Supertest, nock, MockServer
|· Webdriverio with Cucumber JS, Mocha
· Selenium Webdriver with Cucumber JVM
· Selenium Webdriver with Behave
|Gatling, Jmeter, Taurus
Venkataraman shares this figure to explain the best approaches to test microservices:
Why would businesses adopt automated microservices testing?
Industry leaders (like Netflix, Amazon, Apple Care, etc.) and many other businesses had and have recognized the need for continuous and sustainable innovation, and which is why they’ve either already moved away or moving away from monolith applications as it slows down their plan of incremental and fast improvements to applications in response to market demands.
Indeed, as Ajay points out, with a monolith, any new feature added to an application requires substantial time and resources to build and deploy, thus shunts the ambition of fast innovation and implementation.
On the other hand, Microservice offers the capability to construct applications with a functional approach with multiple distinct services rather than running everything inside one single application.
Besides, Guillermo emphasises that organisations want the software to support their strategies by solving complex business problems. Microservices help organisations to solve those problems with many small pieces of software working altogether. Changing a microservice could affect the way those complex problems are solved. Testing is one of the strategies that organisations have to get a good degree of confidence on how changes in microservices will not affect or disrupt an important part of the business. Testing is then a key factor in a microservice architecture.
However, Venkataraman warns that going for this approach might not be for everyone. Indeed, he points out that due to distributed deployment, the volume of testing can be high, and the test team might have to deal with the complexity of a distributed system.
Moreover, he continues, this architecture brings additional complexity as the tests have to mitigate network latency, and deal with a variety of message formats as well as load balancing. The increased number of services may also result in information barriers and in duplication of effort.
Thus, he recommends to businesses automate from day one in order to build resilience and get teams moving fast. By automating the release process, you will achieve frequent releases and get codes to flow freely through continuous integration pipelines. He also advises a lot of groundwork, communication, and cooperation between different teams in order to better handle use cases.
According to Venkataraman, automated microservices improve fault isolation and eliminates long-term commitment to a single technology stack. Besides, it can also make it easier for a new developer to understand the functionality of a service as well as allow independent scalability and deployment, which are sure to be more resilient.
For Ajay, the biggest advantage of microservices is that it’s easily deployable (independently) and maintainable (with the right infrastructure set up).
With microservices test automation, you can have:
- Feature-focused design and continuous delivery: It gives the ability to break down an application’s large number of services into smaller, distinct parts, which enable teams to easily work on one part without affecting the others. Thus, it speeds up the CI/CD process.
- Faster time to market: Decoupling of services gives enormous flexibility to teams to innovate and add new features which can be easily developed, tested, and deployed
- Improved scalability: As services are decoupled, it’s easy to horizontal scaling each component independently in case of high demand. Unlike monolith, you won’t have to scale up the whole application
- Increased Resilience & Security: Unlike monolithic architecture, where a single failure affects the whole application, microservices limit the blast radius and easy to recover. Similarly, a security breach in one microservice does not impact the security of other microservices
- Multiple services-Different Platforms: With microservice, different services can be easily developed on multiple stacks and deployed on different platforms
Guillermo points out that testing microservices is definitely a good thing to do. Testing will help to increase the level of confidence in how changes to isolated services will be nicely integrated into the whole digital strategy.
It will also give the organisations more confidence to change and adapt their business rules quickly by offering new products to their customers in a fast-paced challenging environment, without affecting or disrupting existing customer or other systems integrations to support their business value chain.
…And the challenges
The co-founder and CTO of Contino, Benjamin Wootton, says that “microservices are not a free lunch”.
Indeed, Ajay emphasizes that microservices popularity is primarily because of the ongoing trends such as Cloud, DevOps, and Continuous Delivery coming together as enablers, backed by the great work done by Netflix, one of the pioneering case studies in recent time. Therefore, although microservices have lots of significant benefits, it is vital to understand the complexity it brings to the table with ‘managing these services and orchestrating business processes with it’.
Here are some of the complexities of Microservices implementation:
- Operations overhead: Monolith application can be deployed to small application server clusters, but with microservices, you will need cluster for failover/resilience for each service, followed by seeing up load balancers and messaging layers between the services, and all of it needs high-quality monitoring and operations infrastructure
- Strong DevOps Skills Required: Operations challenges of keeping Microservices up and available mean you definitely need highly skilled DevOps and automation skilled development team
- Overhead of component management and Release risk: In a Microservice world, a simple change might end up require changes to many different components, all needing to be released in coordinated ways. Thus, releasing one new feature might force you to release many other services as well, and adds the additional release risk
- Distributed System Complexity: With a distributed system, you will have to reckon Network latency, unreliable networks, asynchronicity, versioning, varying loads, etc. which is not there with a monolith
For Venkataraman, the challenges are that:
- Large numbers of microservices are difficult to orchestrate,
- Understanding, managing, and testing dependencies is difficult,
- Software patterns (encapsulations and such) do not provide a uniform service abstraction,
- Message flow increases with the number of microservices and hampers performance,
- Service interface versioning needs to be managed for multiple services.
The different types of tests require a big effort from the engineering and technical team. However, Guillermo warns, a robust testing strategy is not only affecting technical people within an organisation. It will require product owners and different stakeholders to get involved with different inputs on how the microservices should work in a given scenario, how the whole digital strategy should be affected by one change in a microservice.
These inputs will help to have a clear high-level picture of the microservices within the organisation and how all of them support the business strategies. Hence, it might be difficult to get all of these inputs from different areas of the organisation. It might also require a good amount of time and effort to create a robust testing strategy in the organisation and mix it up within the Continuous Integration and Continuous Deployment strategies.
The future of automated microservices testing
Ajay believes that it depends completely on the growth of adoption of Microservice implementation in the Industry.
According to a survey conducted in 2018 by Bernd Rücker about digital transformation initiatives, 63% percent of 354 questioned enterprises have shown an inclination of getting into microservices. Tech giant Netflix was one of the trend seers of the microservice implementation, and later on, other companies like Amazon, Uber, SoundCloud, and eBay followed the footprints of Netflix. Former CTO of eBay, Steve Fisher, once said eBay utilizes more than 1,000 services.
Similarly, Google trends also suggest that interest in moving from Monolith to Microservice has grown steadily through 2018 all mid of 2019, and then it peaked in Jan 2020. However, there was a small dip late in the year 2020 which is likely to go up again in the coming years.
For Ajay, as the adoption increases, the adoption of automated microservice testing will play a crucial part in the coming years for the testing industry.
Venkataraman thinks that improvements in software architecture have led to fundamental changes in the way applications are designed and tested.
Hence, making sure that the required amount of testing is focused at the right time, with the most suitable tools, would ensure that organisations are able to deal with testing in such an environment and meet the demands of the customer. A consumer driving approach is suggested as it is a better way to mitigate risk when services are exposed to an assorted and disparate set of customers and it further helps to deal with changes without impacting the customer.
Guillermo believes that adapting business digital strategies quickly will give an advantage to an organisation to reduce its time to market, to put in place new products and services before its competitors, or adapt quickly to new regulations.
All of these fast pace changes need to be supported by a flexible and robust digital strategy that gives confidence to organisations on adapting fast. Testing within a microservices architecture is one way to achieve a high level of confidence in adapting your software to support your business strategies.
Special thanks to Guillermo Toro-Bayona, Venkataraman Purushothaman, and Ajay Thakur for their insights on the topic!