{ "verdict": "APPROVED", "rejection_reason": "NONE", "audit_details": { "target_invoked": true, "pre_conditions_tested": true, "post_conditions_tested": true, "test_data_used": true }, "feedback": "Both test files have successfully passed the audit. The 'task_log_viewer.test.js' suite now correctly imports and mounts the real Svelte component using Test Library, fully eliminating the logic mirror/tautology issue. The 'test_logger.py' suite now properly implements negative tests for the @PRE constraint in 'belief_scope' and fully verifies all @POST effects triggered by 'configure_logger'." }
This commit is contained in:
63
.ai/knowledge/test_import_patterns.md
Normal file
63
.ai/knowledge/test_import_patterns.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Backend Test Import Patterns
|
||||
|
||||
## Problem
|
||||
|
||||
The `ss-tools` backend uses **relative imports** inside packages (e.g., `from ...models.task import TaskRecord` in `persistence.py`). This creates specific constraints on how and where tests can be written.
|
||||
|
||||
## Key Rules
|
||||
|
||||
### 1. Packages with `__init__.py` that re-export via relative imports
|
||||
|
||||
**Example**: `src/core/task_manager/__init__.py` imports `.manager` → `.persistence` → `from ...models.task` (3-level relative import).
|
||||
|
||||
**Impact**: Co-located tests in `task_manager/__tests__/` **WILL FAIL** because pytest discovers `task_manager/` as a top-level package (not as `src.core.task_manager`), and the 3-level `from ...` goes beyond the top-level.
|
||||
|
||||
**Solution**: Place tests in `backend/tests/` directory (where `test_task_logger.py` already lives). Import using `from src.core.task_manager.XXX import ...` which works because `backend/` is the pytest rootdir.
|
||||
|
||||
### 2. Packages WITHOUT `__init__.py`:
|
||||
|
||||
**Example**: `src/core/auth/` has NO `__init__.py`.
|
||||
|
||||
**Impact**: Co-located tests in `auth/__tests__/` work fine because pytest doesn't try to import a parent package `__init__.py`.
|
||||
|
||||
### 3. Modules with deeply nested relative imports
|
||||
|
||||
**Example**: `src/services/llm_provider.py` uses `from ..models.llm import LLMProvider` and `from ..plugins.llm_analysis.models import LLMProviderConfig`.
|
||||
|
||||
**Impact**: Direct import (`from src.services.llm_provider import EncryptionManager`) **WILL FAIL** if the relative chain triggers a module not in `sys.path` or if it tries to import beyond root.
|
||||
|
||||
**Solution**: Either (a) re-implement the tested logic standalone in the test (for small classes like `EncryptionManager`), or (b) use `unittest.mock.patch` to mock the problematic imports before importing the module.
|
||||
|
||||
## Working Test Locations
|
||||
|
||||
| Package | `__init__.py`? | Relative imports? | Co-located OK? | Test location |
|
||||
|---|---|---|---|---|
|
||||
| `core/task_manager/` | YES | `from ...models.task` (3-level) | **NO** | `backend/tests/` |
|
||||
| `core/auth/` | NO | N/A | YES | `core/auth/__tests__/` |
|
||||
| `core/logger/` | NO | N/A | YES | `core/logger/__tests__/` |
|
||||
| `services/` | YES (empty) | shallow | YES | `services/__tests__/` |
|
||||
| `services/reports/` | YES | `from ...core.logger` | **NO** (most likely) | `backend/tests/` or mock |
|
||||
| `models/` | YES | shallow | YES | `models/__tests__/` |
|
||||
|
||||
## Safe Import Patterns for Tests
|
||||
|
||||
```python
|
||||
# In backend/tests/test_*.py:
|
||||
import sys
|
||||
from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
||||
|
||||
# Then import:
|
||||
from src.core.task_manager.models import Task, TaskStatus
|
||||
from src.core.task_manager.persistence import TaskPersistenceService
|
||||
from src.models.report import TaskReport, ReportQuery
|
||||
```
|
||||
|
||||
## Plugin ID Mapping (for report tests)
|
||||
|
||||
The `resolve_task_type()` uses **hyphenated** plugin IDs:
|
||||
- `superset-backup` → `TaskType.BACKUP`
|
||||
- `superset-migration` → `TaskType.MIGRATION`
|
||||
- `llm_dashboard_validation` → `TaskType.LLM_VERIFICATION`
|
||||
- `documentation` → `TaskType.DOCUMENTATION`
|
||||
- anything else → `TaskType.UNKNOWN`
|
||||
Reference in New Issue
Block a user