Menu

Tijdelijke mailbox-API voor geautomatiseerde tests: aanmaken, pollen, verifiëren

Gebruik een tijdelijke mailbox-API in tests: maak een mailbox via HTTP, poll de bevestigingsmail, lees de code uit en ruim op in CI.

Gepubliceerd

  • automatisering
  • testmailbox
  • continue integratie

Een bevestigingsmail is het deel van een aanmeldingsstroom dat een browsertest niet alleen kan doorlopen. Iets moet een adres bezitten, het bericht ontvangen en de code teruggeven aan de test. Een tijdelijke mailbox-API doet precies dat: de suite vraagt een dienst om via HTTP een mailbox aan te maken, leest wat aankomt en gooit de mailbox weg wanneer het geval klaar is. Er is geen browser, geen gedeelde menselijke mailbox en geen handmatig kopiëren en plakken.

Dit artikel gaat over de API-kant van die opzet. Het gaat niet over het richten van je applicatie op een lokaal ontvangstpunt: dat is e-mail vastleggen in CI, en de twee lossen verschillende problemen op. Lokale opvang bewijst wat je applicatie verzendt. Een mailbox-API bewijst wat werkelijk aankomt, via een echt bezorgpad, op een adres dat de test bezit.

Waarom een mailbox-API in tests gebruiken?

Omdat het alternatief een echte menselijke mailbox is, of niets.

Een gedeelde mailbox is een slechte fixture. Meerdere runs lezen dezelfde mailbox, berichten van een eerdere run staan er nog, en het adres verzamelt verkeer dat geen enkele test heeft gevraagd. Elke assertie moet dan raden welk bericht bij het huidige geval hoort, en in dat raden ontstaat flakiness.

De webinterface van een provider met een browser oogsten is de tweede slechte optie. Het maakt de test afhankelijk van markup die zonder aankondiging verandert, van sessiestatus en van een login waar de suite op moet letten. Zodra de provider een knop restyled, wordt een groene suite rood om een reden die niets met het product te maken heeft.

Een mailbox-API haalt beide problemen weg. Het adres wordt voor het geval aangemaakt, het is leeg van nature, en het wordt gelezen via een stabiele interface die de test direct kan aanroepen. De suite geeft niet langer om hoe de provider eruitziet, alleen om of het contract standhoudt: aanmaken, ontvangen, lezen, verwijderen.

Er is ook een privacyargument. Een adres dat via een API is aangemaakt, staat voor niemand. Het is niet iemands mailbox, het is geen plek waar een echt bericht zou kunnen landen, en het wordt met de run weggegooid.

Welke eindpunten heeft een test echt nodig?

Een mailbox-API kan tientallen routes bieden, maar een testclient heeft vier bewerkingen nodig, en het helpt ze te benoemen zoals de suite ze gebruikt.

Aanmaken geeft een adres en een handle terug. Het adres is waar de applicatie onder test naartoe moet sturen. De handle, vaak een token of identificatie, is wat de test gebruikt om in elke latere aanroep naar die mailbox te vragen. De suite moet het paar als één object behandelen en de handle nooit reconstrueren uit het adres, want providers mogen de twee los van elkaar maken.

Lijsten geeft samenvattingen in plaats van bodies: één regel per bericht, met een identificatie, de afzender, het onderwerp en de aankomsttijd. Dit is de aanroep die een poll-lus moet gebruiken, want hij is goedkoop en volstaat om de enige vraag te beantwoorden die vroeg telt: of er al iets is aangekomen.

Lezen geeft één bericht volledig terug, inclusief het tekst- en HTML-deel. Daar leeft de code, en dit is de aanroep die pas moet gebeuren nadat lijsten een overeenkomst heeft gemeld.

Wissen verwijdert de berichten uit een mailbox of verwijdert de mailbox helemaal. Een test heeft het om twee redenen nodig: om tussen pogingen te resetten zonder een nieuw adres aan te maken, en om op te ruimen wanneer het geval eindigt.

Sommige diensten voegen een wacht- of long-poll-eindpunt toe dat de verbinding vasthoudt tot een bericht aankomt of een time-out verstrijkt. Het is handig, maar een client moet nog steeds kunnen terugvallen op lijsten, want de wachtaanroep is het deel dat het vaakst wordt beperkt door rate limits.

Pollen op de code zonder flakiness

De meest voorkomende fout in dit soort test is een vaste slaap. Een constant aantal seconden is een gok: te kort wanneer de bezorging langzaam is, verspillend lang wanneer ze snel is, en in beide richtingen fout op een belaste CI-runner. Vervang het door een lus die lijsten aanroept, op een overeenkomst controleert en terugkeert zodra er een is gevonden, met een plafond dat de test laat falen in plaats van de job te laten hangen.

Het matchen is de tweede helft van het probleem. Het bericht dat de test wil, is het bericht aan het adres dat het geval heeft aangemaakt en, als de mailbox meer dan één soort mail kan bevatten, dat waarvan het onderwerp een stabiel fragment draagt. Geef de voorkeur aan de nieuwste overeenkomst, zodat een dubbele bezorging door een herhaling het lezen niet in de war brengt. Neem nooit klakkeloos het eerste bericht; op een hergebruikt adres wordt zo precies een oude code gevalideerd.

