pytest recipe
A small conftest.py fixture gives every test a fresh inbox and a
wait_for_email helper.
conftest.py
import os, re, time, uuid
import pytest, requests
API = os.environ.get("MAILFADE_API_URL", "https://api.mailfade.dev")
KEY = os.environ.get("MAILFADE_KEY")
HEADERS = {"Authorization": f"Bearer {KEY}"} if KEY else {}
class Inbox:
def __init__(self, prefix: str = "py"):
self.address = f"{prefix}-{uuid.uuid4().hex[:10]}@mailfade.dev"
def wait_for(self, subject_re=None, from_re=None, timeout: float = 30):
deadline = time.time() + timeout
while time.time() < deadline:
r = requests.get(f"{API}/inbox/{self.address}", headers=HEADERS, timeout=10).json()
for e in r.get("emails", []):
if subject_re and not re.search(subject_re, e.get("subject") or ""):
continue
if from_re and not re.search(from_re, e.get("sender") or ""):
continue
full = requests.get(f"{API}/message/{e['id']}", headers=HEADERS, timeout=10).json()
return full
time.sleep(1)
raise AssertionError(f"no matching email at {self.address}")
@pytest.fixture
def inbox():
return Inbox()
A test
def test_signup_sends_verification(client, inbox):
client.post("/signup", json={"email": inbox.address, "password": "hunter2hunter2"})
email = inbox.wait_for(subject_re=r"confirm", from_re=r"@acme\.com$")
assert "https://" in email["text"]
assert email["sender"].endswith("@acme.com")