pytestbeginner

Python SDK + pytest

Test email flows with Plop Python SDK and pytest fixtures

Python SDK + pytest (python)python
# tests/conftest.py
import pytest
import os
import time
from plop import Plop

@pytest.fixture
def plop_client():
    """Provide a configured Plop client for tests."""
    return Plop(api_key=os.environ["PLOP_API_KEY"])

@pytest.fixture
def test_email():
    """Generate unique test email addresses."""
    def _generate(prefix: str = "test"):
        tag = f"{prefix}-{int(time.time() * 1000)}"
        return f"qa+{tag}@in.plop.email", "qa", tag
    return _generate


# tests/test_auth_emails.py
import pytest

class TestAuthEmails:
    def test_welcome_email(self, plop_client, test_email):
        """Welcome email should arrive with correct content."""
        email, mailbox, tag = test_email("welcome")

        # Trigger your app to send a welcome email
        create_user(email=email, name="Test User")

        # Wait for email  replaces time.sleep() + requests loop
        msg = plop_client.wait_for(
            mailbox=mailbox,
            tag=tag,
            timeout=10.0,
        )

        assert "Welcome" in msg.subject
        assert "Test User" in msg.text_content
        assert "Get Started" in msg.html_content

    def test_password_reset_email(self, plop_client, test_email):
        """Password reset should include a valid reset link."""
        email, mailbox, tag = test_email("reset")

        request_password_reset(email=email)

        msg = plop_client.wait_for(
            mailbox=mailbox,
            tag=tag,
            timeout=10.0,
        )

        assert "Reset" in msg.subject
        assert "reset" in msg.html_content.lower()

        # Extract and validate reset link
        import re
        link = re.search(r'href="([^"]*reset[^"]*)"', msg.html_content)
        assert link is not None

    @pytest.mark.parametrize("locale,expected_subject", [
        ("en", "Welcome"),
        ("es", "Bienvenido"),
        ("fr", "Bienvenue"),
    ])
    def test_localized_welcome(
        self, plop_client, test_email, locale, expected_subject
    ):
        """Welcome email should be localized."""
        email, mailbox, tag = test_email(f"locale-{locale}")

        create_user(email=email, name="Test", locale=locale)

        msg = plop_client.wait_for(
            mailbox=mailbox,
            tag=tag,
            timeout=10.0,
        )

        assert expected_subject in msg.subject

How It Works

1

pytest Fixture

The plop_client fixture provides a configured SDK client. The test_email fixture generates unique addresses with mailbox and tag separated for easy use with wait_for().

2

wait_for() vs time.sleep()

The SDK's wait_for() replaces the common pattern of time.sleep(2) + requests.get() with retry. It polls automatically and raises a clear TimeoutError if the email never arrives.

3

Pydantic Models

The returned message object is a Pydantic model with typed fields like subject, text_content, and html_content. IDEs provide full autocomplete.

4

Parametrized Tests

The localization test uses @pytest.mark.parametrize to verify email templates across multiple languages with the same test logic.

Try This Example

Get a free API key and test this example in minutes.