# Testing Guide for OpenTTD Python Client This guide explains how the test suite is structured, the types of tests available, and how to execute them. --- ## 📂 Test Suite Structure The tests are located in the `tests/` directory: | Test File | Target | Description | | :--- | :--- | :--- | | [`test_admin.py`](file:///home/kovagoadi/openttd-client/tests/test_admin.py) | `OpenTTDAdminClient` | Tests admin client initialization, admin packet types, and basic protocol constants. | | [`test_protocol.py`](file:///home/kovagoadi/openttd-client/tests/test_protocol.py) | `OpenTTDProtocol` | Tests binary serialization, custom parsers, and stream encryption/decryption (XChaCha20-Poly1305). | | [`test_logic.py`](file:///home/kovagoadi/openttd-client/tests/test_logic.py) | `OpenTTDClient` | Tests client connection lifecycle, company joining flow, authentication, and state management. | | [`test_coverage.py`](file:///home/kovagoadi/openttd-client/tests/test_coverage.py) | Coverage Helpers | Auxiliary unit tests targeting connection errors, fallback packet handlers, and missing passwords to ensure high test coverage. | | [`test_e2e.py`](file:///home/kovagoadi/openttd-client/tests/test_e2e.py) | Integration / E2E | Connects to a running local OpenTTD server (e.g., in Docker) to verify full socket interactions, stream cryptography, and keep-alive frames. | --- ## 🚀 How to Run Tests Pytest automatically uses [`pytest.ini`](file:///home/kovagoadi/openttd-client/pytest.ini) to configure the Python import path (`pythonpath = lib`). You do not need to manually configure `PYTHONPATH`. Make sure your virtual environment is active before running commands: ```bash source venv/bin/activate ``` ### 1. Run Normal (Non-E2E) Tests These are unit and logic tests that run instantly in memory without external dependencies: ```bash pytest -m "not e2e" ``` ### 2. Run E2E Tests Only Requires a running local OpenTTD server configured with password `"asd"`. If the server is offline, this test will fail: ```bash pytest -m "e2e" ``` --- ## 🐳 Starting the OpenTTD Server (Docker) To run E2E tests locally, you can start the dedicated JGRPP OpenTTD server using the provided Docker Compose configuration in the `docker/` directory. ### 1. Build and Start the Server Run this command from the project root directory: ```bash docker compose -f docker/docker-compose.yml up -d --build ``` *Note: The first build will clone and compile the JGRPP source code, which may take a few minutes.* ### 2. Monitor Server Logs To watch the server logs (e.g., to see client connections and events): ```bash docker compose -f docker/docker-compose.yml logs -f ``` ### 3. Stop the Server To stop the server container: ```bash docker compose -f docker/docker-compose.yml down ``` ### 3. Run All Tests Runs both unit/logic tests and E2E tests: ```bash pytest ``` ### 4. Run with Coverage Report To view statement coverage statistics: ```bash pytest --cov=openttd --cov-report=term-missing ``` --- ## 📊 Testing Mandate We enforce the following testing mandates: * **Normal/Unit tests (`pytest -m "not e2e"`)** must achieve 100% code coverage on the codebase independently. * **E2E tests (`pytest -m "e2e"`)** do NOT require 100% code coverage. Instead, they are only required to cover every public function of the client classes (`OpenTTDClient` and `OpenTTDAdminClient`) and protocol classes with multiple (varied) inputs/scenarios. To run/verify tests: * **Normal Tests (Must achieve 100% coverage):** ```bash pytest -m "not e2e" --cov=openttd --cov-report=term-missing --cov-fail-under=100 ``` * **E2E Tests (No coverage mandate, must cover all public functions with multiple inputs):** ```bash pytest -m "e2e" ``` --- ## 🔧 Pytest Configuration (`pytest.ini`) The project uses a [`pytest.ini`](file:///home/kovagoadi/openttd-client/pytest.ini) file at the root: - **`pythonpath = lib`**: Simplifies invocation by resolving imports from the local `lib/` directory. - **`markers`**: Registers the custom `e2e` marker for pytest classification.