Open Sourcing Our Test Middleware
Testing with microservices is tricky. The behavior you need to support is spread across many different codebases, with their own testing frameworks, deployment processes, and developers. With a platform as widely used as the Medidata Clinical Cloud, it gets even trickier: if there’s any aspect of a service contract you haven’t carefully defined and tested, you’re going to end up breaking some integration.
Today we’re open-sourcing a pair of Ruby gems we developed to help with manual and automated testing in a distributed world.
Fault tolerance testing gets politically fraught with microservices. If you want to see what happens to your app when the discovery service goes down, it’s tempting to just turn off the discovery service in our integration testing environment and see what happens…until the angry mob of developers tracks you down. There’s more than one solution to this problem; increasingly ours has been Aranea. We inject middleware into our API client that can be configured (programatically or through HTTP) to simulate whatever fault, in whatever service, we’re testing tolerance for at the moment. Since it’s in the client, not the server, only your app is actually affected, but it’ll behave more or less as it would if the server were down. It’s a powerful tool (sufficiently powerful that we’ve preemptively written a fair bit of code to ensure it’s never active in production). It’s coded to support a wide variety of use cases, so please check it out on GitHub or RubyGems.
Probity grew out of a misadventure where Rails’s magic XML generation turned against us after a database schema change, creating a non-standards-compliant response some of our integrators couldn’t parse. Since the in-house clients we used for testing were tolerant to slightly eccentric XML, we didn’t catch this as early as we wanted to. We resolved to ensure that all of our API responses parsed properly in strict mode. But how were we to add an assertion every time we served a response?
Well, the same way you do anything else that you want to happen every time you serve a response: add server-side middleware. Rack lets us add arbitrary postprocessing in Ruby to every request we send, and we can easily configure Rails to only use a given middleware in non-production environments. Probity inspects the outgoing JSON and XML responses generated by the app server our tests spin up, and simply raises if it sees anything improper. Whatever test framework we’re using sees a failing response and takes care of the rest.
Probity, too, is highly configurable, allowing you to define validators for any content type you happen to be serving, and is designed to work with any Rack application, not just Ruby on Rails. Give it a try on GitHub or RubyGems.