Testing Naming Conventions - GIVEN-WHEN-THEN


Python clean test tip:

Tests should have descriptive names to reveal their intention. For example, you could follow GIVEN-WHEN-THEN or SHOULD-WHEN naming conventions:

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel

app = FastAPI()


class LoginRequest(BaseModel):
    username: str
    password: str


@app.post("/login")
def login(data: LoginRequest):
    return {"access_token": "1234"}


@pytest.fixture()
def client():
    yield TestClient(app)


# BAD
def test_login(client):
    response = client.post("/login", json={"username": "johndoe", "password": "correct_password"})
    assert response.status_code == 200
    assert response.json()["access_token"] == "1234"


# GOOD
def test_valid_username_and_password_combination_can_be_exchanged_for_access_token(client):
    response = client.post("/login", json={"username": "johndoe", "password": "correct_password"})
    assert response.status_code == 200
    assert response.json()["access_token"] == "1234"


def test_given_valid_username_and_password_combination_when_user_calls_login_then_access_token_is_returned(client):
    response = client.post("/login", json={"username": "johndoe", "password": "correct_password"})
    assert response.status_code == 200
    assert response.json()["access_token"] == "1234"


def test_access_token_should_be_returned_when_valid_username_and_password_combination_is_provided(client):
    response = client.post("/login", json={"username": "johndoe", "password": "correct_password"})
    assert response.status_code == 200
    assert response.json()["access_token"] == "1234"