|
| 1 | +--- |
| 2 | +paths: |
| 3 | + - "tests/unit/**/*.py" |
| 4 | +--- |
| 5 | + |
| 6 | +# Unit test rules |
| 7 | + |
| 8 | +Unit tests cover pure logic, data transformations, schema parsing, and error handling. Use `httpx_mock` to simulate HTTP responses at the transport boundary. Do not substitute a mocked unit test for behaviour that depends on Infrahub's actual server responses — write an integration test for that. |
| 9 | + |
| 10 | +## HTTP mocking with `httpx_mock` |
| 11 | + |
| 12 | +Add the module-level marker when any fixture or test in the file reuses mocked responses: |
| 13 | + |
| 14 | +```python |
| 15 | +pytestmark = pytest.mark.httpx_mock(can_send_already_matched_responses=True) |
| 16 | +``` |
| 17 | + |
| 18 | +Use `is_reusable=True` on fixtures that serve multiple tests: |
| 19 | + |
| 20 | +```python |
| 21 | +@pytest.fixture |
| 22 | +async def mock_branch_list(httpx_mock: HTTPXMock) -> HTTPXMock: |
| 23 | + httpx_mock.add_response( |
| 24 | + method="POST", |
| 25 | + json={"data": {"Branch": [...]}}, |
| 26 | + match_headers={"X-Infrahub-Tracker": "query-branch-all"}, |
| 27 | + is_reusable=True, |
| 28 | + ) |
| 29 | + return httpx_mock |
| 30 | +``` |
| 31 | + |
| 32 | +## Testing both async and sync clients |
| 33 | + |
| 34 | +Use the `BothClients` fixture from `tests/unit/sdk/conftest.py` when behaviour must be verified for both client variants. Parametrize over `["standard", "sync"]`: |
| 35 | + |
| 36 | +```python |
| 37 | +@pytest.mark.parametrize("client_type", ["standard", "sync"]) |
| 38 | +async def test_branch_list(clients: BothClients, client_type: str, mock_branch_list: HTTPXMock) -> None: |
| 39 | + if client_type == "standard": |
| 40 | + branches = await clients.standard.branch.all() |
| 41 | + else: |
| 42 | + branches = clients.sync.branch.all() |
| 43 | + assert list(branches.keys()) == ["main", "branch01"] |
| 44 | +``` |
| 45 | + |
| 46 | +Assert the actual expected value. Assertions like `assert result is not None` or `assert result` do not verify behaviour — they only confirm something was returned. |
| 47 | + |
| 48 | +## Test file layout |
| 49 | + |
| 50 | +Mirror the source structure: |
| 51 | + |
| 52 | +```text |
| 53 | +infrahub_sdk/client.py → tests/unit/sdk/test_client.py |
| 54 | +infrahub_sdk/ctl/commands/get.py → tests/unit/ctl/test_get.py |
| 55 | +``` |
| 56 | + |
| 57 | +## No external dependencies |
| 58 | + |
| 59 | +Unit tests must not connect to external services, local file access is fine. If a test requires a running Infrahub instance, it belongs in `tests/integration/`. |
0 commit comments