Functional testing series
- Blackbox testing microservices
- Graybox testing - Control your dependencies
- Bring functional tests closer to business with Cucumber
- Functional testing of email communication
This post continues the story about functional testing which I referred to in Blackbox Testing Microservices. In that post we had a clear case of testing a system as blackbox as it had input and expected output but all parts of the system were under our control. There were no external dependencies.
Recently, I worked on a project which had social sign on functionality as one external dependency and Amazon S3 image upload as other. We could not test the instance of this service through Rest Api since it internally called this external services. We needed a solution where we could place the external services under our control and give the expected response to our main application when it communicates with them.
We explored some options and decided to go with WireMock. It is a great little tool where you can define URL patterns, POST body, URI query parameters, it will intercept those defined patterns and respond with controlled data. It was exactly what we needed. What is even better is the fact that it can work in two modes, you can pull it as a library and test application will start the WireMock server, or you can download a standalone jar, start the server and use the library which will send mappings to it through internal call. Since we wanted to have flexibility in deployment process and to have fixed address of a mocked server which we can configure both in Rest Api application and functional testing application, we decided to go with standalone WireMock server.
So we started our work. We are running functional tests in an environment dedicated only to that so we changed the external addresses for Facebook, Twitter and LinkedIn apis to point to WireMock server address and port in Rest Api application. Some changes were easy, where we used direct Rest communication, but there were places, such as Twitter, where it was hard to change URL since we used Twitter Api library which wrapped communication, so we had to tweak library configuration for that environment.
The second thing to do was to catch the patterns of all Api calls for each social network and to create patterns with WireMock api. We needed to catch the responses as well to get to know the structure that we must return to our application. Such rule will be sent via the network to WireMock server so it will know what to intercept and what to give as response to Rest Api application.
The third thing was to install WireMock standalone on a separate instance. We created an Ansible role for that and provisioned a clean instance. Our WireMock server got its own IP address and port.
With this 3 step approach we created functional tests, which are doing social sign on requests to our application, we are intercepting calls to social networks and returning controlled data so we can test if the flow on our side of application works as expected. The flow with Amazon is similar to what is explained for social networks.
It was of great help to have this kind of tests in our application since we made sure our part of the integration works, and we added tests which will locally show the errors to developers before deployment to a certain environment. Testing social sign on integration is hard since it must be tested against working application on a social network, which is in some testing environment. This way we are mocking that social network and doing tests early before deployment, which is giving us the confidence to constantly change and improve that part of application. It paid off quite quickly, because we got an additional requirement to pull a profile picture, so we can test drive that, we changed mocked response, changed the application logic and started tests which proved we did the right thing.