Menü

Temporäre Postfach-API für automatisierte Tests: anlegen, abfragen, prüfen

Temporäre Postfach-API in automatisierten Tests: Postfach per HTTP anlegen, Bestätigungsmail abfragen, Code auslesen und in CI aufräumen.

Veröffentlicht am

  • Automatisierung
  • Testpostfach
  • Continuous Integration

Eine Bestätigungsmail ist der Teil eines Anmeldeablaufs, den ein Browsertest nicht allein fahren kann. Etwas muss eine Adresse besitzen, die Nachricht empfangen und den Code an den Test zurückgeben. Eine temporäre Postfach-API tut genau das: Die Suite bittet einen Dienst, per HTTP ein Postfach anzulegen, liest, was ankommt, und verwirft das Postfach, wenn der Fall erledigt ist. Es gibt keinen Browser, kein gemeinsames menschliches Postfach und kein manuelles Kopieren und Einfügen.

Dieser Artikel behandelt die API-Seite dieser Anordnung. Es geht nicht darum, Ihre Anwendung auf einen lokalen Empfangsendpunkt zu richten – das ist E-Mail in CI abfangen, und die beiden lösen verschiedene Probleme. Lokale Aufnahme belegt, was Ihre Anwendung versendet. Eine Postfach-API belegt, was tatsächlich ankommt, über einen echten Zustellweg, an einer Adresse, die der Test besitzt.

Warum eine Postfach-API in Tests verwenden?

Weil die Alternative ein echtes menschliches Postfach ist oder gar nichts.

Ein geteiltes Postfach ist ein schlechtes Fixture. Mehrere Läufe lesen dasselbe Postfach, Nachrichten eines früheren Laufs liegen noch dort, und die Adresse sammelt Verkehr an, den kein Test angefordert hat. Jede Prüfung muss dann raten, welche Nachricht zum aktuellen Fall gehört, und im Raten entsteht Flackern.

Die Weboberfläche eines Anbieters mit einem Browser abzuernten ist die zweite schlechte Option. Sie macht den Test abhängig von Markup, das sich ohne Ankündigung ändert, von Sitzungszustand und von einer Anmeldung, die die Suite beaufsichtigen muss. Sobald der Anbieter einen Knopf umgestaltet, wird eine grüne Suite rot, ohne dass es mit dem Produkt zu tun hätte.

Eine Postfach-API beseitigt beide Probleme. Die Adresse wird für den Fall angelegt, sie ist von Natur aus leer, und sie wird über eine stabile Schnittstelle gelesen, die der Test direkt aufrufen kann. Die Suite kümmert sich nicht mehr darum, wie der Anbieter aussieht, sondern nur darum, dass der Vertrag hält: anlegen, empfangen, lesen, löschen.

Es gibt auch ein Datenschutzargument. Eine per API angelegte Adresse steht für niemanden. Sie ist nicht das Postfach einer Person, sie ist kein Ort, an dem eine echte Nachricht landen könnte, und sie wird mit dem Lauf verworfen.

Welche Endpunkte braucht ein Test tatsächlich?

Eine Postfach-API kann Dutzende Routen anbieten, aber ein Testclient braucht vier Operationen, und es hilft, sie so zu benennen, wie die Suite sie nutzt.

Anlegen liefert eine Adresse und ein Handle. Die Adresse ist das, wohin die zu testende Anwendung senden soll. Das Handle, oft ein Token oder eine Kennung, ist das, womit der Test in jedem späteren Aufruf nach diesem Postfach fragt. Die Suite sollte das Paar als ein Objekt behandeln und das Handle niemals aus der Adresse rekonstruieren, denn Anbieter dürfen die beiden unabhängig voneinander machen.

Auflisten liefert Zusammenfassungen statt Texte: einen Eintrag pro Nachricht, mit Kennung, Absender, Betreff und Ankunftszeit. Das ist der Aufruf, den eine Abfrageschleife nutzen sollte, weil er billig ist und ausreicht, um die einzige Frage zu beantworten, die früh zählt: ob überhaupt schon etwas angekommen ist.

Lesen liefert eine Nachricht vollständig, einschließlich Text- und HTML-Teil. Dort lebt der Code, und das ist der Aufruf, der erst erfolgen sollte, nachdem Auflisten einen Treffer gemeldet hat.

