CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/pytest-api-testing

Pytest patterns for Python APIs -- httpx AsyncClient, conftest fixtures, database isolation, parametrize edge cases, error response testing, auth flows, factory fixtures

99

1.23x
Quality

99%

Does it follow best practices?

Impact

100%

1.23x

Average score across 5 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-4/

Write Comprehensive Tests for a User Account API

Problem/Feature Description

A SaaS platform's user account service has been live for six months. The frontend team recently filed three bugs: one where the app crashed because a 404 came back as an HTML error page instead of JSON, one where the admin UI accidentally displayed password hashes in the user list, and one where the API accepted malformed JSON silently. The backend team wants tests that would have caught all three of these before they reached production.

You have been asked to write a thorough test suite for the /users resource. The tests need to go beyond verifying that the happy paths return 200 — they must verify error responses are proper JSON with the expected structure, that the response body on success contains the right fields, and that sensitive information is never exposed.

Output Specification

Produce the following files:

  • tests/conftest.py — shared fixtures
  • tests/test_users.py — the full test suite
  • pyproject.toml — pytest configuration

Input Files

The following files are provided as inputs. Extract them before beginning.

=============== FILE: app/main.py =============== from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import List, Optional import hashlib

app = FastAPI()

_users: List[dict] = [] _next_id = 1

def hash_password(password: str) -> str: return hashlib.sha256(password.encode()).hexdigest()

class UserCreate(BaseModel): email: str name: str password: str

class UserUpdate(BaseModel): name: Optional[str] = None

@app.post("/api/users", status_code=201) async def create_user(body: UserCreate): global _next_id for u in _users: if u["email"] == body.email: raise HTTPException(status_code=409, detail="Email already taken") user = { "id": _next_id, "email": body.email, "name": body.name, "password_hash": hash_password(body.password), } _users.append(user) _next_id += 1 # Return without password_hash return {"data": {"id": user["id"], "email": user["email"], "name": user["name"]}}

@app.get("/api/users") async def list_users(): return {"data": [{"id": u["id"], "email": u["email"], "name": u["name"]} for u in _users]}

@app.get("/api/users/{user_id}") async def get_user(user_id: int): for u in _users: if u["id"] == user_id: return {"data": {"id": u["id"], "email": u["email"], "name": u["name"]}} raise HTTPException(status_code=404, detail="User not found")

@app.delete("/api/users/{user_id}", status_code=204) async def delete_user(user_id: int): global _users for u in _users: if u["id"] == user_id: _users = [x for x in _users if x["id"] != user_id] return raise HTTPException(status_code=404, detail="User not found")

@app.patch("/api/users/{user_id}") async def update_user(user_id: int, body: UserUpdate): for u in _users: if u["id"] == user_id: if body.name is not None: u["name"] = body.name return {"data": {"id": u["id"], "email": u["email"], "name": u["name"]}} raise HTTPException(status_code=404, detail="User not found")

evals

tile.json