Agent Skill
2/7/2026

gts-testing

Testing for GTS: TDD workflow, pytest patterns, fixtures, scaffolding, mutation verification, and anti-patterns. Use when writing tests, implementing features via TDD, debugging test failures, scaffolding new test files, or verifying mutations persist.

K
krazyuniks
0GitHub Stars
1Views
npx skills add krazyuniks/guitar-tone-shootout

SKILL.md

Namegts-testing
DescriptionTesting for GTS: TDD workflow, pytest patterns, fixtures, scaffolding, mutation verification, and anti-patterns. Use when writing tests, implementing features via TDD, debugging test failures, scaffolding new test files, or verifying mutations persist.

name: gts-testing description: "Testing for GTS: regression test authoring, pytest patterns, fixtures, scaffolding, mutation verification, and anti-patterns. Use when writing tests, debugging test failures, scaffolding new test files, or verifying mutations persist." context: fork

GTS Testing

Single reference for all testing in GTS. See .claude/rules/testing-policy.md for policy (auto-loaded).

Reference Files

Working OnRead
Test scaffolding templates (unit, integration, E2E, factory)references/test-scaffolding.md
Test suite audit (dead code, coverage gaps, health score)references/audit.md

Quick Reference

CommandScopeRuns In
just tdd <path>Single test fileDocker
just test-unitAll unit testsDocker
just test-integrationAll integration testsDocker
just testUnit + integrationDocker
just test-regressionStack connectivity (<1s)Docker
just test-golden-pathE2E user journeyHost
just checkFull quality gatesDocker

Regression Test Authoring

Tests are written AFTER the product works. Validation confirms the feature functions, then a regression test captures that working behaviour.

Common Mistakes (from Production Runs)

MistakeCorrect Behaviour
Modified existing test filesOnly CREATE new test files. Existing tests are immutable contracts.
Ran the full test suiteOnly run YOUR new/modified test files during development.
Imported non-existent packagesUse standard imports. Fail with ImportError, not SyntaxError.
Used wrong conftest fixturesUnit and integration fixtures are separate. Check which conftest applies.
Hit max turns without finishingStart with the simplest test. Iterate. Don't plan upfront.

Test Structure & Placement

tests/
  conftest.py              # Root config: markers, pytest_plugins
  fixtures/                # Shared fixtures (database, auth, factories)
  unit/
    backend/               # Pure logic, no external deps
    video/                 # Video composition tests
  integration/
    backend/               # Real DB, pgmq tests
    video/                 # Video API tests
  regression/              # Stack connectivity (<1s)
  e2e/
    python/                # E2E tests (pytest + Playwright, HOST only)
      conftest.py          # Browser fixtures, auth, DB access
      tests/               # Test files

Placement Decision

QuestionYesNo
Browser-based?tests/e2e/python/tests/ (HOST)Continue below
Needs real DB/pgmq?tests/integration/ (Docker)tests/unit/ (Docker)

Antipatterns

Banned Test Patterns

PatternIssue
assert True / assert x (truthy only)Trivial or weak
mock.assert_called() aloneSpy-only, no effect verification
pass only / @pytest.mark.skipNo assertions / defeats purpose
time.sleep()Flaky indicator
importlib.util / find_specFragile, use standard imports
db_session.get_bind()Returns sync Engine, breaks async

Forbidden Mocking

No mocking. The quality gate bans unittest.mock, @patch, Mock(), MagicMock(), AsyncMock().


Production-Learned Banned Patterns

These caused repeated failures in automated runs.

Test-Authoring

#PatternWhy BannedCorrect Approach
1importlib.util / find_specFalse failures (module found, attrs not loaded)Standard import; missing file = collection failure
2AsyncSession.get_bind()Returns sync EngineUse fixtures directly
3AsyncClient(app=...)Removed in HTTPX 0.28+AsyncClient(transport=ASGITransport(app=app), ...)
4Inline FastAPI() without set_session_override()Missing DB sessionUse conftest autouse fixture
5Testing backward-compat import removalUnsolvable contradictionTest NEW location works
6from __future__ import annotations in route modulesBreaks Depends() runtime resolution (422 errors)Import types directly
7Query param name mismatchTest URL param != endpoint paramUse Query(None, alias="...")

Infrastructure

#PatternCorrect Approach
8Close session + recreate from enginedb_session.expire_all() + re-query
9db_session.begin() nestingConftest uses _TestAsyncSession with begin_nested() fallback
10Module existence testingJust import it; missing file = collection failure
11conftest.py is NOT a test fileCan be modified by ALL agents for fixture changes
12Test helpers in production modulesPut in tests/fixtures/ or conftest.py
13lazy="raise" relationship accessUse joinedload() or session.refresh(obj, ["rel"])

E2E Testing (Golden Path)

E2E tests live in tests/e2e/python/tests/ and run on HOST only via just test-golden-path.

Three-Layer Verification

  1. UI action -- page.goto(), page.click(), page.fill()
  2. DOM verification -- expect(locator).to_be_visible(), text content checks
  3. Database verification -- Direct DB queries via text() (no ORM imports on host)

Key Constraints

  • Uses Playwright (not available in Docker)
  • CANNOT import internal packages (webapp, core, audio) -- use raw SQL via text()
  • Regression gate for the project

Key Fixtures

Fixture Quick Reference

Integration:

FixtureDescription
db_sessionAsync DB session with transaction rollback
test_userAuthenticated test user
other_userSecond user for isolation tests
clienthttpx AsyncClient (unauthenticated)
authenticated_clienthttpx AsyncClient with auth
auth_headers{"Authorization": "Bearer ..."}
make_signal_chainFactory for SignalChain
make_user_gearFactory for UserGear
make_shootoutFactory for Shootout

E2E:

FixtureDescription
pageAuthenticated Playwright page
guest_pageUnauthenticated page
frontend_urlBase URL (e.g., http://localhost:9000)
db_sessionDirect DB access for verification

Mutation Verification

For CRUD operations, verify persistence across three layers:

  1. UI Response -- Success toast, no errors, expected state change
  2. API Response -- 2xx status (watch for 409 conflict, 422 validation, 500 crash)
  3. Database State -- Direct query to confirm persistence
SymptomCauseFix
UI success, DB emptyTransaction not committedawait session.commit()
409 ConflictUnique constraintCheck for existing record
500 ErrorMissing foreign keyVerify related entity exists
Stale after refreshCache not invalidatedClear cache after mutation

Markers

MarkerUse WhenAuto-Applied
unitSingle function/classtests/unit/
integrationReal DB, pgmqtests/integration/
e2eBrowser-basedtests/e2e/
e2e_quick / e2e_fullFast/comprehensive E2EManual
smokeCritical pathManual
t3k_integrationReal T3K API (skip in CI)Manual

Failure Recovery

FailureAction
Tests won't passjust tdd <path> -v --tb=long
Test quality failedRewrite -- no trivial assertions
Golden path failingFix product code, then re-run
Skills Info
Original Name:gts-testingAuthor:krazyuniks