Leeren entfernt die Nachrichten aus einem Postfach oder löscht das Postfach ganz. Ein Test braucht es aus zwei Gründen: um zwischen Versuchen zurückzusetzen, ohne eine neue Adresse anzulegen, und um aufzuräumen, wenn der Fall endet.

Manche Dienste ergänzen einen Warte- oder Long-Poll-Endpunkt, der die Verbindung hält, bis eine Nachricht eintrifft oder eine Frist abläuft. Das ist bequem, aber ein Client sollte weiterhin auf Auflisten zurückfallen können, weil der Warteaufruf der Teil ist, der am ehesten ratenbegrenzt wird.

Den Code ohne Flackern abfragen

Der mit Abstand häufigste Fehler in dieser Art Test ist ein festes Warten. Eine konstante Zahl von Sekunden ist eine Schätzung: zu kurz, wenn die Zustellung langsam ist, verschwenderisch lang, wenn sie schnell ist, und in beide Richtungen falsch auf einem belasteten CI-Runner. Ersetzen Sie es durch eine Schleife, die Auflisten aufruft, auf einen Treffer prüft und zurückkehrt, sobald einer gefunden ist, mit einer Obergrenze, die den Test scheitern lässt statt den Job aufzuhängen.

Der Abgleich ist die zweite Hälfte des Problems. Die Nachricht, die der Test will, ist die an die Adresse gerichtete, die der Fall angelegt hat, und, wenn das Postfach mehr als eine Art Mail halten kann, die, deren Betreff ein stabiles Fragment trägt. Bevorzugen Sie den neuesten Treffer, damit eine doppelte Zustellung aus einem Wiederholungsversuch das Lesen nicht verwirrt. Nehmen Sie niemals bedingungslos die erste Nachricht; auf einer wiederverwendeten Adresse validiert man so genau einen alten Code.

Die Extraktion sollte verankert sein. Ein Text kann eine Referenznummer, einen Zeitstempel und einen Preis enthalten, und ein Parser, der den ersten Ziffernlauf greift, greift manchmal einen davon statt des Codes. Suchen Sie die Formulierung, die den Code einleitet, lesen Sie den Code aus deren Umgebung und scheitern Sie mit angehängtem Text, wenn nichts passt.

Respektieren Sie schließlich das erneute Sende-Limit. Ein Code-Ablauf erlaubt meist nur wenige Sendungen in einem kurzen Fenster, und dieses Limit ist Teil des geprüften Verhaltens. Ein Test, der den Knopf erneut drückt, um einen frischen Code zu bekommen, wird irgendwann abgelehnt und scheitert aus dem falschen Grund. Wiederholen Sie, indem Sie das Postfach erneut lesen, nicht indem Sie eine weitere Nachricht auslösen.

Integration in eine End-to-End- oder CI-Suite

Die saubere Form ist ein Fixture. Bevor der Ablauf startet, legt das Fixture ein Postfach an und gibt dessen Adresse zurück. Der Test steuert die Anwendung mit dieser Adresse. Nachdem die Anwendung bestätigt hat, dass sie etwas gesendet hat, liest die Prüfung das Postfach und extrahiert den Code. Wenn der Fall endet, löscht das Fixture das Postfach.

Halten Sie den Client klein und injizierbar. Ein Modul kapselt die vier Aufrufe; der Test hängt von diesem Modul ab, niemals von rohem HTTP, das über die Suite verstreut ist. Das macht es möglich, für Unit-Tests einen Doppelgänger einzusetzen und dieselbe Suite auf einen anderen Anbieter zu richten, ohne Prüfungen umzuschreiben.

In CI gehören Zugangsdaten in den Secret-Speicher des Jobs, niemals ins Repository und niemals in eine Logzeile. Geben Sie jedem Job oder jedem parallelen Worker sein eigenes Postfach, und stellen Sie generierten Adressen ein Präfix voran, das den Lauf kennzeichnet, damit eine verirrte Nachricht durch Hinsehen zuzuordnen ist. Setzen Sie das Timeout des Clients unter das Timeout des Jobs selbst, damit eine hängende Abfrage mit einer klaren Meldung scheitert statt mit einem abrupten Jobabbruch.

