Erfahre, wie du E‑Mail‑Validierungs‑Test‑Fixtures erstellst, die Tippfehler, tote Domains, Catch‑All‑Postfächer und Wegwerf‑E‑Mails abdecken — und wie du sie in CI automatisierst.

Normalisiere zuerst die Eingabe und teste die „unordentlichen“ Eingaben, die Nutzer tatsächlich abschicken: führende/trailing Leerzeichen, Großbuchstaben in Domains, trailing Punkte und Plus‑Tags. Ergänze dann Fixtures, die Domain‑Existenz, MX‑Vorhandensein, Catch‑All‑Verhalten und Wegwerf‑Erkennung abdecken, damit deine Tests reale Anmelde‑Risiken widerspiegeln.
Ein Regex sagt nur, dass der String wie eine E‑Mail aussieht. Es kann nicht bestätigen, ob die Domain existiert, ob sie Mail empfangen kann (MX‑Records) oder ob es sich um einen Wegwerf‑Provider handelt. Deshalb genehmigst du sonst leicht Adressen, die bouncen oder Spam anziehen.
Teile die Validierung in Schichten, die sich separat testen lassen: Syntax und Normalisierung (offline), Domain‑ und MX‑Signale (Netzwerkgrenze), Provider‑Typ (Wegwerf vs. normal) und deine geschäftlichen Risikoregeln. So ist leichter zu erkennen, welche Schicht eine Fixture auffangen soll.
Verwende abgestufte Ergebnisse wie valid, risky, invalid und unknown statt nur pass/fail. Catch‑All‑Domains und Timeouts sind große Gründe: sie lassen sich oft nicht als zustellbar beweisen. Ein klares „risky/unknown“ erlaubt dem Produkt, zu entscheiden, ob es erlaubt, warnt oder zusätzliche Verifikation verlangt.
Beinhaltet Tippfehler und Formatfehler, tote Domains (NXDOMAIN oder kein MX), Catch‑All‑Fälle, Wegwerf‑Provider und Lookalikes sowie Rollen‑ oder verdächtige Muster wie admin@ oder lange numerische Strings. Verknüpfe jede Fixture mit einer erwarteten Entscheidung, damit du Verhalten testest, nicht nur String‑Parsing.
Behandle Fixtures als strukturierte Datensätze: Eingabe‑E‑Mail, erwartetes Ergebnis, Reason‑Code und eine Notiz. Nutze Tags wie typo, dead_domain, disposable oder catch_all, damit du gezielt Teilmengen ausführst, wenn du eine Regel änderst.
Mache Unit‑Tests vollständig offline, indem du DNS/MX/API‑Ergebnisse mockst, und zeichne oder spiele Antworten für Contract‑Tests auf. Live‑Internet‑Abhängigkeiten ändern sich mit der Zeit; wenn du sie in CI verwendest, führen sie zu zufälligen Fehlern, die nichts mit deinem Code zu tun haben.
Stubbe die Validator‑Grenze so, dass der Anmeldeflow End‑to‑End mit festen Antworten getestet werden kann, inklusive Timeouts und Fehlerfällen. Halte daneben eine kleine Live‑Prüfungs‑Routine (nächtlich oder manuell), die reale DNS‑ und API‑Antworten überprüft, um Drift zu erkennen, ohne jeden Pull‑Request zu brechen.
Behandle es als Signal, nicht als Beweis, und erwarte ein mehrdeutiges Ergebnis wie „Domain OK, Postfach unbekannt“, statt automatisch freizugeben. Produktseitig ist ein guter Default: Anmeldung erlauben, aber Bestätigung verlangen oder Einschränkungen setzen — und genau das sollten deine Tests festhalten.
Pinniere erwartete strukturierte Ergebnisse pro Fixture und aktualisiere sie nur, wenn du die Policy bewusst änderst. Wenn du Verimail nutzt, mappe Fixtures auf dessen Pipeline‑Signale (syntax, domain, MX, disposable/blocklist), stubbe Antworten in CI und führe periodisch eine kleine Live‑Suite aus, um Klassifikationsänderungen zu erkennen.
Die meisten Test‑Suites für E‑Mail‑Validierung sehen solide aus und schlagen trotzdem in Produktion fehl, weil reale Adressen unordentlich sind. Nutzer fügen Leerzeichen ein, nutzen Plus‑Tags, mischen Groß‑/Kleinschreibung, hängen Punkte an oder tippen auf dem Handy zu schnell und lassen Zeichen aus. Wenn deine Fixtures nur saubere, lehrbuchmäßige E‑Mails abdecken, testest du eine Welt, in der deine Nutzer nicht leben.
Ein weiteres häufiges Problem ist, dass nur die einfachste Schicht getestet wird: Syntax. Syntax‑Checks fangen offensichtliche Fehler ab, aber viele schlechte Anmeldungen verwenden gültig aussehende Adressen auf Domains, die nicht existieren, Domains ohne Mail‑Setup oder Wegwerf‑Provider, die sich ständig ändern. Eine Test‑Suite, die bei einem Regex stehen bleibt, gibt ein falsches Sicherheitsgefühl.
Das Ziel ist nicht, alles Verdächtige zu blockieren. Das Ziel ist, schlechte Anmeldungen zu stoppen, ohne echte Nutzer zu blockieren. Das heißt: Beide Seiten testen — das, was wirklich abgelehnt werden sollte, ablehnen, und gängige legitime Muster (wie Plus‑Adressen und Subdomains) akzeptieren.
Diese Fehlerbilder treten immer wieder auf:
Gute Tests decken Schichten ab, die zur realen Validierung passen: Syntax (RFC‑ähnliche Regeln), Domain‑Signale (Domain existiert, MX‑Records), Postfach‑Signale (Catch‑All‑Verhalten oder Akzeptanzmuster) und Risiko‑Signale (Blocklisten, Wegwerf‑Erkennung).
Erwarte früh: manche Ergebnisse sind probabilistisch. Catch‑All‑Domains können jede Adresse akzeptieren, ohne ein bestimmtes Postfach zu beweisen. Wegwerf‑Listen verändern sich täglich. Selbst Enterprise‑Tools wie Verimail können riskante Signale zurückgeben, die besser mit Produktregeln (erlauben, blocken oder zusätzliche Verifikation verlangen) gehandhabt werden, statt so zu tun, als hätte jeder Fall eine perfekte Antwort.
E‑Mail‑Validierung wirkt wie ein einzelner Check, ist aber eigentlich eine Kette kleinerer Prüfungen. Teile diese Kette in Schichten und deine Tests werden klarer und leichter zu pflegen. Das hilft auch, Fixtures zu bauen, die zu echten Nutzeranmeldungen passen statt zu zufälligen Strings.
Ein praktisches Schichtenmodell sieht so aus:
Nicht jede Schicht sollte in Tests gleich behandelt werden. Manche Schichten sind reine Logik und laufen schnell und offline (Syntax, die meisten Risiko‑Regeln). Andere hängen vom Netzwerk ab (DNS, MX‑Lookup, Echtzeit‑Blocklists). Behandle diese unterschiedlich, damit deine Test‑Suite stabil bleibt.
Als Nächstes: Entscheide, was deine App mit jedem Ergebnis einer Schicht macht. Viele Teams kennen nur Pass oder Fail und landen dann bei verwirrenden Randfällen. Ein abgestuftes Ergebnis ist meist einfacher:
Ein praktisches Beispiel: Ein Nutzer gibt [email protected] ein. Die Syntax besteht, aber deine Tippfehler‑Regeln markieren es als riskant. Du könntest die Anmeldung erlauben, aber um Bestätigung bitten. Wenn er [email protected] eingibt, besteht die Syntax, aber Domain oder MX schlagen fehl, also blockst du.
Beim Schreiben von Tests mappe jede Fixture auf die Schicht, die sie auffangen soll, und auf das erwartete Ergebnis. Für Netzwerk‑Schichten bevorzuge Boundary‑Tests (z. B. wie du mit einem DNS‑Fehler vs. einem echten No‑MX‑Ergebnis umgehst) und halte den Rest als schnelle Unit‑Tests. Wenn du eine API wie Verimail verwendest, kannst du ihre mehrstufigen Ergebnisse (Syntax, Domain, MX, Wegwerf‑Checks) in deinen eigenen Schicht‑Erwartungen spiegeln.
Gute E‑Mail‑Validierungs‑Fixtures sehen aus wie das, was echte Nutzer tippen, nicht wie zufällige Strings. Wenn du Fixtures um einige klare Szenario‑Kategorien herum aufbaust, bleiben Tests lesbar und Lücken offensichtlich.
Behalte diese Kernkategorien in jeder Suite:
@, doppelte @@, führende/abschließende Leerzeichen, doppelte Punkte, ein Punkt direkt vor @ und vertauschte Zeichen in gängigen Domains. Diese sollten auf Syntax‑Ebene schnell fehlschlagen, bevor Netzwerk‑Checks laufen.admin@, support@, info@ und verdächtige Muster wie lange numerische Strings. Teste deine Policy‑Entscheidung (erlauben, warnen oder blocken), statt anzunehmen, sie seien immer schlecht.Damit Kategorien nützlich bleiben, verknüpfe jede Fixture mit einer erwarteten Entscheidung, nicht nur gültig/ungültig. Labels wie syntax_invalid, domain_invalid, disposable_block, risky_allow_with_warning, unknown_catch_all machen Fehler leichter interpretierbar.
Wenn du einen Validator‑API wie Verimail nutzt, mappe diese Kategorien auf die Pipeline‑Schritte, die du erwartest (Syntax, Domain‑Checks, MX‑Lookup, Wegwerf‑Blocklist‑Match). So sagt ein fehlgeschlagener Test, welche Art von Fehler es war, nicht nur, dass etwas kaputt ging.
Gute Fixtures fühlen sich an wie echte Anmeldungen, nicht wie Keyboard‑Mashing. Wenn ein Test fehlschlägt, solltest du sofort verstehen, was passiert ist und warum es wichtig ist.
Behandle Fixtures als kleine Datensätze mit konsistenter Form: die Eingabe‑E‑Mail, das erwartete Ergebnis (akzeptieren, ablehnen oder zusätzliche Prüfungen nötig) und ein kurzer Grund. Füge ein Notizfeld für Dinge hinzu, die du später vergisst (warum die Domain verwendet wird oder welches Verhalten du erwartest, falls sich der Provider ändert).
Hier ein kompaktes Beispiel, das du in dein Repo kopieren kannst:
[
{
\"name\": \"typo_gmail_missing_dot\",
\"input\": \"alex@gmailcom\",
\"expected\": \"reject\",
\"reason\": \"typo\",
\"tags\": [\"typo\"],
\"notes\": \"Missing dot in domain; should fail domain validation.\"
},
{
\"name\": \"disposable_known_provider\",
\"input\": \"[email protected]\",
\"expected\": \"reject\",
\"reason\": \"disposable\",
\"tags\": [\"disposable\"],
\"notes\": \"Should be blocked by disposable provider list.\"
}
]
Tags machen die Suite leichter erweiterbar. Statt einer großen Datei, halte kleine benannte Sets pro Kategorie (typos, dead domains, catch‑all, disposable, edge cases). So kannst du nur das Ausführen, was du brauchst — z. B. nur die Wegwerf‑Fälle, wenn du die Klassifikationsregeln änderst.
Normalisierungsregeln gehören ebenfalls in die Fixtures, weil reale Nutzer unordentliche Daten einfügen. Schließe Fälle ein, die belegen, dass du damit umgehst:
Versioniere Fixtures wie Code. Jeder neue Fall sollte eine Frage beantworten: welchen Bug hat das verhindert? Füge eine kurze Notiz hinzu, verlange Review bei Änderungen und entferne Duplikate. Mit der Zeit werden deine Fixtures eine lebende Karte der Fehler und Angriffe, die dein Signup wirklich sieht.
Wenn du auf API‑Antworten vertraust (z. B. Verimail), speichere ein gepinntes erwartetes Ergebnis pro Fixture und aktualisiere es nur, wenn du die Policy bewusst änderst.
E‑Mail‑Checks berühren Dinge, die sich ohne Vorwarnung ändern: DNS‑Records, Mailserver‑Einstellungen und das Wegwerf‑Provider‑Ökosystem. Wenn deine Fixtures vom Live‑Internet abhängen, fallen Tests an einem zufälligen Dienstag aus, aus Gründen, die nichts mit deinem Code zu tun haben.
Trenne zunächst, was deterministisch gemacht werden kann, von dem, was es nicht kann. Syntaxfälle sind einfach: sie sollten niemals einen Netzwerkaufruf benötigen. Schwieriger wird alles, was Domain‑ oder Postfach‑Erreichbarkeit beinhaltet.
Ein stabiles Fixture‑Set kommt meist aus wenigen Quellen:
Vermeide es, echte Personenadressen in Fixtures zu verwenden, selbst wenn sie öffentlich sind. Nutze synthetische Local‑Parts (wie "user" oder "test") und klar gefälschte Namen. Das reduziert Privatsphäre‑Risiken und verhindert versehentliche E‑Mails, falls Testdaten in Logs oder nachgelagerte Systeme gelangen.
Für Dead‑Domain‑Szenarien ist der stabilste Ansatz, den DNS‑Fehler als Test‑Daten zu behandeln, nicht als Live‑Realität. Zeichne oder mocke das Resolver‑Ergebnis (z. B. NXDOMAIN oder kein MX) und behaupte, dass deine Logik damit korrekt umgeht. Live‑tote Domains sind instabil, weil Domains später registriert und konfiguriert werden können.
Wegwerf‑Erkennung braucht besondere Sorgfalt. Provider tauchen auf, verschwinden und ändern Domains häufig. Halte einen versionierten Snapshot deiner Wegwerf‑Liste (oder der Klassifikationsantworten deines Validation Vendors) und entscheide, wie Drift gehandhabt wird. Beispiel: Unit‑Tests laufen gegen das Snapshot, während ein separater geplanter Job Änderungen prüft und einen Review‑Task erstellt.
Schreibe auf, welche Fixtures zeitkritisch sind und was du tun wirst, wenn sie sich ändern: Snapshot aktualisieren, Assertion lockern oder den Fall in einen Contract‑Test verschieben. Wenn du Verimail in Produktion nutzt, behandle dessen Echtzeit‑Klassifikation so: teste mit gepinnten Aufnahmen und verifiziere periodisch mit einer kleinen, kontrollierten Live‑Suite.
Schnelle, verlässliche Tests beginnen bei den Teilen der Validierung, die kein Netzwerk berühren. Betrachte deinen Validator als Satz reiner Funktionen (Input rein, Output raus) und sperre den Vertrag, den der Rest deiner App erwarten kann.
Unit‑Tests sollten Syntax‑Regeln und Normalisierung abdecken, weil diese durch kleine Refaktoren leicht brechen. Beispiele: Trimmen von Leerzeichen, Kleinschreibung des Domain‑Teils, Ablehnen doppelter @‑Zeichen und Handhabung offensichtlicher Tippfehler wie fehlende Punkte in der Domain.
Beim Aufbau von Fixtures lasse jede Zeile für sich sprechen: Input, erwarteter normalisierter Wert (oder leer) und ein kurzer Reason‑Code. Reason‑Codes lassen sich leichter prüfen als volle Sätze.
Ein einfaches Muster sind table‑driven Tests: durchlaufe eine Fixture‑Tabelle und assertiere sowohl Status als auch Reason für jeden Fall. Das hält die Testdatei kurz und deckt dennoch viele Szenarien ab.
Contract‑Tests beantworten eine andere Frage: Gibt das Validierungsmodul immer die gleiche Struktur zurück? Wenn ein anderes Team { status, reason, normalized } erwartet und ein Release das stillschweigend ändert, entstehen Bugs, die zufällig aussehen.
Contract‑Tests sollten Dinge prüfen wie:
status, reason, normalized_email)valid, invalid, risky)Property‑based‑Tests können hier ebenfalls helfen. Statt jede Tippfehler‑Variante handzuschreiben, generiere Near‑Misses: zusätzliche Leerzeichen, vertauschte Zeichen um das @, wiederholte Punkte oder gemischte Groß-/Kleinschreibung in Domains. Ziel ist, Parser‑Bugs und Randfälle zu fangen, an die du nicht gedacht hast.
Snapshot‑Tests können für UI‑Meldungen nützlich sein, aber setze sie gezielt ein. Bevorzuge das Snapshotten stabiler Fehler‑Codes, nicht ganzer Texte. Wenn du Texte sperrst, halte sie kurz und konsistent, damit kleine Copy‑Änderungen nicht einen Großteil deiner Test‑Suite brechen.
Integrationstests sind der Punkt, an dem E‑Mail‑Validierungslogik oft unzuverlässig wird. Sobald ein Test von echtem DNS, MX‑Lookups oder einem Drittanbieter abhängt, sind zufällige Fehler möglich, die nichts mit deinem Code zu tun haben.
Für alltägliche CI‑Runs strebe Tests an, die schnell und reproduzierbar sind. Behandle das Netzwerk als Input, den du kontrollierst.
Ein praktischer Ansatz ist, die Netzwerkgrenze zu mocken und zu testen, was deine App mit jedem Ergebnis macht. Ruft dein Signup‑Service eine E‑Mail‑Validierungs‑API auf, ersetze diesen Aufruf durch einen Stub, der für deine Fixtures bekannte Antworten liefert. Du testest weiterhin den kompletten Flow (Controller, Service, Policy‑Entscheidung, Fehlermeldung), testest aber nicht das Internet.
Muster, die gut funktionieren:
Timeouts verdienen besondere Aufmerksamkeit. Entscheide deine Policy und teste sie explizit: Bei einem Timeout behandelst du die E‑Mail als ungültig oder als unbekannt und lässt den Nutzer mit zusätzlicher Verifikation weiter? Beides kann richtig sein, aber nur, wenn es konsistent ist.
Gemockte Tests können von der Realität abdriften. Eine Domain, die früher MX‑Records hatte, kann sterben. Eine Wegwerf‑Klassifikation kann sich ändern. Um Drift zu erkennen, halte eine separate Pipeline, die echte Netzwerkaufrufe macht, aber nicht bei jedem Pull‑Request läuft.
Ein typisches Setup ist ein nächtlicher Run oder ein manueller Live‑Checks‑Workflow. Halte diese Lane klein: ein paar repräsentative E‑Mails pro Kategorie (Tippfehler, tote Domains, Catch‑All, Wegwerf) reichen aus, um Drift zu entdecken, ohne zu viel Lärm zu erzeugen.
Wenn du Verimail in Produktion nutzt, kann deine CI dessen Antwort auf disposable: true für eine Fixture wie [email protected] stubben, und du prüfst, dass deine UI die Anmeldung blockt und die richtige Meldung zeigt. Dein nächtlicher Job kann dann die echte API mit kontrollierten Adressen abfragen und dich alarmieren, wenn Ergebnisse sich ändern, damit du Fixtures oder Policy anpassen kannst, bevor Nutzer es bemerken.
Eine Test‑Suite kann beschäftigt aussehen und dennoch die Fehler übersehen, die in Produktion schaden. Das größte Risiko ist falsches Vertrauen: Tests laufen, aber echte Nutzer werden blockiert oder falsche Anmeldungen kommen durch.
Eine häufige Falle ist, Catch‑All‑Domains als Beweis für die Existenz eines Postfachs zu werten. Catch‑All bedeutet nur, dass die Domain Mail für jede Adresse akzeptiert. Wenn deine Logik daraufhin alles auf Catch‑All‑Domains auto‑approvt, trainieren deine Fixtures stillschweigend, Junk‑Adressen zu akzeptieren.
Eine andere Falle ist, nur ein Regex zu verwenden und das für Validierung zu halten. Regex fängt offensichtliche Formatfehler, aber nicht, ob die Domain existiert, MX‑Records hat oder ob die Adresse von einem Wegwerf‑Provider stammt. Testest du nur String‑Patterns, testest du deinen Regex, nicht das Verhalten von E‑Mails.
Das harte Ablehnen bei temporären DNS‑Problemen ist ebenfalls ein häufiger Fehler. Netzwerke haben Timeouts und intermittierende Fehler. Wenn deine Tests nur DNS funktioniert vs. DNS schlägt fehl abdecken, kannst du gute Nutzer bei einer kurzen Störung abweisen. Besser ist, einige Fehler als unbekannt zu behandeln und ggf. später zu retryen oder die Anmeldung zu erlauben, aber die Adresse zur späteren Verifikation zu markieren.
Internationalisierte Domains und moderne Mailbox‑Regeln vergisst man leicht. Plus‑Adressen (z. B. [email protected]) sind gültig und weit verbreitet. Einige Nutzer haben Non‑ASCII‑Domains. Wenn deine Fixtures diese niemals enthalten, lieferst du einen Validator, der normale Eingaben kaputtmacht.
Einige Wege, wie Teams sich selbst täuschen:
+ für ungültig halten oder falsch strippenEine praktische Absicherung ist, Ergebnisse in klare Buckets zu trennen (invalid, risky, unknown, valid) und Übergänge zwischen ihnen zu testen. Tools wie Verimail helfen, weil sie strukturierte Signale zurückgeben (syntax, domain, MX, disposable), was es einfacher macht, Verhalten zu behaupten, ohne aus einem einzelnen Pass/Fail zu raten.
Vor dem Merge mach eine kurze Prüfung auf Coverage und Vertrauen. Ziel ist nicht, jede E‑Mail auf der Erde zu testen, sondern sicherzustellen, dass Fixtures sich wie echte Anmeldungen verhalten und auf vorhersehbare Weise fehlschlagen.
Überfliege dein Fixture‑Set nach Kategorien. Wenn eine Kategorie nur ein oder zwei Beispiele hat, kann eine kleine Code‑Änderung reale Nutzer kaputtmachen und deine Tests bleiben grün. Ziel: ein kleiner Cluster von Fällen pro Kategorie, damit du Randfälle (z. B. ein Tippfehler, der trotzdem gültig aussieht) abdeckst.
Nutze diese kurze Checkliste:
Ignoriere Stabilität nicht. Tests, die von realen Domains abhängen, können mit der Zeit verrotten, und Catch‑All‑Verhalten kann sich ohne Vorwarnung ändern. Für Unit‑Tests bevorzuge Fixtures, die kein Netzwerk benötigen, und behalte Domain‑Verhalten als gemockte Antworten. Für Integrationstests begrenze den Umfang und mache sie intentional. Ein einfaches Muster ist ein kleiner nächtlicher Job, der einige bekannte Fälle gegen deinen Validierungsservice ausführt, während CI deterministische Unit‑Tests fokussiert.
Ein gängiges SaaS‑Problem: Das Signup‑Formular wirkt bei manuellen Tests in Ordnung, aber nach dem Launch kommen Wellen von Spam‑Anmeldungen. Viele nutzen Wegwerf‑Provider — schlechte Leads, höhere Bounce‑Raten und eine unordentliche Nutzer‑DB.
Ein praktischer Ansatz ist, klares Verhalten zu definieren und mit Fixtures zu fixieren. Beispiel: Wegwerf‑Adressen blocken, tote Domains ablehnen und Catch‑All‑Domains erlauben, aber mit Warnung.
Hier ein kleines Fixture‑Set, das realistische Signup‑Inputs abdeckt, ohne auf Zufallsstrings zu setzen:
[email protected] (sieht echt aus, Domain ist falsch geschrieben)[email protected] (nutze .invalid, um eine Domain darzustellen, die niemals aufgelöst werden sollte)[email protected] (behandele das in Mocks als Catch‑All, nicht als reale DNS‑Tatsache)[email protected] (behandele das in Mocks als Wegwerf, nicht als echten Provider)[email protected] (normal aussehende Adresse für den Happy‑Path)Wichtig ist, dass deine App während Unit‑Tests nicht versucht, Catch‑All‑ oder Wegwerf‑Status über das öffentliche Internet zu beweisen. Stattdessen sollte deine Validierungs‑Schicht ein normalisiertes Ergebnis zurückgeben, das dein Signup‑Logic verwenden kann.
Eine einfache Regel für den Signup‑Endpoint könnte sein:
is_disposable = true: Anmeldung blocken mit klarer Fehlermeldungdomain_status = dead: ablehnen und um eine andere E‑Mail bittenis_catch_all = true: Anmeldung erlauben, aber Warnung anzeigen (und ggf. zusätzliche Verifikation erwägen)Um CI schnell und vorhersehbar zu halten, teile Tests in zwei Geschwindigkeiten: schnelle Unit‑Tests für deine Entscheidungslogik und gemockte Integrationstests für die Validator‑Grenze.
// Example: decision logic unit tests (no network)
const cases = [
{ email: "[email protected]", result: { is_disposable: true }, expect: "BLOCK" },
{ email: "[email protected]", result: { domain_status: "dead" }, expect: "REJECT" },
{ email: "[email protected]", result: { is_catch_all: true }, expect: "WARN" },
{ email: "[email protected]", result: { suggestion: "gmail.com" }, expect: "REJECT" },
{ email: "[email protected]", result: { ok: true }, expect: "ALLOW" },
];
for (const c of cases) {
const decision = decideSignup(c.email, c.result);
expect(decision).toBe(c.expect);
}
In CI kann der gemockte Integrationstest sicherstellen, dass dein Signup‑Code den Validator einmal aufruft und Timeouts sowie Fehlerantworten handhabt, ohne wirklich DNS‑ oder MX‑Lookups durchzuführen.
Wenn du echte Checks (RFC‑konforme Syntax, Domain‑Verifikation, MX‑Lookup und Wegwerf/Blocklist‑Matching) ohne eigenen Aufwand möchtest, kann eine E‑Mail‑Validierungs‑API sinnvoll sein. Teams, die Verimail bereits nutzen, folgen oft dem Muster: die meisten Tests bleiben gemockt und deterministisch; zusätzlich läuft ein kleiner Satz Contract‑Checks, um sicherzustellen, dass die Integration mit verimail.co weiterhin die Antwortstruktur liefert, die deine App erwartet.