How to Run Tests in the makeplane/plane Repository: Complete Guide
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 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.unitand use fixtures likecreate_userandapi_token. - Contract tests verify public API contracts for both the external API (
/api/v1/) and web-app API (/api/). These reside inplane.tests.contract.apiandplane.tests.contract.app, utilizingapi_key_clientfor API key authentication andsession_clientfor session-based authentication. - Smoke tests spin up a real Django test server to perform end-to-end checks. These are found in
plane.tests.smokeand rely on theplane_serverlive 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:
python -m pytest
Alternatively, use the convenience wrapper script located at apps/api/run_tests.py:
./run_tests.py
Targeting Specific Test Layers
During development, you can isolate specific test categories by targeting their directory paths:
# 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 script in apps/api/ provides shorthand flags for common workflows:
# 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:
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-Keyheader provided by theapi_key_clientfixture, while web-app tests use Django session cookies via thesession_clientfixture. - URL reversing: Use
reverse("api:endpoint_name")for external API endpoints andreverse("endpoint_name")for web-app endpoints. - Database access: Any test touching the database must include the
@pytest.mark.django_dbdecorator. - External service mocking: Fixtures like
mock_redis,mock_elasticsearch, andmock_celeryprevent 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:
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 pytestor theapps/api/run_tests.pyhelper script with flags like-u(unit),-c(contract), and-p(parallel). - The suite mocks external services (Redis, Elasticsearch, Celery) via fixtures defined in
conftest.pyandconftest_external.py, enabling local execution without containers. - Use
api_key_clientfor external API authentication andsession_clientfor web-app session authentication. - Generate coverage reports with
--cov=planeflags to produce HTML output inhtmlcov/.
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), 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 for an overview of test organization and apps/api/tests/RUNNING_TESTS.md for detailed execution instructions. Fixture definitions are located in apps/api/plane/tests/conftest.py and conftest_external.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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →