Backend Testing Infrastructure in Screenshot-to-Code: pytest and pytest-asyncio Setup

The Screenshot-to-Code backend uses pytest with automatic async support via pytest-asyncio, configured through backend/pytest.ini and managed by Poetry, allowing developers to run unit and integration tests against FastAPI routes and agents.

The Screenshot-to-Code repository provides a robust backend testing infrastructure built on pytest. Located in the backend/ directory, this setup supports both synchronous and asynchronous test patterns essential for validating FastAPI endpoints, agent logic, and LLM integration code.

Testing Infrastructure Components

The testing stack is defined in backend/pyproject.toml and configured via backend/pytest.ini. This infrastructure enables comprehensive validation of the Python backend without requiring external test runners.

Core Test Dependencies

The following tools form the backbone of the testing infrastructure as declared in the project's Poetry configuration:

  • pytest: Discovers and executes tests according to the patterns defined in backend/pytest.ini.
  • pytest-asyncio: Enables async def test functions for testing asynchronous FastAPI endpoints and HTTP clients. Declared in the dev dependency group in backend/pyproject.toml.
  • pyright: Performs static type checking through Poetry to prevent type errors from reaching production.

Key Configuration Files

Two files control the test behavior and discovery:

  • backend/pytest.ini: Sets testpaths = tests, defines asyncio_mode = auto for automatic async handling, and applies verbose output (-v) with short tracebacks (--tb=short).
  • backend/pyproject.toml: Declares test dependencies including pytest and pytest-asyncio in the Poetry dev group, as recommended by the project's AGENTS.md.

Running the Backend Test Suite

Execute the full test suite from within the Poetry-managed environment.

First, ensure development dependencies are installed:

cd backend && poetry install

Then run pytest:

cd backend && poetry run pytest

When executed, pytest reads the configuration from backend/pytest.ini, collects tests from the tests/ directory matching the test_*.py pattern, and automatically handles async tests via the asyncio_mode = auto setting. The output displays verbose results with short tracebacks, showing passed or failed status for each collected item.

Writing Tests for the Backend

New test files belong in backend/tests/ and must follow the test_*.py naming convention to be discovered by pytest.

Synchronous Tests

For standard FastAPI route testing, use the synchronous TestClient. This pattern validates HTTP endpoints without requiring async syntax:


# backend/tests/test_example.py

import pytest
from fastapi.testclient import TestClient
from backend.main import app

client = TestClient(app)

def test_home_route():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Welcome to Screenshot-to-Code!"}

Asynchronous Tests

When testing async functions, LLM helpers, or using httpx.AsyncClient, declare tests with async def. The asyncio_mode = auto setting in backend/pytest.ini eliminates the need for @pytest.mark.asyncio decorators:


# backend/tests/test_async_status.py

import pytest
from httpx import AsyncClient
from backend.main import app

async def test_status_endpoint():
    async with AsyncClient(app=app, base_url="http://test") as client:
         resp = await client.get("/status")
    assert resp.status_code == 200
    data = resp.json()
    assert data["state"] in {"idle", "running"}

The test test_broadcast in backend/tests/test_status_broadcast.py demonstrates this pattern for validating broadcasting logic, while backend/tests/test_screenshot.py provides examples of async HTTP client usage against the screenshot route.

Type Checking Integration

Maintain type safety by running pyright before committing changes:

cd backend && poetry run pyright

This command scans changed files for type violations. The test files themselves are excluded from type checking unless they import from the backend package.

Common Testing Issues

Issue Symptom Resolution
Missing dev dependencies Import errors when running pytest Run poetry install in the backend directory
Async test failures RuntimeError: Task <…> got destroyed Verify asyncio_mode = auto exists in backend/pytest.ini
Zero tests collected "collected 0 items" message Ensure files are named test_*.py and located under backend/tests/
Type errors pyright reports new violations Update type hints or use # type: ignore sparingly

Summary

  • The backend testing infrastructure relies on pytest and pytest-asyncio managed through Poetry.
  • Configuration resides in backend/pytest.ini with asyncio_mode = auto enabling seamless async test support without decorators.
  • Tests live in backend/tests/ following the test_*.py naming pattern.
  • pyright provides static type checking via poetry run pyright.
  • Reference implementations in test_status_broadcast.py and test_screenshot.py demonstrate patterns for testing FastAPI routes and async logic.

Frequently Asked Questions

What testing infrastructure is available for the Screenshot-to-Code backend?

The backend uses pytest as the primary test runner with pytest-asyncio plugin support for asynchronous tests. This infrastructure is configured through backend/pytest.ini and dependency-managed via Poetry in backend/pyproject.toml, enabling comprehensive testing of FastAPI endpoints and agent logic.

How do I run the backend tests locally?

Navigate to the backend directory and execute poetry run pytest after installing dependencies with poetry install. This command automatically discovers tests in the backend/tests/ directory and applies the async configuration from pytest.ini to handle both sync and async test functions.

Can I write asynchronous tests without decorators?

Yes. Because backend/pytest.ini sets asyncio_mode = auto, you can define test functions using async def without requiring the @pytest.mark.asyncio decorator. The pytest-asyncio plugin automatically detects and manages the event loop for these tests.

Where are the example test files located?

Reference implementations are located at backend/tests/test_status_broadcast.py for broadcasting logic tests and backend/tests/test_screenshot.py for route testing. These files demonstrate patterns for both synchronous TestClient and asynchronous AsyncClient usage against the FastAPI app defined in backend/main.py.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →