Skip to content

Tests

This document outlines the testing procedures for the Aipress24 project. We use a combination of unit, integration, and end-to-end tests to ensure code quality and reliability.

Test organisation (tiers)

Python tests live under tests/ and are split into three tiers, run in order and increasingly close to a real environment:

  • tests/a_unit — fast, isolated unit tests. The db_session fixture yields None: these tests do not touch a database.
  • tests/b_integration — integration tests running inside a savepoint (nested transaction) that is rolled back after each test, so they share a fast, always-clean database without committing.
  • tests/c_e2e — end-to-end tests using a committing Flask test client against a fresh (drop/create) in-memory database (the fresh_db / logged_in_client / make_authenticated_client fixtures). These exercise real request → commit → teardown behaviour.

Tests must clean up after themselves: a tier must leave the database in the state the next tier expects.

The suite runs against both SQLite (default, fast) and PostgreSQL — see make test-sqlite / make test-postgres.

Browser-based end-to-end tests (Playwright) live under e2e_playwright/ and run against a running server (see below).

Prerequisites

Before running tests, ensure you have installed the necessary dependencies, including testing tools, as described in the Getting Started / Installation section of the README. This typically involves running:

make develop
make fake # if needed to generate fake data

Running Tests

The Makefile provides convenient shortcuts for various testing tasks. You can view all available testing commands by running:

make help

Here’s a breakdown of the most common testing scenarios:

Unit and Integration Tests

These tests are executed using pytest and cover individual components (unit tests) and their interactions (integration tests).

  • Run all tests (unit and integration):

    make test
    

    or
    pytest
    

  • Run tests in random order (helps detect order-dependent issues):

    make test-randomly
    
  • Run tests with coverage report:

    make test-with-coverage
    

    or
    pytest --cov=aipress24
    

  • Run tests with runtime type checking (using typeguard):

    make test-with-typeguard
    

    or
    pytest --typeguard-packages=aipress24
    

  • Run tests with runtime type checking (using beartype):

    make test-with-beartype
    

    or
    BEARTYPE_ENABLED=True pytest
    

Linting and Static Analysis

Before running tests, it’s highly recommended to run linters and static analysis to catch potential issues early.

make lint

or:
nox -s lint

End-to-End Tests

End-to-end tests simulate user interactions with the application and verify that the entire system works as expected.

pytest -vvv --browser firefox --video on --headed e2e_playwright

More information in the tests-e2e directory.

Nox Integration Tests

Nox is a powerful tool for automating tests in multiple environments. It uses a noxfile.py configuration file to define various testing sessions.

Nox sessions are shown by nox -l:

* test-3.12
* test-3.11
* test-3.10
* lint
- check_prod
  • test-3.12, test-3.11, test-3.10: These sessions run the test suite (using pytest) against Python 3.12, 3.11 and 3.10 respectively. This ensures that the code is compatible with different Python versions.
  • lint: This session runs linters and static analysis tools (e.g., ruff, mypy) to check code quality and catch potential errors, as configured in the noxfile.py
  • check_prod: This session checks the code for production readiness.

To run a specific Nox session, use nox -s <session_name>. For example:

nox -s test-3.12  # Run tests with Python 3.12
nox -s lint       # Run linters

Running nox without the -s flag will execute all sessions marked with a star * by default, in this case the tests against all supported Python versions.

Continuous Integration

CI runs primarily on SourceHut builds (.builds/), under Ubuntu 24.04, 26.06 and Rocky Linux.

The use of uv and nox in CI mirrors the recommended local development and testing workflow.

Cloud deployment

hop3 deploy deploys the application on a Hop3 server. See hop3.toml.

Notes

  • The Makefile shortcuts are recommended for ease of use and consistency.
  • Ensure your development environment is properly set up before running tests (see the “Development Environment” section in the README).
  • When contributing code, please make sure to add appropriate unit and integration tests to cover your changes.