How to test AWS Event Driven Serverless Applications
For serverless architectures the adoption of event-driven architecture is the preferred methodology.
One key element in implementing event-driven serverless architectures is the frequent utilization of message services such as Amazon Simple Queue Service (SQS) and Amazon Simple Notification Service (SNS). These messaging services play a crucial role in establishing reliable and efficient communication channels between different components.
But at the heart of many serverless architectures, you’ll often find Amazon EventBridge, serving as a central hub for the distribution of events to various services or microservices. This centralized mechanism facilitates seamless event distribution, ensuring that relevant services are appropriately triggered and responsive to the events they receive.
In serverless architectures the testing often leans more towards integration testing rather than traditional unit tests. This shift is attributed to the nature of serverless applications, where components are often interconnected, and the overall functionality relies on seamless collaboration between various services.
Testing event-driven applications poses challenges compared to synchronous counterparts, primarily due to the asynchronous nature of interactions. The decoupled and asynchronous nature of events requires specialized testing strategies.
This article describes how you can write integration tests for event-driven architectures that use Amazon EventBridge as the central event distributor.
Challenges
Testing asynchronous functions demands a different test design approach. In an asynchronous environment, calls occur in response to messages. For the integration test the service should be tested in isolation by using its interfaces and inspecting produced events without looking into implementation details of the service.
Within the testing framework, it is imperative to verify whether the service under test is dispatching the correct events to EventBridge. Therefore, the test must have a mechanism to retrieve the recorded events and subsequently validate their correct arrival in EventBridge.
Another problem that needs to be solved arises when events that are produced by the service under test are written to EventBridge. Any registered consumer associated with these events initiate processing, potentially generating additional events and triggering other services. Therefore the propagation of all events written during a test to EventBridge to other consumers must be prevented.
Solution
To verify whether a service under test generated an event, you can subscribe CloudWatch to EventBridge. In an integration test, the testing client can monitor all events generated in the CloudWatch log group and confirm the production of the correct event.
To stop propagation each test http call to the service should contain tracing details with a test flag that includes the service name under test. Whenever the service writes an event it should include the tracing details in the event. Consumers can use a subscription filter to exclude any events with a test flag containing a service name that does not match their own.
Conclusion
Testing event-driven serverless applications presents its challenges, often requiring a shift towards more integration tests. In this blog post, we focused on how a service under test produces the correct event and publishes it on EventBridge and how to avoid test event propagation.
An easy way for verifying event transmission to EventBridge involves subscribing a CloudWatch log group to capture all events. Subsequently, the integration test can poll the log group until the targeted event is identified.
To stop event propagation, each test event should incorporate tracing details with a designated test flag and the specific service name under test. This approach allows other services to filter out these events.