I have an application with RabbitMQ that makes each Rest flow asynchronous and I’m struggling with creating tests for that
How can I create tests for microservices backend applications that rely on async communication? Is there any tool for that?
Thanks :)
CodePudding user response:
This is a real pain. Asynchronous communication makes testing microservices environments much harder, there is no accessibility to the status codes and exceptions. “layers” to applications like that make it harder to create tests.
You have a few options if you want to create tests:
1. Log-based Testing
You can add logs for each operation in the different services, then, you can fetch the logs from those services and validate that the relevant data exists.
There are a few challenges with this approach:
- You assume that the developer added logs for the operation you want to validate, which is not always true.
- You can only validate the data that was written in the logs. If, for example, there are no written payloads of a request to the logs, they can’t be validated.
- You are coupling logs and the tests – which sounds like a perfect way to create flaky tests.
- You are testing only the logs of the operation and not the operation itself. As a result, we don’t know if the operation succeeded.
2. DB Querying
By saving the operation indication in DB, the DB can be queried during the test to validate if it exists.
There are a few issues with this approach:
- You need to expose the database to the tests project, which sometimes requires heavy lifting.
- You need to engineer the database for the tests, which is overengineering and not the focus of our work, making it a weird thing to do.
- You coupled our DB model to the tests, which is logically wrong. And again, just like with the previous log solution, you are testing the DB object update operation and not the actual operation, which is entirely wrong and can’t detect any real issues.
3. Trace-based testing
Instead of over-engineering your applications to make them testable, I suggest a new paradigm that popedup in the indusdrty that doesn’t require any engineering to your code. This way is built upon traces.
Traces are an aggregation of all the operations. Operation in a trace called Span and it's represent any communication between components.
With searchable trace, you can search and validate all kind of spans . This makes it easy to approach each operation and see it as part of a whole, and not as an individual action.
In addition, traces can be created automatically, without a developer having to decide where to insert them, unlike logs.
You can read more about trace base testing here