Lesson 5 of 5
Testing asynchronous event flows
10 min
Listen to this lesson
A synchronous test is easy to read: call, get an answer, compare. An asynchronous flow gives no answer. The test creates a sales order in CMQ and then has to find out, somewhere else and somewhat later, whether the right thing happened. Two techniques make that reliable: correlation, so you can follow one business change through every hop, and eventual assertions, so you wait for an outcome within a time limit instead of guessing.
- ArrangePick a unique business key: a new test order for Great Lakes Fleet Services with a known reference
- ActCreate or change the order in CMQ client 100
- CorrelateFind the event for that order: type, source, id and time in the test broker or consumer log
- Assert eventuallyPoll the fleet portal test API until the update appears, or fail after 120 seconds
- RecordKeep order number, event id, timestamps and the final state as evidence
Correlation
Every hop must log something that ties back to the same business change. The business key (the sales order number) is the anchor testers know. The CloudEvents id and source identify the event. SAP events can also carry SAP-specific tracing information; SAP's documentation shows a sappassport extension attribute used as a tracing identifier in some event packages. Contoso's consumer logs order number, event type, source, id and outcome on one line, so Priya can search the logs, or SAP Cloud ALM's monitoring, by order number and see the whole path.
Eventual assertions, not sleeps
The tempting test waits 30 seconds and then checks. It is slow when the system is fast and flaky when it is slow. Instead, poll for the expected outcome at short intervals until it appears or a timeout expires, and make the timeout match a stated expectation: Contoso's non-functional requirement says a fleet portal update appears within two minutes of the order change in production, so the test fails at 120 seconds. Assert the final state (the portal shows the new delivery date), not intermediate steps nobody promised.
The negative cases are the real test
Happy-path events will work in the first demo. The defects live in the cases lessons 3 and 4 described, and they can only be tested if the test team can produce them on demand. That means test hooks: a way to publish a crafted event to the test broker (duplicate id, old time, broken payload), and a way to stop and start the consumer in cmc-ext-test. Those hooks exist only in test stages and are documented as test tools.
| Test case | How to produce it | Expected result |
|---|---|---|
| Duplicate | Publish the same event twice with the same source and id | One portal update, one email; second event acknowledged and skipped |
| Out of order | Publish Changed, then Created for a new order | Portal shows current order data |
| Consumer outage | Stop the consumer 30 minutes; create 50 orders; restart | All 50 processed; queue drains; none lost |
| Poison message | Publish an event with a broken payload | Lands in the dead message queue; alert raised; others continue |
| Dependency down | Block the S/4HANA destination in test | Retries, then events kept in queue; processed when restored |
| Wrong stage | Create an order in CMQ | No event reaches the production broker or production consumer |
Contoso's asynchronous test catalog for the fleet order notifier.
What would you do?
An end-to-end test of the fleet notifier fails about one run in five with "portal not updated". The test waits a fixed 20 seconds after creating the order. What should the test engineer do first?
- Correlate by business key plus event source and id; log them at every hop.
- Use eventual assertions with polling and a timeout tied to a stated requirement; avoid fixed sleeps.
- Test most cases at unit, contract and component level; keep end-to-end tests few and meaningful.
- Build test hooks to produce duplicates, out-of-order events, outages and poison messages.
- Sign off on negative cases and stage pairing, not on a happy path.
Check your understanding · not graded
Lesson check
1. Why are fixed sleeps a poor way to test asynchronous flows?
2. What should the timeout of an eventual assertion be based on?
3. Which identifiers let you follow one change through every hop?
4. Where should most idempotency and ordering cases be tested?