Files
ss-tools/.opencode/skills/semantics-testing/SKILL.md
busya 143f14d516 chore: remainder — backend test infra, agent config, docker, i18n, frontend ui
- Backend: alembic env, config manager/models, dependencies, translate plugin
- Backend tests: async_sync_regression, integration tests, git services, test_agent
- Docker: docker-compose.yml updates
- Agent: qa-tester.md update, semantics-testing SKILL.md update
- Frontend: TopNavbar, sidebarNavigation, FeaturesSettings, FeatureGate
- i18n: assistant.json en/ru locale updates
- New: frontend/src/lib/components/agent/ directory
2026-06-10 15:06:36 +03:00

181 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: semantics-testing
description: Core protocol for Test Constraints, External Ontology, Graph Noise Reduction, and Invariant Traceability for Python (pytest) and Svelte (vitest) projects.
---
#region Std.Semantics.Testing [C:5] [TYPE Skill] [SEMANTICS testing,qa,verification,pytest,vitest]
@BRIEF HOW to write tests: constraints, external ontology, graph noise reduction, and invariant traceability for pytest and vitest.
@RELATION DEPENDS_ON -> [Std.Semantics.Core]
@RELATION DEPENDS_ON -> [Std.Semantics.Svelte]
@INVARIANT Test modules must trace back to production @INVARIANT tags without flooding the Semantic Graph with orphan nodes.
@RATIONALE Test contracts trace to production @INVARIANT/@POST tags via @TEST_INVARIANT, preventing orphan nodes. pytest+vitest dual stack eliminates cross-language tooling overhead. 3-edge-case floor balances coverage sufficiency against graph noise. Hardcoded fixtures block logic-mirror tautology — the dominant LLM test-generation failure mode where the agent re-implements the production algorithm inside the test as `expected = compute(x)`. The test always passes but proves nothing because it's a copy of what it's testing.
@REJECTED Property-based testing — non-deterministic input space creates unbounded graph edges, irreducible to fixed-scenario tracing. Snapshot testing — brittle to CSS/UI changes without invariant signal. Integration-only (no unit tests) — coarse graph edges miss localized @INVARIANT violations. Cucumber/Gherkin BDD — DSL layer breaks direct traceability to Python/Svelte @POST anchors. Dynamic expected-value computation — `expected = production_fn(x)` is a tautology, not a test; hardcoded fixtures are the only valid approach.
## 0. QA RATIONALE (LLM PHYSICS IN TESTING)
You are an Agentic QA Engineer. Your primary failure modes are:
1. **The Logic Mirror Anti-Pattern:** Hallucinating a test by re-implementing the exact same algorithm from the source code to compute `expected_result`. This creates a tautology (a test that always passes but proves nothing).
2. **Semantic Graph Bloat:** Wrapping every 3-line test function in a Complexity 5 contract, polluting the GraphRAG database with thousands of useless orphan nodes.
Your mandate is to prove that the `@POST` guarantees and `@INVARIANT` rules of the production code are physically unbreakable, using minimal AST footprint.
## I. EXTERNAL ONTOLOGY (BOUNDARIES)
When writing code or tests that depend on 3rd-party libraries or shared schemas that DO NOT have local anchors in our repository, you MUST use strict external prefixes.
**CRITICAL RULE:** Do NOT hallucinate anchors for external code.
1. **External Libraries (`[EXT:Package:Module]`):**
- Use for 3rd-party dependencies.
- Example: `@RELATION DEPENDS_ON -> [EXT:FastAPI:Router]` or `[EXT:SQLAlchemy:Session]`
- Svelte: `[EXT:SvelteKit:load]`
2. **Shared DTOs (`[DTO:Name]`):**
- Use for globally shared schemas, Pydantic models, or external registry definitions.
- Example: `@RELATION DEPENDS_ON -> [DTO:DashboardExportPayload]`
## II. TEST MARKUP ECONOMY (NOISE REDUCTION)
To prevent overwhelming Semantic Graph, test files operate under relaxed complexity rules:
1. **Short hierarchical IDs:** Test modules use `Test.Domain.Name` format (e.g., `Test.Migration.RunTask`), not full file paths or flat names. This satisfies ATTN_2: the `Test.` prefix groups all tests under HCA 128× while the domain name provides DSA Indexer grouping.
2. **Root Binding (`BINDS_TO`):** Do NOT map the internal call graph of a test file. Instead, anchor the entire test suite to the production module using: `@RELATION BINDS_TO -> [TargetModule]`.
3. **Complexity 1 for Helpers:** Small test utilities (e.g., `_setup_mock`, `_build_payload`) are **C1**. They require ONLY the anchor pair. No `@BRIEF` or `@RELATION` allowed.
4. **Complexity 2 for Tests:** Actual test functions (e.g., `test_unauthorized_access`) are **C2**. They require anchor + `@BRIEF`. Do not add `@PRE`/`@POST` to individual test functions.
5. **Maximum test file size:** A single test file MUST NOT exceed **600 lines**. Beyond this threshold:
- Split into multiple test files by domain (e.g., `test_auth_flow.py`, `test_auth_ws.py` instead of `test_auth.py`).
- Extract shared fixtures into a `conftest.py` in the same directory.
- Each test class tests ONE production contract — if a file has more than 3 test classes, split by class.
- **Exception:** Integration test files using Testcontainers may be up to **800 lines** due to longer setup/teardown.
- **RATIONALE:** Files >600 lines degrade the model's sliding-window attention — the bottom of the file is compressed before the top is applied, leading to duplicate tests and orphan contracts.
## III. TRACEABILITY & TEST CONTRACTS
In the Header of your Test Module, you MUST define the Test Contracts. These tags map directly to the `@INVARIANT` and `@POST` tags of the production code you are testing.
- `@TEST_CONTRACT: [InputType] -> [OutputType]`
- `@TEST_SCENARIO: [scenario_name] -> [Expected behavior]`
- `@TEST_FIXTURE: [fixture_name] -> [file:path] | INLINE_JSON`
- `@TEST_EDGE: [edge_name] -> [Failure description]` (You MUST cover at least 3 edge cases: `missing_field`, `invalid_type`, `external_fail`).
- **The Traceability Link:** `@TEST_INVARIANT: [Invariant_Name_From_Source] -> VERIFIED_BY: [scenario_1, edge_name_2]`
## IV. ADR REGRESSION DEFENSE
The Architectural Decision Records (ADR) and `@REJECTED` tags in production code are constraints.
If the production contract has a `@REJECTED [Forbidden_Path]` tag (e.g., `@REJECTED fallback to SQLite`), your Test Module MUST contain an explicit `@TEST_EDGE` scenario proving that the forbidden path is physically unreachable or throws an appropriate error.
Tests are the enforcers of architectural memory.
## V. ANTI-TAUTOLOGY RULES
1. **No Logic Mirrors:** Use deterministic, hardcoded fixtures (`@TEST_FIXTURE`) for expected results. Do not dynamically calculate `expected = a + b` to test an `add(a, b)` function.
2. **Do Not Mock The System Under Test:** You may mock `[EXT:...]` boundaries (like DB drivers or external APIs), but you MUST NOT mock the local contract node you are actively verifying.
## VI. PYTHON / PYTEST CONVENTIONS
### Test file structure
```
backend/tests/
├── conftest.py # Shared fixtures, mock setup (C3 Module)
├── test_auth.py # Auth tests (C2 Module, BINDS_TO -> AuthService)
├── test_migration.py # Migration tests
└── test_plugins/ # Plugin-specific tests
```
### Test module template
```python
# #region Test.Migration.RunTask [C:3] [TYPE Module] [SEMANTICS test,migration]
# @BRIEF Verify dashboard migration contracts — @POST guarantees and rejected paths.
# @RELATION BINDS_TO -> [Migration.RunTask]
# @TEST_EDGE: missing_db_mapping -> Migration fails with MappingError
# @TEST_EDGE: invalid_dashboard_id -> Migration fails with NotFoundError
# @TEST_EDGE: external_api_timeout -> Migration fails with TimeoutError, rolls back
import pytest
from unittest.mock import AsyncMock, patch
class TestDashboardMigration:
"""Verify migrate_dashboard @POST guarantees."""
# #region test_migrate_dashboard_success [C:2] [TYPE Function]
# @BRIEF Happy path: valid dashboard with complete db mapping.
@pytest.mark.asyncio
async def test_migrate_dashboard_success(self):
# Use hardcoded fixture, not algorithmic computation
expected = {"id": "dash_1", "status": "imported"}
# ... test implementation
pass
# #endregion test_migrate_dashboard_success
# #endregion TestDashboardMigration
```
### Running tests
```bash
# All backend tests
cd backend && source .venv/bin/activate && python -m pytest -v
# Specific test file
python -m pytest tests/test_migration.py -v
# With coverage
python -m pytest --cov=src --cov-report=term-missing
```
## VII. SVELTE / VITEST CONVENTIONS
### Test file structure
```
frontend/src/
├── lib/
│ ├── components/__tests__/ # Component tests
│ │ ├── MigrationTaskCard.test.js
│ │ └── StatusBadge.test.js
│ └── stores/__tests__/ # Store tests
│ └── taskDrawer.test.js
```
### Component test template
```javascript
import { render, screen, fireEvent } from "@testing-library/svelte";
import { describe, it, expect, vi } from "vitest";
import ComponentName from "../ComponentName.svelte";
describe("ComponentName", () => {
it("renders with props", () => {
const { container } = render(ComponentName, {
props: { title: "Test", status: "idle" }
});
expect(container.textContent).toContain("Test");
});
it("shows loading state on action", async () => {
// Use mock API, verify loading states
});
});
```
### Running tests
```bash
# All frontend tests
cd frontend && npm run test
# Watch mode
npm run test:watch
```
## VIII. VERIFIABLE HARNESS RULES
For agentic development, a test harness is part of the task environment.
- Prefer real executable checks over narrative claims that a change is safe.
- Verify that the harness actually fails on the broken state and passes on the fixed state whenever feasible.
- Resist shortcut tests that bypass the real integration boundary the task is supposed to validate.
- When a production `@POST` guarantee is subtle, add the narrowest test that can falsify it.
## IX. LONG-HORIZON QA MEMORY
When multiple attempts are needed:
- Preserve the smallest set of failing fixtures, commands, and invariant mappings that explain the current gap.
- Fold older failed attempts into one bounded note describing what was tried and why it was rejected.
- Do not keep extending the active QA transcript with redundant command output.
## X. TESTING SEARCH DISCIPLINE
- Use one concrete failing hypothesis plus one verifier by default.
- Add alternative test strategies only when the first verifier is inconclusive.
- Do not mirror the implementation logic to fabricate expected values; use fixtures, explicit contracts, and invariant-oriented assertions.
#endregion Std.Semantics.Testing