Het extraheren moet verankerd zijn. Een body kan een referentienummer, een tijdstempel en een prijs bevatten, en een parser die de eerste reeks cijfers pakt, pakt soms een daarvan in plaats van de code. Zoek de formulering die de code inleidt, lees de code uit zijn omgeving, en faal met de body eraan gehecht wanneer niets overeenkomt.

Respecteer ten slotte de limiet voor opnieuw verzenden. Een codestroom staat meestal maar een paar verzendingen in een kort venster toe, en die limiet is deel van het gedrag dat wordt getest. Een test die opnieuw op de knop drukt voor een verse code wordt uiteindelijk geweigerd en faalt om de verkeerde reden. Herhaal door de mailbox opnieuw te lezen, niet door nog een bericht te triggeren.

Het inbedden in een end-to-end- of CI-suite

De schone vorm is een fixture. Voordat de stroom begint, maakt de fixture een mailbox aan en geeft het adres terug. De test stuurt de applicatie met dat adres. Nadat de applicatie bevestigt dat ze iets heeft verzonden, leest de assertie de mailbox en haalt de code eruit. Wanneer het geval eindigt, verwijdert de fixture de mailbox.

Houd de client klein en injecteerbaar. Eén module wikkelt de vier aanroepen; de test hangt af van die module, nooit van rauwe HTTP die door de suite is verspreid. Dat maakt het mogelijk om in unittests een dubbel in te pluggen en dezelfde suite op een andere provider te richten zonder asserties te herschrijven.

In CI horen inloggegevens in de secret-store van de job, nooit in de repository en nooit in een logregel. Geef elke job of elke parallelle worker zijn eigen mailbox, en zet voor gegenereerde adressen een prefix dat de run identificeert, zodat een verdwaald bericht door inspectie kan worden toegewezen. Zet de time-out van de client onder die van de job zelf, zodat een vastgelopen poll faalt met een duidelijke melding in plaats van een abrupte annulering van de job.

Herhaal het lezen, niet de hele stroom. Als de code nog niet is aangekomen, wacht en lees opnieuw; de registratie opnieuw doen zou een tweede bericht opleveren en daarmee een tweede kandidaat voor de assertie. En houd de mailbox-API buiten productiestromen: het is testinfrastructuur, en een suite zou nooit naar een echte klant mogen kunnen sturen vanuit die API.

De stroom rond de code, in plaats van de mechanica van het lezen ervan, wordt behandeld in testen van de e-mailverificatiestroom, en de parseerstap in het bijzonder is het onderwerp van OTP testen in end-to-end suites.

Isolatie en opruimen

Eén adres per geval is de regel die de meeste fouten tussen tests voorkomt. Het haalt de noodzaak weg om te redeneren welk bericht bij wie hoort, en het laat de versheidsvraag verdwijnen, omdat de mailbox alleen ooit het verkeer van één geval heeft ontvangen.

Opruimen moet expliciet en onvoorwaardelijk zijn. Verwijder de mailbox in een teardown die draait of het geval nu slaagt of faalt, niet alleen op het gelukkige pad. Alleen op de levensduur van de provider vertrouwen is een fout: het bericht kan lang genoeg blijven om door een latere run op dezelfde machine te worden gelezen, en die levensduur is een gemak, geen garantie.

Als het opruimen faalt, log het en laat de suite eindigen. Een opruimfout is het waard om te weten, maar het is niet hetzelfde als een productdefect, en de run erom laten falen leert het team om teardown-fouten te negeren. Behandel alles wat het adres heeft ontvangen als testdata: het bestaat voor één assertie, het mag niet worden geëxporteerd of gedeeld, en het mag nooit als iemands contactpunt worden beschouwd.

Limieten en kanttekeningen

Een mailbox-API blijft een afhankelijkheid van derden, en zijn limieten worden de jouwe. Rate limits per minuut kunnen een reeks aanmaakacties uit een grote parallelle run weigeren. Quota beperken hoeveel adressen tegelijk bestaan. Berichten kunnen vertraagd zijn, en een vertraagd bericht ziet er precies als een ontbrekend bericht uit tot het aankomt.

Wegwerpbare domeinen zijn bovendien breed geblokkeerd. Het domein van een provider kan worden geweigerd door precies het aanmeldingsformulier dat je test, wat een legitieme test in een verwarrende fout verandert. Wanneer dat gebeurt, is het antwoord niet om de provider als uitzondering te behandelen, maar om te begrijpen of het product onder test wegwerpbare adressen bewust weigert, en dat gedrag dan bewust te testen.

De eerlijke samenvatting is dat de mailbox-API het juiste gereedschap is om te beweren wat aankomt. Om te beweren wat je applicatie uitzendt, is een lokaal ontvangstpunt sneller en heeft het geen quotum. De meeste volwassen suites gebruiken beide: lokale opvang voor het merendeel van de asserties, en een mailbox-API alleen waar het echte bezorgpad het ding is dat wordt getest.

Volgende stappen

Zoek een test die een code leest door een gedeelde mailbox te pollen en vervang hem door een fixture die een vers adres van een mailbox-API aanmaakt. Log het adres met de run, verwijder het in de teardown, en kijk hoeveel van de flakiness die je had geaccepteerd gewoon ophoudt. Wanneer je met de hand een echte mailbox nodig hebt, maakt de tijdelijke mailpagina er in een ogenblik een aan, en de adressen die hij uitgeeft zijn steigers voor een run, nooit een echte identiteit.

Verder lezen

Handleidingen over Tijdelijke e-mail (wegwerp-e-mail / e-mail van 10 minuten)