# How to Run Tests in the makeplane/plane Repository: Complete Guide

> Master running tests in the makeplane/plane repository. This guide details pytest unit, contract, and smoke tests for Django backend services. Execute tests easily with standard commands or our helper script.

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

---

**The makeplane/plane repository ships with a comprehensive pytest-based test suite that validates Django backend services through three distinct layers—unit, contract, and smoke tests—executable via standard pytest commands or the [`apps/api/run_tests.py`](https://github.com/makeplane/plane/blob/main/apps/api/run_tests.py) helper script.**

The Plane open-source project maintains a robust testing infrastructure located under `apps/api/plane/tests/` that supports local execution without requiring external containers like Redis or Elasticsearch. Because the suite relies on fixtures that mock external services, developers can run the full test matrix locally to validate API contracts and end-to-end workflows.

## Test Suite Architecture

The Plane codebase organizes tests into three logical layers, each serving a specific validation purpose:

- **Unit tests** isolate individual functions or model methods. These live in `plane.tests.unit` and use fixtures like `create_user` and `api_token`.
- **Contract tests** verify public API contracts for both the external API (`/api/v1/`) and web-app API (`/api/`). These reside in `plane.tests.contract.api` and `plane.tests.contract.app`, utilizing `api_key_client` for API key authentication and `session_client` for session-based authentication.
- **Smoke tests** spin up a real Django test server to perform end-to-end checks. These are found in `plane.tests.smoke` and rely on the `plane_server` live server fixture.

## How to Run Tests in the makeplane/plane Repository

### Running the Full Test Suite

To execute all test layers—unit, contract, and smoke—run the standard pytest command from the API directory:

```bash
python -m pytest

```

Alternatively, use the convenience wrapper script located at [`apps/api/run_tests.py`](https://github.com/makeplane/plane/blob/main/apps/api/run_tests.py):

```bash
./run_tests.py

```

### Targeting Specific Test Layers

During development, you can isolate specific test categories by targeting their directory paths:

```bash

# Unit tests only

python -m pytest plane/tests/unit/

# External API contract tests

python -m pytest plane/tests/contract/api/

# Web-app (App) contract tests

python -m pytest plane/tests/contract/app/

# Smoke tests (live server)

python -m pytest plane/tests/smoke/

```

### Using the run_tests.py Helper Script

The [`run_tests.py`](https://github.com/makeplane/plane/blob/main/run_tests.py) script in `apps/api/` provides shorthand flags for common workflows:

```bash

# Run only unit tests

./run_tests.py -u

# Run contract tests with coverage report

./run_tests.py -c -o

# Execute tests in parallel (uses pytest-xdist)

./run_tests.py -p

```

**Note:** When using parallel execution (`-p`), ensure your machine has sufficient RAM, as pytest-xdist spawns multiple workers.

### Generating Coverage Reports

To generate both terminal and HTML coverage reports, execute:

```bash
python -m pytest --cov=plane --cov-report=term --cov-report=html

```

The HTML report will be available in the `htmlcov/` directory after execution.

## Key Testing Concepts and Fixtures

Understanding the testing conventions in `apps/api/plane/tests/` ensures accurate test implementation:

- **Authentication methods:** External API tests require an `X-Api-Key` header provided by the `api_key_client` fixture, while web-app tests use Django session cookies via the `session_client` fixture.
- **URL reversing:** Use `reverse("api:endpoint_name")` for external API endpoints and `reverse("endpoint_name")` for web-app endpoints.
- **Database access:** Any test touching the database must include the `@pytest.mark.django_db` decorator.
- **External service mocking:** Fixtures like `mock_redis`, `mock_elasticsearch`, and `mock_celery` prevent real network calls, keeping the suite deterministic and fast.

## Example Test Implementation

Below is a practical example of a contract test using the API-key authenticated client:

```python
import pytest
from django.urls import reverse

@pytest.mark.contract
@pytest.mark.django_db
def test_create_issue(api_key_client):
    url = reverse("api:issues-list")
    resp = api_key_client.post(url, {"name": "Test issue", "project": 1})
    assert resp.status_code == 201
    assert resp.json()["name"] == "Test issue"

```

## Summary

- The Plane repository uses pytest to organize tests into **unit**, **contract**, and **smoke** layers under `apps/api/plane/tests/`.
- Execute tests using `python -m pytest` or the [`apps/api/run_tests.py`](https://github.com/makeplane/plane/blob/main/apps/api/run_tests.py) helper script with flags like `-u` (unit), `-c` (contract), and `-p` (parallel).
- The suite mocks external services (Redis, Elasticsearch, Celery) via fixtures defined in [`conftest.py`](https://github.com/makeplane/plane/blob/main/conftest.py) and [`conftest_external.py`](https://github.com/makeplane/plane/blob/main/conftest_external.py), enabling local execution without containers.
- Use `api_key_client` for external API authentication and `session_client` for web-app session authentication.
- Generate coverage reports with `--cov=plane` flags to produce HTML output in `htmlcov/`.

## Frequently Asked Questions

### What is the difference between contract and smoke tests in Plane?

Contract tests verify the API schema and response formats for the external (`/api/v1/`) and web-app (`/api/`) interfaces using mocked dependencies, while smoke tests spin up an actual Django test server via the `plane_server` fixture to validate end-to-end workflows with real HTTP requests.

### Can I run tests without installing Redis or Elasticsearch locally?

Yes. The test suite in `makeplane/plane` includes fixtures that mock Redis, Elasticsearch, and Celery (located in [`conftest_external.py`](https://github.com/makeplane/plane/blob/main/conftest_external.py)), allowing the full test suite to run locally without external containers or services.

### How do I authenticate API requests in Plane contract tests?

External API contract tests use the `api_key_client` fixture, which automatically injects an `X-Api-Key` header into requests. Web-app contract tests use the `session_client` fixture, which handles Django session cookie authentication for endpoints under the web-app namespace.

### Where can I find more detailed documentation about Plane's testing strategy?

Reference the [`apps/api/plane/tests/README.md`](https://github.com/makeplane/plane/blob/main/apps/api/plane/tests/README.md) for an overview of test organization and [`apps/api/tests/RUNNING_TESTS.md`](https://github.com/makeplane/plane/blob/main/apps/api/tests/RUNNING_TESTS.md) for detailed execution instructions. Fixture definitions are located in [`apps/api/plane/tests/conftest.py`](https://github.com/makeplane/plane/blob/main/apps/api/plane/tests/conftest.py) and [`conftest_external.py`](https://github.com/makeplane/plane/blob/main/conftest_external.py).