Wiederholen Sie das Lesen, nicht den ganzen Ablauf. Ist der Code noch nicht angekommen, warten Sie und lesen Sie erneut; die Anmeldung neu auszuführen, würde eine zweite Nachricht und damit einen zweiten Kandidaten für die Prüfung erzeugen. Und halten Sie die Postfach-API aus Produktionsabläufen heraus: Sie ist Testinfrastruktur, und eine Suite sollte daraus nie an einen echten Kunden senden können.

Der Ablauf um den Code, nicht die Mechanik des Lesens, wird in Test von Verifizierungsabläufen behandelt, und der Parsing-Schritt speziell ist Thema von OTP-Test in End-to-End-Suiten.

Isolierung und Aufräumen

Eine Adresse pro Fall ist die Regel, die die meisten Fehler zwischen Tests verhindert. Sie beseitigt die Notwendigkeit, darüber nachzudenken, welche Nachricht zu wem gehört, und lässt die Frischefrage verschwinden, weil das Postfach nur je den Verkehr eines Falls empfangen hat.

Das Aufräumen sollte ausdrücklich und bedingungslos sein. Löschen Sie das Postfach in einem Teardown, das läuft, ob der Fall bestanden oder gescheitert ist, nicht nur auf dem glücklichen Pfad. Sich allein auf die Lebensdauer des Anbieters zu verlassen, ist ein Fehler: Die Nachricht kann lange genug bleiben, um von einem späteren Lauf auf derselben Maschine gelesen zu werden, und diese Lebensdauer ist eine Bequemlichkeit, keine Garantie.

Scheitert das Aufräumen, protokollieren Sie es und lassen Sie die Suite zu Ende laufen. Ein Aufräumfehler ist es wert, gekannt zu werden, aber er ist nicht dasselbe wie ein Produktdefekt, und den Lauf deswegen scheitern zu lassen, lehrt das Team, Teardown-Fehler zu ignorieren. Behandeln Sie alles, was die Adresse empfangen hat, als Testdaten: Es existiert für eine Prüfung, es sollte nicht exportiert oder geteilt werden, und es darf niemals als Kontaktpunkt von jemandem gelten.

Grenzen und Vorbehalte

Eine Postfach-API ist weiterhin eine Abhängigkeit von Dritten, und ihre Grenzen werden Ihre Grenzen. Ratenbegrenzungen pro Minute können eine Serie von Anlageaufrufen aus einem großen parallelen Lauf ablehnen. Kontingente begrenzen, wie viele Adressen gleichzeitig existieren. Nachrichten können sich verzögern, und eine verzögerte Nachricht sieht genau wie eine fehlende aus, bis sie ankommt.

Wegwerf-Domains sind zudem weit verbreitet blockiert. Die Domain eines Anbieters kann von genau dem Anmeldeformular abgelehnt werden, das Sie testen, was einen legitimen Test in einen verwirrenden Fehler verwandelt. Wenn das passiert, ist die Antwort nicht, den Anbieter als Sonderfall zu behandeln, sondern zu verstehen, ob das zu testende Produkt Wegwerfadressen absichtlich ablehnt, und dieses Verhalten dann bewusst zu testen.

Die ehrliche Zusammenfassung ist, dass die Postfach-API das richtige Werkzeug ist, um zu belegen, was ankommt. Um zu belegen, was Ihre Anwendung ausgibt, ist ein lokaler Empfangsendpunkt schneller und hat kein Kontingent. Die meisten ausgereiften Suiten nutzen beides: lokale Aufnahme für die Masse der Prüfungen und eine Postfach-API nur dort, wo der echte Zustellweg das Prüfobjekt ist.

Nächste Schritte

Suchen Sie einen code-lesenden Test, der ein geteiltes Postfach abfragt, und ersetzen Sie ihn durch ein Fixture, das eine frische Adresse von einer Postfach-API anlegt. Protokollieren Sie die Adresse mit dem Lauf, löschen Sie sie im Teardown, und beobachten Sie, wie viel des Flackerns, das Sie hingenommen hatten, einfach aufhört. Wenn Sie von Hand ein echtes Postfach brauchen, erzeugt die Seite für temporäre E-Mail in einem Augenblick eines, und die Adressen, die sie ausgibt, sind Gerüst für einen Lauf, niemals eine echte Identität.

Weiterlesen

Artikel zu Temporäre E-Mail (Einweg-E-Mail / 10-Minuten-Mail)