# How to Run API Tests in the Plane Backend: A Complete Docker Guide

> Learn how to run API tests in the Plane backend using Docker. This guide details the Docker Compose setup for isolated testing with temporary databases and services.

- Repository: [Plane/plane](https://github.com/makeplane/plane)
- Tags: how-to-guide
- Published: 2026-08-22

---

**The Plane backend API test suite runs inside an isolated Docker Compose stack defined in [`docker-compose-test.yml`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml), which spins up temporary PostgreSQL, Valkey, RabbitMQ, and MinIO containers before executing pytest from the `api-tests` service.**

The `makeplane/plane` repository uses a fully containerized approach to ensure reproducible test runs. Instead of requiring a local database or Redis instance, the test harness orchestrates ephemeral infrastructure through Docker Compose, allowing developers to execute unit, contract, and integration tests in a clean environment for every run.

## Prerequisites and Environment Setup

Before executing any Docker commands, you must prepare the environment configuration files. The repository includes a helper script that copies template files to active configuration locations.

Run the setup script from the repository root:

```bash
./setup.sh

```

This script copies `apps/api/.env.example` to `apps/api/.env`, along with environment files for other applications. The [`docker-compose-test.yml`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml) file reads variables from `apps/api/.env`, making this step mandatory before launching the test stack.

## Understanding the Docker Compose Test Stack

The test infrastructure is defined in **[`docker-compose-test.yml`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml)** at the repository root. This configuration launches five interconnected services:

- **`test-db`** – PostgreSQL 15.7 Alpine for the test database
- **`test-redis`** – Valkey 7.2.11 Alpine (Redis-compatible) for caching and Celery broker
- **`test-mq`** – RabbitMQ 3.13.6 with management UI for task queuing
- **`test-minio`** – MinIO for S3-compatible object storage testing
- **`api-tests`** – Custom image built from `apps/api/Dockerfile.dev` that executes pytest

The `api-tests` service declares explicit `depends_on` conditions with health checks for all data stores. The container waits until PostgreSQL, Valkey, RabbitMQ, and MinIO report healthy status before launching the test runner.

## Running the Full API Test Suite

To execute the entire test suite with proper exit code propagation and automatic cleanup of dependent services, use the following command:

```bash
docker compose -f docker-compose-test.yml up \
  --build \
  --abort-on-container-exit \
  --exit-code-from api-tests

```

**Command breakdown:**

- **`--build`** – Recompiles the `api-tests` image when `Dockerfile.dev` or test requirements change
- **`--abort-on-container-exit`** – Stops all supporting containers (database, cache, etc.) immediately when the test container finishes
- **`--exit-code-from api-tests`** – Propagates pytest’s exit status to the shell, ensuring CI pipelines correctly detect failures

## Running Specific Test Subsets

You can override the default pytest command to run specific markers, directories, or individual files using `docker compose run`.

**Run only unit tests:**

```bash
docker compose -f docker-compose-test.yml run --rm --build api-tests pytest -m unit

```

**Run a specific test directory with verbose output:**

```bash
docker compose -f docker-compose-test.yml run --rm api-tests \
  pytest plane/tests/unit/models/ -vv

```

**Run a single test file:**

```bash
docker compose -f docker-compose-test.yml run --rm api-tests \
  pytest plane/tests/unit/models/test_workspace.py -vv

```

## Test Configuration and Markers

Test categorization is controlled by **[`apps/api/pytest.ini`](https://github.com/makeplane/plane/blob/main/apps/api/pytest.ini)**, which defines markers used to filter test runs:

- **`unit`** – Fast, isolated unit tests
- **`contract`** – API contract validation tests
- **`smoke`** – Critical path smoke tests
- **`slow`** – Long-running integration tests

The `api-tests` service automatically sets `DJANGO_SETTINGS_MODULE=plane.settings.test` via environment variables defined in [`docker-compose-test.yml`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml) (lines 10-20). This ensures the Django configuration points to the temporary PostgreSQL and Redis instances rather than production endpoints.

## Cleanup and Teardown

After test execution, remove the temporary volumes and network to ensure a clean slate for subsequent runs:

```bash
docker compose -f docker-compose-test.yml down -v

```

The `-v` flag deletes named volumes containing test data, preventing state leakage between test sessions.

## Summary

- **Containerized execution** – API tests run inside Docker via [`docker-compose-test.yml`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml), eliminating local dependency conflicts
- **Ephemeral infrastructure** – PostgreSQL, Valkey, RabbitMQ, and MinIO containers are created fresh for each test run
- **Setup requirement** – Always run [`./setup.sh`](https://github.com/makeplane/plane/blob/main/./setup.sh) first to generate required `.env` files from templates
- **Flexible filtering** – Use pytest markers (`-m unit`, `-m contract`) or file paths to run specific subsets
- **Clean teardown** – Execute `docker compose -f docker-compose-test.yml down -v` to remove test artifacts

## Frequently Asked Questions

### How do I debug a failing test in the Plane backend?

Use `docker compose run` with the `--rm` flag to access an interactive shell. You can override the command to enter a bash session inside the test container, then manually invoke pytest with `--pdb` to drop into the debugger when failures occur.

### Can I run API tests without Docker?

The Plane backend test suite is designed specifically for Docker execution as defined in [`docker-compose-test.yml`](https://github.com/makeplane/plane/blob/main/docker-compose-test.yml). While theoretically possible to run pytest locally against manually provisioned services, the official [`RUNNING_TESTS.md`](https://github.com/makeplane/plane/blob/main/RUNNING_TESTS.md) documentation only supports the containerized approach to ensure environment consistency.

### Where are the test fixtures and utilities defined?

Shared test fixtures, including `api_client` and `create_user`, are documented in **[`apps/api/plane/tests/TESTING_GUIDE.md`](https://github.com/makeplane/plane/blob/main/apps/api/plane/tests/TESTING_GUIDE.md)**. These utilities handle authentication, database setup, and mock object creation for the Django test environment.

### Why does the test suite use Valkey instead of Redis?

The `test-redis` service uses `valkey/valkey:7.2.11-alpine`, an open-source Redis fork. This provides Redis-compatible caching and queue functionality while aligning with the project's open-source licensing requirements. The connection strings in `plane.settings.test` point to this Valkey instance automatically.