Test dei microservizi
Due forme di servizi, un contratto di test. I worker service leggono una coda BullMQ, processano, e scrivono su una coda di output; i support service rispondono a chiamate REST. Entrambi sono "dato un input, produrre un output conforme" — cambia solo il trasporto.
Test case dichiarativo
service: document-parser
transport: bullmq # oppure: rest
input: fixtures/invoice-01.json
expect:
schema: schemas/parser-output.json
matches: golden/invoice-01.expected.json
I transport adapter condividono un'unica interfaccia (start / invoke / stop)
così il runner è transport-agnostico.
Requisiti del BullMQ adapter
Listener prima di publish. Se il job viene pubblicato prima, un worker veloce può scrivere il risultato prima che il listener si colleghi, e il test si blocca.
Requisiti completi:
waitUntilReady()sul worker — la fonte più comune di run flaky- Un correlation id esplicito nel payload, propagato dal servizio. Il job di output ha un BullMQ id diverso, quindi l'id del servizio stesso è inutile per il matching.
- Una pending map con chiave per correlation id, così i test concorrenti su una coda risolvono solo le proprie risposte
- Un listener
QueueEventssufailed, così "il servizio ha fallito" si distingue da "il servizio è lento" invece che entrambi vadano in timeout - Teardown rigoroso: rifiuta le promise pendenti, chiudi worker, events e queue — altrimenti i listener zombie si diffondono nei test successivi
- Redis isolato per run (Testcontainers) oppure un BullMQ
prefixper run
Determinismo
Timestamp, UUID e chiamate LLM rompono il confronto con i golden file. Normalizza i campi volatili prima di confrontare, oppure valida schema più asserzioni semantiche invece dell'uguaglianza esatta.
Strumenti consigliati
| Strumento | Uso |
|---|---|
| Testcontainers | Isolamento (Redis per run) |
| Ajv | Conformance dello schema |
| Vitest | Runner e snapshot (emette JUnit XML, consumato da ogni CI) |
| Pact | Consumer-driven contract testing, se necessario in futuro |