| name | testing |
| description | Create Scenescape pytest cases (unit, functional, integration, UI, BAT) with SCENESCAPE_SPEC, Zephyr IDs, and positive/negative coverage. Use when adding or modifying tests under tests/, writing pytest, or choosing unit vs functional vs UI. |
Creating Test Cases for Scenescape
Test philosophy
- Always add positive and negative cases (valid path + invalid/edge/boundary).
- Keep tests independent: own setup/teardown; no order dependence.
- Unit tests mock external deps; functional/UI use live services via fixtures.
Runtime verification (mandatory)
After creating or modifying tests, follow
.github/skills/test-verification-gate/SKILL.md
for target selection, image freshness, execution, and pass/fail reporting.
Do not treat lint or syntax checks as verification.
Import path policy (mandatory)
Before adding imports or path setup in a new or modified test file:
- Check
tests/conftest.py and the nearest local conftest.py.
- Confirm whether modules are already importable via existing fixtures/path setup.
- Use direct imports (e.g.
from controller...) when shared bootstrap already sets paths.
- Add path manipulation only if no shared bootstrap exists.
- If required, put setup once in the nearest
conftest.py — not per test module.
Prohibited: sys.path.insert(...) in individual test modules when equivalent setup can live in shared conftest.py.
Authoring report: state whether conftest files were checked, where import-path setup lives, and that no unnecessary per-file sys.path.insert was added.
Category routing
| Category | Location | When | Infrastructure |
|---|
| Unit | tests/sscape_tests/ or service */tests/ | Isolated functions/classes; no live services | Mocks; host pytest |
| Functional | tests/functional/ | Workflows with live REST/MQTT/DB | SCENESCAPE_SPEC + scenescape_env |
| Integration | tests/functional/ or tests/system/ | Cross-service pipelines | Same as functional |
| UI | tests/ui/ | Browser/Selenium flows | SCENESCAPE_SPEC + AUTH_BROWSER |
| BAT | functional/UI + @pytest.mark.basic_acceptance | Critical-path smoke | Same as parent category |
Read the matching reference under Additional resources before writing a category.
Hard requirements
- Zephyr ID: every test suite/module needs
NEX-T##### (TEST_NAME and/or record_xml_attribute).
- Functional/UI: declare module-level
SCENESCAPE_SPEC = FuncTestSpec(...) with the correct ServiceProfile from tests/utils/profiles.py.
- Naming: files
test_*.py, functions test_* (pytest norms).
- Markers that matter:
@pytest.mark.basic_acceptance — BAT / make run_basic_acceptance_tests
@pytest.mark.preserve_db — skip automatic DB restore
@pytest.mark.kubernetes_only — skipped on --backend=docker
Authoring checklist
Before marking a test-authoring task complete:
Additional resources
Automated eval cases: evals/evals.json.