Skip to main content

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

Regola critica

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 QueueEvents su failed, 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 prefix per 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

StrumentoUso
TestcontainersIsolamento (Redis per run)
AjvConformance dello schema
VitestRunner e snapshot (emette JUnit XML, consumato da ogni CI)
PactConsumer-driven contract testing, se necessario in futuro