Microservices- The right way to test it
Everyone is transitioning to Microservices, so let’s understand how to test it
It isn’t new that we try to build our entire world as small autonomous units, so that we can construct larger projects out of them. Woodworkers combine several types of wood, creating the desired texture from the composition. Vehicles are comprised of different independent parts manufactured in different places around the world, and assembled in different types of vehicles, some of which use the same parts. If we look even closer to home at the human body, medicine and technology have already succeeded in making autonomous parts that can be replaced as needed in specific people.
Here too, in the IT world, we aim at developing autonomous software parts, which can function as independent, separate units. It’s important to emphasize that the transition to separate independent units has completely influenced our field – the testing world. However, before we move on to the testing world, let’s understand the changes in the development world.
What have we had until now? A monolithic environment.
A monolithic object, according to the dictionary, is a statue or building made of one slab of stone.
Although we’re not a statue, this definition applies to a monolith development environment-
One Service code base, one host, one DB, and unified technology (for example, when everything is written in the same development language).
In the monolithic method, all parts link to each other, so that different developers’ codes cannot be combined. Each part for which a commit is carried out needs to be tested, to ensure that it doesn’t compromise other parts in the environment.
What does Microservices development mean?
Each MS (Micro Service) is written completely independently. Some have their own DB, meaning that maintenance changes or expansion is carried out for each service separately, without any change and/or influence on other services. The service can be written in a different language or platform, as long as it can be connected to other services via a RestAPI interface, where parameters can be sent via a Jason and/or YAML file, and the required data can be received.
MS development reinforces all the methods and innovations in the modern development field. The automated DevOps process and the use of the Continuous platform is a MUST, because new services are constantly launching simultaneously, so everything needs to be automated, and we haven’t even started to speak about working in Agile mode.
So… Let’s move on to our main topic, the testing field, shall we?
So that we’re on the same page, let’s first present the pyramid that describes the Testing Life Cycle (TLC) related to the MS. Note that the description of the pyramid indicates that as we advance to the top of the pyramid, the less effort we need to invest.
Let’s move on to explain each stage – what it means, and how it affects the next stage in the pyramid.
This isn’t the regular unit test that we’re familiar with, because this includes a platform that also manufactures single and independent units, and the unit test is divided into two parts:
1. Solitary Test – single unit tests – as can be seen in the chart below.
Such tests are suitable for separating the units that need to be tested, without involving the other units. These tests are the most efficient in terms of speed and cost.
2. Sociable Test – unit tests based on other units, to achieve the desired functionality.
These tests don’t separate the test units, but rely on other units that must be part of the testing. For example: for running any business process, or for conducting a functionality test that relies on the functionality of other units.
This type of testing allows us to conduct an E2E test and/or an entire business process, by running several units simultaneously, when in fact, the test is for one single unit that connects with other Virtual Services units. Meaning, the other units have not been completed or developed in full, and they can still be simulated by Service Virtualization.
There are several tools that may help us simulate Services for testing purposes:
A contract between the single units, or between the template and the service, as demonstrated in the next example:
A contract between Consumer A and the provider indicated in the contract – in this case, we have 2 fields: first name and email.
Note that the contract between Consumer B and the provider is different, which means that in this contract, we have 3 fields: first name, last name, address. Why do we need these tests, what do they cover, and why should we deal with this?
So why do we need this?
First, testing is a must. It’s necessary to ensure that the structure of the communication between the various units remains the same. For each change in the structure, there must be a test to verify that the tested functionality has not been damaged by the communicated structural change between the different units.
What do the tests cover?
The units can communicate with each other within a fixed and established structure. These tests are a preparation for the E2E. When the system is based on communication between units in an API structure, it is not possible to progress to E2E tests that represent the running of the required functionality without checking that the request and answer structure is the required structure.
How would it benefit us to deal with this?
Contract testing is very easily implemented and can prevent failure of test runs and unnecessary investigations. The tests can be carried out with tools, such as Post Man. You only need to run the API and ensure that the structure required in the JSON file is received. The running and testing are simple, and can be developed and run very quickly. Below are some examples of contract testing.
Note that contract testing is not the system’s functionality testing, but a data structure test. Note the following example:
* cDc = Consumer Driven Contract test
There are several recommended tools that can be relevant to this topic:
Integration and E2E Test
After all possible types of tests are completed, E2E tests and the traditional integration work must be carried out to ensure that the desired functionality is achieved. Note that most tests at this stage can be associated with API tests in order to shorten processes and test durations in particular, and streamline the process as a whole. When we check the MS in these types of tests, we ensure the integrity of the system as a unit, and the MS is referred to in the analysis stage in the event of failures, to know how to crack the Root CA.
We will now move on to the last and best stage, which is Canary Testing. What is Canary Testing, and how is it related to canaries?
These are tests that are conducted at the manufacturing stage, or right before production. A team is appointed to work in the production area, and the new version is launched, but only for part of the testing environment (2 tracks for example). The new features are tested at this stage. The team running the tests will notify right in the production environment whether it is advisable to launch the new features or not.
So, what’s the connection to canaries, and how is this related to coal mines?
Canaries used to serve in coal mining to alert the miners when toxic gases reached dangerous levels. A small group of end users chosen for the test serve as ‘canaries’, and provide an early alert regarding problems. As long as the canaries continued singing, this meant they had enough air to breathe, and when they stopped singing the coal miners knew they had only a few moments to run out of the mine.
So what do we have here?
Monolithic environment – Out. From now on, we speak the Microservices language, working with separate autonomous units in the development environment. The units are tested with emphasis on the Shift Left in the direction of the Unit Test, and here too, because of the connection between the different MS, they can be tested as autonomous units, and as one connected and affected by the other MS. Remember the component testing that provides us with the ability to test before all MS are ready for action, and the Contract Testing that will save many bugs with a simple testing method, that is critical in the MS environment. Then, remember the Integration, the E2E, and finally, the Canary Testing.
I hope this helped you, and that we all continue to enjoy the testing and produce better and quality products.
Lior Katz, CTO, Matrix Testing and Automation