gaia-framework 1.57.0 → 1.57.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/gaia-framework.js +27 -19
- package/gaia-install.sh +1 -1
- package/package.json +15 -11
- package/.claude/commands/gaia-a11y-testing.md +0 -17
- package/.claude/commands/gaia-action-items.md +0 -23
- package/.claude/commands/gaia-add-feature.md +0 -17
- package/.claude/commands/gaia-add-stories.md +0 -17
- package/.claude/commands/gaia-advanced-elicitation.md +0 -17
- package/.claude/commands/gaia-adversarial.md +0 -15
- package/.claude/commands/gaia-agent-analyst.md +0 -14
- package/.claude/commands/gaia-agent-architect.md +0 -14
- package/.claude/commands/gaia-agent-brainstorming.md +0 -14
- package/.claude/commands/gaia-agent-data-engineer.md +0 -14
- package/.claude/commands/gaia-agent-design-thinking.md +0 -14
- package/.claude/commands/gaia-agent-dev-angular.md +0 -14
- package/.claude/commands/gaia-agent-dev-flutter.md +0 -14
- package/.claude/commands/gaia-agent-dev-go.md +0 -14
- package/.claude/commands/gaia-agent-dev-java.md +0 -14
- package/.claude/commands/gaia-agent-dev-mobile.md +0 -14
- package/.claude/commands/gaia-agent-dev-python.md +0 -14
- package/.claude/commands/gaia-agent-dev-typescript.md +0 -14
- package/.claude/commands/gaia-agent-devops.md +0 -14
- package/.claude/commands/gaia-agent-innovation.md +0 -14
- package/.claude/commands/gaia-agent-performance.md +0 -14
- package/.claude/commands/gaia-agent-pm.md +0 -14
- package/.claude/commands/gaia-agent-presentation.md +0 -14
- package/.claude/commands/gaia-agent-problem-solver.md +0 -14
- package/.claude/commands/gaia-agent-qa.md +0 -14
- package/.claude/commands/gaia-agent-security.md +0 -14
- package/.claude/commands/gaia-agent-sm.md +0 -14
- package/.claude/commands/gaia-agent-storyteller.md +0 -14
- package/.claude/commands/gaia-agent-tech-writer.md +0 -14
- package/.claude/commands/gaia-agent-test-architect.md +0 -14
- package/.claude/commands/gaia-agent-ux-designer.md +0 -14
- package/.claude/commands/gaia-agent-validator.md +0 -14
- package/.claude/commands/gaia-atdd.md +0 -17
- package/.claude/commands/gaia-brainstorm.md +0 -17
- package/.claude/commands/gaia-brainstorming.md +0 -17
- package/.claude/commands/gaia-brownfield.md +0 -17
- package/.claude/commands/gaia-build-configs.md +0 -22
- package/.claude/commands/gaia-change-request.md +0 -11
- package/.claude/commands/gaia-changelog.md +0 -16
- package/.claude/commands/gaia-check-dod.md +0 -17
- package/.claude/commands/gaia-check-review-gate.md +0 -17
- package/.claude/commands/gaia-ci-setup.md +0 -17
- package/.claude/commands/gaia-code-review.md +0 -17
- package/.claude/commands/gaia-correct-course.md +0 -17
- package/.claude/commands/gaia-create-arch.md +0 -17
- package/.claude/commands/gaia-create-epics.md +0 -17
- package/.claude/commands/gaia-create-prd.md +0 -17
- package/.claude/commands/gaia-create-story.md +0 -23
- package/.claude/commands/gaia-create-ux.md +0 -17
- package/.claude/commands/gaia-creative-sprint.md +0 -17
- package/.claude/commands/gaia-deploy-checklist.md +0 -17
- package/.claude/commands/gaia-design-thinking.md +0 -17
- package/.claude/commands/gaia-dev-story.md +0 -23
- package/.claude/commands/gaia-document-project.md +0 -17
- package/.claude/commands/gaia-domain-research.md +0 -17
- package/.claude/commands/gaia-edge-cases.md +0 -15
- package/.claude/commands/gaia-edit-arch.md +0 -17
- package/.claude/commands/gaia-edit-prd.md +0 -17
- package/.claude/commands/gaia-edit-test-plan.md +0 -17
- package/.claude/commands/gaia-editorial-prose.md +0 -15
- package/.claude/commands/gaia-editorial-structure.md +0 -15
- package/.claude/commands/gaia-epic-status.md +0 -17
- package/.claude/commands/gaia-fix-story.md +0 -17
- package/.claude/commands/gaia-help.md +0 -15
- package/.claude/commands/gaia-index-docs.md +0 -15
- package/.claude/commands/gaia-infra-design.md +0 -17
- package/.claude/commands/gaia-innovation.md +0 -17
- package/.claude/commands/gaia-market-research.md +0 -17
- package/.claude/commands/gaia-memory-hygiene.md +0 -17
- package/.claude/commands/gaia-merge-docs.md +0 -16
- package/.claude/commands/gaia-mobile-testing.md +0 -17
- package/.claude/commands/gaia-nfr.md +0 -17
- package/.claude/commands/gaia-party.md +0 -17
- package/.claude/commands/gaia-perf-testing.md +0 -17
- package/.claude/commands/gaia-performance-review.md +0 -17
- package/.claude/commands/gaia-pitch-deck.md +0 -17
- package/.claude/commands/gaia-post-deploy.md +0 -17
- package/.claude/commands/gaia-problem-solving.md +0 -17
- package/.claude/commands/gaia-product-brief.md +0 -17
- package/.claude/commands/gaia-project-context.md +0 -17
- package/.claude/commands/gaia-qa-tests.md +0 -17
- package/.claude/commands/gaia-quick-dev.md +0 -17
- package/.claude/commands/gaia-quick-spec.md +0 -17
- package/.claude/commands/gaia-readiness-check.md +0 -17
- package/.claude/commands/gaia-refresh-ground-truth.md +0 -17
- package/.claude/commands/gaia-release-plan.md +0 -17
- package/.claude/commands/gaia-resume.md +0 -25
- package/.claude/commands/gaia-retro.md +0 -20
- package/.claude/commands/gaia-review-a11y.md +0 -16
- package/.claude/commands/gaia-review-api.md +0 -16
- package/.claude/commands/gaia-review-deps.md +0 -16
- package/.claude/commands/gaia-review-perf.md +0 -16
- package/.claude/commands/gaia-review-security.md +0 -16
- package/.claude/commands/gaia-rollback-plan.md +0 -17
- package/.claude/commands/gaia-run-all-reviews.md +0 -17
- package/.claude/commands/gaia-security-review.md +0 -17
- package/.claude/commands/gaia-shard-doc.md +0 -15
- package/.claude/commands/gaia-slide-deck.md +0 -17
- package/.claude/commands/gaia-sprint-plan.md +0 -17
- package/.claude/commands/gaia-sprint-status.md +0 -17
- package/.claude/commands/gaia-storytelling.md +0 -17
- package/.claude/commands/gaia-summarize.md +0 -16
- package/.claude/commands/gaia-teach-testing.md +0 -17
- package/.claude/commands/gaia-tech-debt-review.md +0 -20
- package/.claude/commands/gaia-tech-research.md +0 -17
- package/.claude/commands/gaia-test-automate.md +0 -17
- package/.claude/commands/gaia-test-design.md +0 -17
- package/.claude/commands/gaia-test-framework.md +0 -17
- package/.claude/commands/gaia-test-review.md +0 -17
- package/.claude/commands/gaia-threat-model.md +0 -17
- package/.claude/commands/gaia-trace.md +0 -17
- package/.claude/commands/gaia-triage-findings.md +0 -20
- package/.claude/commands/gaia-val-validate-plan.md +0 -17
- package/.claude/commands/gaia-val-validate.md +0 -17
- package/.claude/commands/gaia-validate-framework.md +0 -17
- package/.claude/commands/gaia-validate-prd.md +0 -17
- package/.claude/commands/gaia-validate-story.md +0 -22
- package/.claude/commands/gaia.md +0 -32
- package/CLAUDE.md +0 -165
- package/_gaia/_config/agent-manifest.csv +0 -29
- package/_gaia/_config/agents/CUSTOMIZATION-README.md +0 -117
- package/_gaia/_config/files-manifest.csv +0 -30
- package/_gaia/_config/gaia-help.csv +0 -82
- package/_gaia/_config/global.yaml +0 -45
- package/_gaia/_config/lifecycle-sequence.yaml +0 -593
- package/_gaia/_config/manifest.yaml +0 -24
- package/_gaia/_config/skill-manifest.csv +0 -12
- package/_gaia/_config/task-manifest.csv +0 -17
- package/_gaia/_config/workflow-manifest.csv +0 -73
- package/_gaia/_memory/tier2-results/.gitkeep +0 -0
- package/_gaia/_memory/tier2-results/checkpoint-resume-2026-03-24.yaml +0 -6
- package/_gaia/_memory/tier2-results/engine-scenarios-2026-03-22.yaml +0 -14
- package/_gaia/core/.resolved/.gitkeep +0 -0
- package/_gaia/core/agents/orchestrator.md +0 -303
- package/_gaia/core/config.yaml +0 -8
- package/_gaia/core/engine/error-recovery.xml +0 -28
- package/_gaia/core/engine/protocols/discover-inputs.xml +0 -31
- package/_gaia/core/engine/protocols/handoff.xml +0 -21
- package/_gaia/core/engine/protocols/preflight-check.xml +0 -31
- package/_gaia/core/engine/task-runner.xml +0 -63
- package/_gaia/core/engine/workflow.xml +0 -225
- package/_gaia/core/module-help.csv +0 -21
- package/_gaia/core/protocols/agent-specification-protocol.md +0 -103
- package/_gaia/core/protocols/review-gate-check.xml +0 -29
- package/_gaia/core/protocols/sprint-status-write-safety.xml +0 -35
- package/_gaia/core/protocols/status-sync.xml +0 -49
- package/_gaia/core/tasks/editorial-review-prose.xml +0 -42
- package/_gaia/core/tasks/editorial-review-structure.xml +0 -43
- package/_gaia/core/tasks/generate-changelog.xml +0 -35
- package/_gaia/core/tasks/help.md +0 -45
- package/_gaia/core/tasks/index-docs.xml +0 -46
- package/_gaia/core/tasks/merge-docs.xml +0 -34
- package/_gaia/core/tasks/review-accessibility.xml +0 -47
- package/_gaia/core/tasks/review-adversarial.xml +0 -55
- package/_gaia/core/tasks/review-api-design.xml +0 -38
- package/_gaia/core/tasks/review-dependency-audit.xml +0 -38
- package/_gaia/core/tasks/review-edge-case-hunter.xml +0 -52
- package/_gaia/core/tasks/review-performance.xml +0 -49
- package/_gaia/core/tasks/review-security.xml +0 -37
- package/_gaia/core/tasks/shard-doc.xml +0 -49
- package/_gaia/core/tasks/summarize-doc.xml +0 -33
- package/_gaia/core/tasks/validate-framework.xml +0 -66
- package/_gaia/core/workflows/brainstorming/steps/step-01-session-setup.md +0 -7
- package/_gaia/core/workflows/brainstorming/steps/step-02-technique-selection.md +0 -20
- package/_gaia/core/workflows/brainstorming/steps/step-03-technique-execution.md +0 -11
- package/_gaia/core/workflows/brainstorming/steps/step-04-idea-organization.md +0 -14
- package/_gaia/core/workflows/brainstorming/template.md +0 -38
- package/_gaia/core/workflows/brainstorming/workflow.yaml +0 -26
- package/_gaia/core/workflows/party-mode/steps/step-01-agent-loading.md +0 -11
- package/_gaia/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +0 -16
- package/_gaia/core/workflows/party-mode/steps/step-03-graceful-exit.md +0 -10
- package/_gaia/core/workflows/party-mode/workflow.yaml +0 -23
- package/_gaia/creative/.resolved/.gitkeep +0 -0
- package/_gaia/creative/agents/brainstorming-coach.md +0 -93
- package/_gaia/creative/agents/design-thinking-coach.md +0 -91
- package/_gaia/creative/agents/innovation-strategist.md +0 -89
- package/_gaia/creative/agents/presentation-designer.md +0 -99
- package/_gaia/creative/agents/problem-solver.md +0 -90
- package/_gaia/creative/agents/storyteller.md +0 -90
- package/_gaia/creative/config.yaml +0 -8
- package/_gaia/creative/data/design-methods.csv +0 -28
- package/_gaia/creative/data/innovation-frameworks.csv +0 -15
- package/_gaia/creative/data/solving-methods.csv +0 -14
- package/_gaia/creative/data/story-types.csv +0 -12
- package/_gaia/creative/module-help.csv +0 -8
- package/_gaia/creative/teams/creative-squad.yaml +0 -10
- package/_gaia/creative/workflows/creative-sprint/checklist.md +0 -10
- package/_gaia/creative/workflows/creative-sprint/instructions.xml +0 -40
- package/_gaia/creative/workflows/creative-sprint/workflow.yaml +0 -11
- package/_gaia/creative/workflows/design-thinking/checklist.md +0 -25
- package/_gaia/creative/workflows/design-thinking/instructions.xml +0 -38
- package/_gaia/creative/workflows/design-thinking/workflow.yaml +0 -13
- package/_gaia/creative/workflows/innovation-strategy/checklist.md +0 -26
- package/_gaia/creative/workflows/innovation-strategy/instructions.xml +0 -34
- package/_gaia/creative/workflows/innovation-strategy/workflow.yaml +0 -13
- package/_gaia/creative/workflows/pitch-deck/checklist.md +0 -22
- package/_gaia/creative/workflows/pitch-deck/instructions.xml +0 -49
- package/_gaia/creative/workflows/pitch-deck/workflow.yaml +0 -15
- package/_gaia/creative/workflows/problem-solving/checklist.md +0 -26
- package/_gaia/creative/workflows/problem-solving/instructions.xml +0 -39
- package/_gaia/creative/workflows/problem-solving/workflow.yaml +0 -13
- package/_gaia/creative/workflows/slide-deck/checklist.md +0 -21
- package/_gaia/creative/workflows/slide-deck/instructions.xml +0 -39
- package/_gaia/creative/workflows/slide-deck/workflow.yaml +0 -15
- package/_gaia/creative/workflows/storytelling/checklist.md +0 -26
- package/_gaia/creative/workflows/storytelling/instructions.xml +0 -38
- package/_gaia/creative/workflows/storytelling/workflow.yaml +0 -13
- package/_gaia/dev/agents/_base-dev.md +0 -180
- package/_gaia/dev/agents/angular-dev.md +0 -70
- package/_gaia/dev/agents/flutter-dev.md +0 -70
- package/_gaia/dev/agents/go-dev.md +0 -72
- package/_gaia/dev/agents/java-dev.md +0 -70
- package/_gaia/dev/agents/mobile-dev.md +0 -70
- package/_gaia/dev/agents/python-dev.md +0 -70
- package/_gaia/dev/agents/typescript-dev.md +0 -70
- package/_gaia/dev/config.yaml +0 -11
- package/_gaia/dev/knowledge/_index.csv +0 -25
- package/_gaia/dev/knowledge/angular/angular-conventions.md +0 -119
- package/_gaia/dev/knowledge/angular/angular-patterns.md +0 -126
- package/_gaia/dev/knowledge/angular/ngrx-state.md +0 -124
- package/_gaia/dev/knowledge/angular/rxjs-patterns.md +0 -119
- package/_gaia/dev/knowledge/flutter/dart-conventions.md +0 -143
- package/_gaia/dev/knowledge/flutter/platform-channels.md +0 -144
- package/_gaia/dev/knowledge/flutter/state-management.md +0 -144
- package/_gaia/dev/knowledge/flutter/widget-patterns.md +0 -134
- package/_gaia/dev/knowledge/go/gin-fiber-patterns.md +0 -40
- package/_gaia/dev/knowledge/go/go-conventions.md +0 -54
- package/_gaia/dev/knowledge/go/go-stdlib-patterns.md +0 -39
- package/_gaia/dev/knowledge/go/go-testing-patterns.md +0 -39
- package/_gaia/dev/knowledge/java/jpa-patterns.md +0 -136
- package/_gaia/dev/knowledge/java/maven-gradle.md +0 -189
- package/_gaia/dev/knowledge/java/microservices.md +0 -159
- package/_gaia/dev/knowledge/java/spring-boot-patterns.md +0 -160
- package/_gaia/dev/knowledge/mobile/kotlin-patterns.md +0 -193
- package/_gaia/dev/knowledge/mobile/mobile-testing.md +0 -186
- package/_gaia/dev/knowledge/mobile/react-native-patterns.md +0 -162
- package/_gaia/dev/knowledge/mobile/swift-patterns.md +0 -190
- package/_gaia/dev/knowledge/python/data-pipelines.md +0 -169
- package/_gaia/dev/knowledge/python/django-patterns.md +0 -145
- package/_gaia/dev/knowledge/python/fastapi-patterns.md +0 -164
- package/_gaia/dev/knowledge/python/python-conventions.md +0 -170
- package/_gaia/dev/knowledge/typescript/express-patterns.md +0 -188
- package/_gaia/dev/knowledge/typescript/nextjs-patterns.md +0 -166
- package/_gaia/dev/knowledge/typescript/react-patterns.md +0 -176
- package/_gaia/dev/knowledge/typescript/ts-conventions.md +0 -133
- package/_gaia/dev/module-help.csv +0 -10
- package/_gaia/dev/skills/_skill-index.yaml +0 -55
- package/_gaia/dev/skills/api-design.md +0 -229
- package/_gaia/dev/skills/code-review-standards.md +0 -226
- package/_gaia/dev/skills/database-design.md +0 -172
- package/_gaia/dev/skills/docker-workflow.md +0 -222
- package/_gaia/dev/skills/documentation-standards.md +0 -256
- package/_gaia/dev/skills/git-workflow.md +0 -157
- package/_gaia/dev/skills/security-basics.md +0 -230
- package/_gaia/dev/skills/testing-patterns.md +0 -232
- package/_gaia/lifecycle/.resolved/.gitkeep +0 -0
- package/_gaia/lifecycle/agents/analyst.md +0 -104
- package/_gaia/lifecycle/agents/architect.md +0 -109
- package/_gaia/lifecycle/agents/data-engineer.md +0 -99
- package/_gaia/lifecycle/agents/devops.md +0 -110
- package/_gaia/lifecycle/agents/performance.md +0 -92
- package/_gaia/lifecycle/agents/pm.md +0 -112
- package/_gaia/lifecycle/agents/qa.md +0 -89
- package/_gaia/lifecycle/agents/security.md +0 -108
- package/_gaia/lifecycle/agents/sm.md +0 -119
- package/_gaia/lifecycle/agents/tech-writer.md +0 -94
- package/_gaia/lifecycle/agents/ux-designer.md +0 -94
- package/_gaia/lifecycle/agents/validator.md +0 -189
- package/_gaia/lifecycle/config.yaml +0 -14
- package/_gaia/lifecycle/module-help.csv +0 -39
- package/_gaia/lifecycle/skills/ground-truth-management.md +0 -252
- package/_gaia/lifecycle/skills/memory-management.md +0 -322
- package/_gaia/lifecycle/skills/validation-patterns.md +0 -230
- package/_gaia/lifecycle/teams/team-data-intensive.yaml +0 -12
- package/_gaia/lifecycle/teams/team-enterprise.yaml +0 -16
- package/_gaia/lifecycle/teams/team-full.yaml +0 -13
- package/_gaia/lifecycle/teams/team-implementation.yaml +0 -8
- package/_gaia/lifecycle/teams/team-planning.yaml +0 -9
- package/_gaia/lifecycle/teams/team-quick-ship.yaml +0 -6
- package/_gaia/lifecycle/teams/team-security-focused.yaml +0 -13
- package/_gaia/lifecycle/templates/api-documentation-template.md +0 -112
- package/_gaia/lifecycle/templates/architecture-template.md +0 -65
- package/_gaia/lifecycle/templates/brownfield-architecture-template.md +0 -198
- package/_gaia/lifecycle/templates/brownfield-assessment-template.md +0 -78
- package/_gaia/lifecycle/templates/brownfield-onboarding-template.md +0 -160
- package/_gaia/lifecycle/templates/dependency-map-template.md +0 -73
- package/_gaia/lifecycle/templates/deployment-template.md +0 -52
- package/_gaia/lifecycle/templates/epic-status-template.md +0 -64
- package/_gaia/lifecycle/templates/event-catalog-template.md +0 -78
- package/_gaia/lifecycle/templates/nfr-assessment-template.md +0 -96
- package/_gaia/lifecycle/templates/prd-template.md +0 -83
- package/_gaia/lifecycle/templates/product-brief-template.md +0 -48
- package/_gaia/lifecycle/templates/review-template.md +0 -47
- package/_gaia/lifecycle/templates/sprint-plan-template.md +0 -45
- package/_gaia/lifecycle/templates/story-template.md +0 -118
- package/_gaia/lifecycle/templates/tech-debt-dashboard-template.md +0 -71
- package/_gaia/lifecycle/templates/test-plan-template.md +0 -56
- package/_gaia/lifecycle/templates/ux-design-assessment-template.md +0 -122
- package/_gaia/lifecycle/workflows/1-analysis/advanced-elicitation/instructions.xml +0 -44
- package/_gaia/lifecycle/workflows/1-analysis/advanced-elicitation/methods.csv +0 -9
- package/_gaia/lifecycle/workflows/1-analysis/advanced-elicitation/workflow.yaml +0 -33
- package/_gaia/lifecycle/workflows/1-analysis/brainstorm-project/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/1-analysis/brainstorm-project/instructions.xml +0 -39
- package/_gaia/lifecycle/workflows/1-analysis/brainstorm-project/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/1-analysis/create-product-brief/checklist.md +0 -27
- package/_gaia/lifecycle/workflows/1-analysis/create-product-brief/instructions.xml +0 -57
- package/_gaia/lifecycle/workflows/1-analysis/create-product-brief/workflow.yaml +0 -38
- package/_gaia/lifecycle/workflows/1-analysis/domain-research/checklist.md +0 -22
- package/_gaia/lifecycle/workflows/1-analysis/domain-research/instructions.xml +0 -34
- package/_gaia/lifecycle/workflows/1-analysis/domain-research/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/1-analysis/market-research/checklist.md +0 -28
- package/_gaia/lifecycle/workflows/1-analysis/market-research/instructions.xml +0 -42
- package/_gaia/lifecycle/workflows/1-analysis/market-research/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/1-analysis/technical-research/checklist.md +0 -22
- package/_gaia/lifecycle/workflows/1-analysis/technical-research/instructions.xml +0 -34
- package/_gaia/lifecycle/workflows/1-analysis/technical-research/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/2-planning/create-prd/checklist.md +0 -36
- package/_gaia/lifecycle/workflows/2-planning/create-prd/instructions.xml +0 -80
- package/_gaia/lifecycle/workflows/2-planning/create-prd/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/checklist.md +0 -26
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/instructions.xml +0 -49
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/2-planning/edit-prd/checklist.md +0 -17
- package/_gaia/lifecycle/workflows/2-planning/edit-prd/instructions.xml +0 -50
- package/_gaia/lifecycle/workflows/2-planning/edit-prd/workflow.yaml +0 -22
- package/_gaia/lifecycle/workflows/2-planning/validate-prd/checklist.md +0 -12
- package/_gaia/lifecycle/workflows/2-planning/validate-prd/instructions.xml +0 -52
- package/_gaia/lifecycle/workflows/2-planning/validate-prd/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/checklist.md +0 -32
- package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/instructions.xml +0 -100
- package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/workflow.yaml +0 -41
- package/_gaia/lifecycle/workflows/3-solutioning/create-epics-stories/checklist.md +0 -30
- package/_gaia/lifecycle/workflows/3-solutioning/create-epics-stories/instructions.xml +0 -86
- package/_gaia/lifecycle/workflows/3-solutioning/create-epics-stories/workflow.yaml +0 -34
- package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/instructions.xml +0 -91
- package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/workflow.yaml +0 -32
- package/_gaia/lifecycle/workflows/3-solutioning/implementation-readiness/checklist.md +0 -66
- package/_gaia/lifecycle/workflows/3-solutioning/implementation-readiness/instructions.xml +0 -160
- package/_gaia/lifecycle/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -48
- package/_gaia/lifecycle/workflows/3-solutioning/infrastructure-design/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/3-solutioning/infrastructure-design/instructions.xml +0 -44
- package/_gaia/lifecycle/workflows/3-solutioning/infrastructure-design/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/3-solutioning/security-threat-model/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/3-solutioning/security-threat-model/instructions.xml +0 -55
- package/_gaia/lifecycle/workflows/3-solutioning/security-threat-model/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/4-implementation/action-items/instructions.xml +0 -131
- package/_gaia/lifecycle/workflows/4-implementation/action-items/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/checklist.md +0 -27
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/instructions.xml +0 -100
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/workflow.yaml +0 -35
- package/_gaia/lifecycle/workflows/4-implementation/change-request/checklist.md +0 -25
- package/_gaia/lifecycle/workflows/4-implementation/change-request/instructions.xml +0 -123
- package/_gaia/lifecycle/workflows/4-implementation/change-request/workflow.yaml +0 -38
- package/_gaia/lifecycle/workflows/4-implementation/check-dod/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/check-dod/instructions.xml +0 -54
- package/_gaia/lifecycle/workflows/4-implementation/check-dod/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/check-review-gate/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/check-review-gate/instructions.xml +0 -53
- package/_gaia/lifecycle/workflows/4-implementation/check-review-gate/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/code-review/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/code-review/instructions.xml +0 -50
- package/_gaia/lifecycle/workflows/4-implementation/code-review/workflow.yaml +0 -24
- package/_gaia/lifecycle/workflows/4-implementation/correct-course/checklist.md +0 -21
- package/_gaia/lifecycle/workflows/4-implementation/correct-course/instructions.xml +0 -63
- package/_gaia/lifecycle/workflows/4-implementation/correct-course/workflow.yaml +0 -25
- package/_gaia/lifecycle/workflows/4-implementation/create-story/checklist.md +0 -38
- package/_gaia/lifecycle/workflows/4-implementation/create-story/instructions.xml +0 -194
- package/_gaia/lifecycle/workflows/4-implementation/create-story/workflow.yaml +0 -26
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/checklist.md +0 -26
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/instructions.xml +0 -268
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/workflow.yaml +0 -51
- package/_gaia/lifecycle/workflows/4-implementation/epic-status/checklist.md +0 -25
- package/_gaia/lifecycle/workflows/4-implementation/epic-status/instructions.xml +0 -62
- package/_gaia/lifecycle/workflows/4-implementation/epic-status/workflow.yaml +0 -24
- package/_gaia/lifecycle/workflows/4-implementation/fix-story/checklist.md +0 -12
- package/_gaia/lifecycle/workflows/4-implementation/fix-story/instructions.xml +0 -67
- package/_gaia/lifecycle/workflows/4-implementation/fix-story/workflow.yaml +0 -17
- package/_gaia/lifecycle/workflows/4-implementation/qa-generate-tests/checklist.md +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/qa-generate-tests/instructions.xml +0 -52
- package/_gaia/lifecycle/workflows/4-implementation/qa-generate-tests/workflow.yaml +0 -20
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/checklist.md +0 -15
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/instructions.xml +0 -164
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/workflow.yaml +0 -30
- package/_gaia/lifecycle/workflows/4-implementation/run-all-reviews/checklist.md +0 -14
- package/_gaia/lifecycle/workflows/4-implementation/run-all-reviews/instructions.xml +0 -78
- package/_gaia/lifecycle/workflows/4-implementation/run-all-reviews/workflow.yaml +0 -16
- package/_gaia/lifecycle/workflows/4-implementation/security-review/checklist.md +0 -29
- package/_gaia/lifecycle/workflows/4-implementation/security-review/instructions.xml +0 -80
- package/_gaia/lifecycle/workflows/4-implementation/security-review/workflow.yaml +0 -27
- package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/checklist.md +0 -29
- package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/instructions.xml +0 -140
- package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/workflow.yaml +0 -33
- package/_gaia/lifecycle/workflows/4-implementation/sprint-status/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/sprint-status/instructions.xml +0 -36
- package/_gaia/lifecycle/workflows/4-implementation/sprint-status/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/tech-debt-review/checklist.md +0 -30
- package/_gaia/lifecycle/workflows/4-implementation/tech-debt-review/instructions.xml +0 -147
- package/_gaia/lifecycle/workflows/4-implementation/tech-debt-review/workflow.yaml +0 -24
- package/_gaia/lifecycle/workflows/4-implementation/triage-findings/checklist.md +0 -17
- package/_gaia/lifecycle/workflows/4-implementation/triage-findings/instructions.xml +0 -124
- package/_gaia/lifecycle/workflows/4-implementation/triage-findings/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/checklist.md +0 -48
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/instructions.xml +0 -125
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/workflow.yaml +0 -31
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/checklist.md +0 -54
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/instructions.xml +0 -147
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/test-structure.sh +0 -116
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/workflow.yaml +0 -29
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-plan/checklist.md +0 -34
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-plan/instructions.xml +0 -162
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-plan/workflow.yaml +0 -39
- package/_gaia/lifecycle/workflows/4-implementation/validate-story/checklist.md +0 -23
- package/_gaia/lifecycle/workflows/4-implementation/validate-story/instructions.xml +0 -146
- package/_gaia/lifecycle/workflows/4-implementation/validate-story/workflow.yaml +0 -25
- package/_gaia/lifecycle/workflows/5-deployment/deployment-checklist/checklist.md +0 -29
- package/_gaia/lifecycle/workflows/5-deployment/deployment-checklist/instructions.xml +0 -59
- package/_gaia/lifecycle/workflows/5-deployment/deployment-checklist/workflow.yaml +0 -39
- package/_gaia/lifecycle/workflows/5-deployment/post-deploy-verify/checklist.md +0 -19
- package/_gaia/lifecycle/workflows/5-deployment/post-deploy-verify/instructions.xml +0 -33
- package/_gaia/lifecycle/workflows/5-deployment/post-deploy-verify/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/5-deployment/release-plan/checklist.md +0 -20
- package/_gaia/lifecycle/workflows/5-deployment/release-plan/instructions.xml +0 -33
- package/_gaia/lifecycle/workflows/5-deployment/release-plan/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/5-deployment/rollback-plan/checklist.md +0 -20
- package/_gaia/lifecycle/workflows/5-deployment/rollback-plan/instructions.xml +0 -33
- package/_gaia/lifecycle/workflows/5-deployment/rollback-plan/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/checklist.md +0 -52
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/instructions.xml +0 -122
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/test-step7.sh +0 -149
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/workflow.yaml +0 -33
- package/_gaia/lifecycle/workflows/anytime/document-project/checklist.md +0 -11
- package/_gaia/lifecycle/workflows/anytime/document-project/instructions.xml +0 -26
- package/_gaia/lifecycle/workflows/anytime/document-project/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/generate-project-context/checklist.md +0 -11
- package/_gaia/lifecycle/workflows/anytime/generate-project-context/instructions.xml +0 -22
- package/_gaia/lifecycle/workflows/anytime/generate-project-context/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/memory-hygiene/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/anytime/memory-hygiene/instructions.xml +0 -108
- package/_gaia/lifecycle/workflows/anytime/memory-hygiene/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/performance-review/checklist.md +0 -25
- package/_gaia/lifecycle/workflows/anytime/performance-review/instructions.xml +0 -62
- package/_gaia/lifecycle/workflows/anytime/performance-review/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/cross-phase/add-feature/checklist.md +0 -30
- package/_gaia/lifecycle/workflows/cross-phase/add-feature/instructions.xml +0 -85
- package/_gaia/lifecycle/workflows/cross-phase/add-feature/workflow.yaml +0 -37
- package/_gaia/lifecycle/workflows/quick-flow/quick-dev/checklist.md +0 -11
- package/_gaia/lifecycle/workflows/quick-flow/quick-dev/instructions.xml +0 -26
- package/_gaia/lifecycle/workflows/quick-flow/quick-dev/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/quick-flow/quick-spec/checklist.md +0 -13
- package/_gaia/lifecycle/workflows/quick-flow/quick-spec/instructions.xml +0 -27
- package/_gaia/lifecycle/workflows/quick-flow/quick-spec/workflow.yaml +0 -15
- package/_gaia/testing/.resolved/.gitkeep +0 -0
- package/_gaia/testing/agents/test-architect.md +0 -131
- package/_gaia/testing/config.yaml +0 -8
- package/_gaia/testing/knowledge/_index.csv +0 -22
- package/_gaia/testing/knowledge/accessibility/axe-core-patterns.md +0 -177
- package/_gaia/testing/knowledge/accessibility/wcag-checks.md +0 -191
- package/_gaia/testing/knowledge/core/deterministic-testing.md +0 -167
- package/_gaia/testing/knowledge/core/fixture-architecture.md +0 -131
- package/_gaia/testing/knowledge/core/test-isolation.md +0 -142
- package/_gaia/testing/knowledge/core/test-pyramid.md +0 -129
- package/_gaia/testing/knowledge/extended/api-testing-patterns.md +0 -196
- package/_gaia/testing/knowledge/extended/data-factories.md +0 -158
- package/_gaia/testing/knowledge/extended/risk-governance.md +0 -119
- package/_gaia/testing/knowledge/extended/selector-resilience.md +0 -109
- package/_gaia/testing/knowledge/mobile-testing/appium-patterns.md +0 -164
- package/_gaia/testing/knowledge/mobile-testing/react-native-testing.md +0 -193
- package/_gaia/testing/knowledge/mobile-testing/responsive-testing.md +0 -177
- package/_gaia/testing/knowledge/performance/k6-patterns.md +0 -200
- package/_gaia/testing/knowledge/performance/lighthouse-ci.md +0 -158
- package/_gaia/testing/knowledge/specialized/contract-testing.md +0 -173
- package/_gaia/testing/knowledge/specialized/test-healing.md +0 -129
- package/_gaia/testing/knowledge/specialized/visual-testing.md +0 -129
- package/_gaia/testing/knowledge/unit-testing/jest-vitest-patterns.md +0 -193
- package/_gaia/testing/knowledge/unit-testing/junit5-patterns.md +0 -200
- package/_gaia/testing/knowledge/unit-testing/pytest-patterns.md +0 -185
- package/_gaia/testing/module-help.csv +0 -13
- package/_gaia/testing/workflows/accessibility-testing/checklist.md +0 -12
- package/_gaia/testing/workflows/accessibility-testing/instructions.xml +0 -41
- package/_gaia/testing/workflows/accessibility-testing/workflow.yaml +0 -13
- package/_gaia/testing/workflows/atdd/checklist.md +0 -6
- package/_gaia/testing/workflows/atdd/instructions.xml +0 -36
- package/_gaia/testing/workflows/atdd/workflow.yaml +0 -22
- package/_gaia/testing/workflows/ci-setup/checklist.md +0 -9
- package/_gaia/testing/workflows/ci-setup/instructions.xml +0 -43
- package/_gaia/testing/workflows/ci-setup/workflow.yaml +0 -11
- package/_gaia/testing/workflows/edit-test-plan/checklist.md +0 -20
- package/_gaia/testing/workflows/edit-test-plan/instructions.xml +0 -65
- package/_gaia/testing/workflows/edit-test-plan/workflow.yaml +0 -35
- package/_gaia/testing/workflows/mobile-testing/checklist.md +0 -13
- package/_gaia/testing/workflows/mobile-testing/instructions.xml +0 -41
- package/_gaia/testing/workflows/mobile-testing/workflow.yaml +0 -11
- package/_gaia/testing/workflows/nfr-assessment/checklist.md +0 -7
- package/_gaia/testing/workflows/nfr-assessment/instructions.xml +0 -26
- package/_gaia/testing/workflows/nfr-assessment/workflow.yaml +0 -11
- package/_gaia/testing/workflows/performance-testing/checklist.md +0 -11
- package/_gaia/testing/workflows/performance-testing/instructions.xml +0 -41
- package/_gaia/testing/workflows/performance-testing/workflow.yaml +0 -11
- package/_gaia/testing/workflows/teach-me-testing/checklist.md +0 -6
- package/_gaia/testing/workflows/teach-me-testing/instructions.xml +0 -28
- package/_gaia/testing/workflows/teach-me-testing/workflow.yaml +0 -12
- package/_gaia/testing/workflows/test-automation/checklist.md +0 -6
- package/_gaia/testing/workflows/test-automation/instructions.xml +0 -49
- package/_gaia/testing/workflows/test-automation/workflow.yaml +0 -11
- package/_gaia/testing/workflows/test-design/checklist.md +0 -9
- package/_gaia/testing/workflows/test-design/instructions.xml +0 -47
- package/_gaia/testing/workflows/test-design/workflow.yaml +0 -11
- package/_gaia/testing/workflows/test-framework/checklist.md +0 -8
- package/_gaia/testing/workflows/test-framework/instructions.xml +0 -25
- package/_gaia/testing/workflows/test-framework/workflow.yaml +0 -11
- package/_gaia/testing/workflows/test-review/checklist.md +0 -9
- package/_gaia/testing/workflows/test-review/instructions.xml +0 -51
- package/_gaia/testing/workflows/test-review/workflow.yaml +0 -11
- package/_gaia/testing/workflows/traceability/checklist.md +0 -6
- package/_gaia/testing/workflows/traceability/instructions.xml +0 -49
- package/_gaia/testing/workflows/traceability/workflow.yaml +0 -21
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: visual-testing
|
|
3
|
-
tier: specialized
|
|
4
|
-
version: '1.0'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Visual Testing
|
|
8
|
-
|
|
9
|
-
## Principle
|
|
10
|
-
|
|
11
|
-
Visual regression testing catches unintended UI changes by comparing screenshots against
|
|
12
|
-
approved baselines. Test at the component level for speed and precision, at the page
|
|
13
|
-
level for critical journeys. Configure thresholds carefully -- too strict causes noise,
|
|
14
|
-
too loose misses real regressions.
|
|
15
|
-
|
|
16
|
-
## Rationale
|
|
17
|
-
|
|
18
|
-
CSS changes, font loading failures, layout shifts, and design system updates can break
|
|
19
|
-
visual appearance without triggering any functional test failure. Visual tests fill this
|
|
20
|
-
gap by asserting on what users actually see, not just what the DOM contains. They are
|
|
21
|
-
the only reliable way to catch visual regressions across browsers and viewports.
|
|
22
|
-
|
|
23
|
-
## Pattern Examples
|
|
24
|
-
|
|
25
|
-
### Component-Level Visual Tests
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
// tests/visual/button.visual.spec.ts
|
|
29
|
-
import { test, expect } from '@playwright/test';
|
|
30
|
-
|
|
31
|
-
test.describe('Button visual regression', () => {
|
|
32
|
-
for (const variant of ['primary', 'secondary', 'danger']) {
|
|
33
|
-
test(`${variant} button matches baseline`, async ({ page }) => {
|
|
34
|
-
await page.goto(`/storybook/button--${variant}`);
|
|
35
|
-
await expect(page.getByTestId('button')).toHaveScreenshot(
|
|
36
|
-
`button-${variant}.png`,
|
|
37
|
-
{ maxDiffPixelRatio: 0.01 }
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### Page-Level Visual Tests
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
test('dashboard layout matches baseline', async ({ page }) => {
|
|
48
|
-
// Mock dynamic content for determinism
|
|
49
|
-
await page.route('**/api/dashboard', (route) => {
|
|
50
|
-
route.fulfill({
|
|
51
|
-
body: JSON.stringify({
|
|
52
|
-
user: { name: 'Test User' },
|
|
53
|
-
stats: { orders: 42, revenue: 1234.56 },
|
|
54
|
-
}),
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
await page.goto('/dashboard');
|
|
59
|
-
await page.waitForLoadState('networkidle');
|
|
60
|
-
|
|
61
|
-
await expect(page).toHaveScreenshot('dashboard-full.png', {
|
|
62
|
-
fullPage: true,
|
|
63
|
-
maxDiffPixelRatio: 0.02,
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Handling Dynamic Content
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
test('profile page visual (with masked dynamic areas)', async ({ page }) => {
|
|
72
|
-
await page.goto('/profile');
|
|
73
|
-
|
|
74
|
-
// Mask elements with dynamic content (timestamps, avatars)
|
|
75
|
-
await expect(page).toHaveScreenshot('profile.png', {
|
|
76
|
-
mask: [
|
|
77
|
-
page.getByTestId('last-login-timestamp'),
|
|
78
|
-
page.getByTestId('user-avatar'),
|
|
79
|
-
page.getByTestId('notification-count'),
|
|
80
|
-
],
|
|
81
|
-
maxDiffPixelRatio: 0.01,
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Threshold Configuration
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
// playwright.config.ts
|
|
90
|
-
export default defineConfig({
|
|
91
|
-
expect: {
|
|
92
|
-
toHaveScreenshot: {
|
|
93
|
-
maxDiffPixelRatio: 0.01, // 1% pixel difference allowed
|
|
94
|
-
threshold: 0.2, // Per-pixel color threshold (0-1)
|
|
95
|
-
animations: 'disabled', // Disable CSS animations for stability
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
projects: [
|
|
99
|
-
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
|
100
|
-
{ name: 'mobile', use: { ...devices['iPhone 14'] } },
|
|
101
|
-
],
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Anti-Patterns
|
|
106
|
-
|
|
107
|
-
1. **Full-page screenshots with dynamic data** -- Timestamps, notification counts, and
|
|
108
|
-
random avatars cause every comparison to fail. Mask dynamic areas or mock the data.
|
|
109
|
-
|
|
110
|
-
2. **Zero threshold** -- Requiring pixel-perfect matches causes failures from font
|
|
111
|
-
rendering differences across OS versions. Use `maxDiffPixelRatio: 0.01` minimum.
|
|
112
|
-
|
|
113
|
-
3. **Only page-level tests** -- Full-page visual tests are slow and noisy. Prefer
|
|
114
|
-
component-level tests for design system elements. Reserve page-level for critical
|
|
115
|
-
layouts.
|
|
116
|
-
|
|
117
|
-
4. **No cross-browser baselines** -- Chrome and Firefox render differently. Generate
|
|
118
|
-
separate baselines per browser/viewport combination.
|
|
119
|
-
|
|
120
|
-
5. **Stale baselines** -- Baselines that are months old accumulate false positives. Update
|
|
121
|
-
baselines as part of the design change PR, not separately.
|
|
122
|
-
|
|
123
|
-
## Integration Points
|
|
124
|
-
|
|
125
|
-
- **Workflows**: `test-automation` (visual test generation), `test-review` (visual
|
|
126
|
-
regression audit)
|
|
127
|
-
- **Related fragments**: `selector-resilience` (stable selectors for screenshot targets),
|
|
128
|
-
`deterministic-testing` (mocking dynamic content for stable screenshots),
|
|
129
|
-
`test-pyramid` (visual tests are E2E level)
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: jest-vitest-patterns
|
|
3
|
-
tier: unit-testing
|
|
4
|
-
version: '1.0'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Jest & Vitest Patterns
|
|
8
|
-
|
|
9
|
-
## Principle
|
|
10
|
-
|
|
11
|
-
Fast feedback loops drive TDD adoption in JavaScript and TypeScript. Jest and Vitest
|
|
12
|
-
provide near-identical APIs with different performance profiles — Vitest leverages
|
|
13
|
-
Vite's transform pipeline for faster execution. Choose based on your bundler; the
|
|
14
|
-
testing patterns remain the same.
|
|
15
|
-
|
|
16
|
-
## Rationale
|
|
17
|
-
|
|
18
|
-
JavaScript's module system and dynamic typing make mocking both powerful and dangerous.
|
|
19
|
-
The describe/it/expect structure enables readable tests, but over-reliance on mocking
|
|
20
|
-
internals creates brittle suites. Focus on testing behavior through public APIs and
|
|
21
|
-
rendered output.
|
|
22
|
-
|
|
23
|
-
## Pattern Examples
|
|
24
|
-
|
|
25
|
-
### Basic Structure
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
// src/utils/format-currency.test.ts
|
|
29
|
-
import { formatCurrency } from './format-currency';
|
|
30
|
-
|
|
31
|
-
describe('formatCurrency', () => {
|
|
32
|
-
it('formats USD with two decimal places', () => {
|
|
33
|
-
expect(formatCurrency(1234.5, 'USD')).toBe('$1,234.50');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('handles zero', () => {
|
|
37
|
-
expect(formatCurrency(0, 'USD')).toBe('$0.00');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('handles negative amounts', () => {
|
|
41
|
-
expect(formatCurrency(-50, 'USD')).toBe('-$50.00');
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Parameterized Tests
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
describe('validateEmail', () => {
|
|
50
|
-
it.each([
|
|
51
|
-
['user@example.com', true],
|
|
52
|
-
['user@sub.example.com', true],
|
|
53
|
-
['invalid', false],
|
|
54
|
-
['@example.com', false],
|
|
55
|
-
['user@', false],
|
|
56
|
-
])('validates %s as %s', (email, expected) => {
|
|
57
|
-
expect(validateEmail(email)).toBe(expected);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Module Mocking
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
// Jest
|
|
66
|
-
jest.mock('./api-client', () => ({
|
|
67
|
-
fetchUsers: jest.fn().mockResolvedValue([{ id: 1, name: 'Alice' }]),
|
|
68
|
-
}));
|
|
69
|
-
|
|
70
|
-
// Vitest
|
|
71
|
-
vi.mock('./api-client', () => ({
|
|
72
|
-
fetchUsers: vi.fn().mockResolvedValue([{ id: 1, name: 'Alice' }]),
|
|
73
|
-
}));
|
|
74
|
-
|
|
75
|
-
// Manual mock — __mocks__/api-client.ts
|
|
76
|
-
export const fetchUsers = jest.fn().mockResolvedValue([]);
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### React Testing Library
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
import { render, screen } from '@testing-library/react';
|
|
83
|
-
import userEvent from '@testing-library/user-event';
|
|
84
|
-
import { LoginForm } from './LoginForm';
|
|
85
|
-
|
|
86
|
-
describe('LoginForm', () => {
|
|
87
|
-
it('submits credentials', async () => {
|
|
88
|
-
const onSubmit = vi.fn();
|
|
89
|
-
render(<LoginForm onSubmit={onSubmit} />);
|
|
90
|
-
|
|
91
|
-
await userEvent.type(screen.getByLabelText('Email'), 'user@test.com');
|
|
92
|
-
await userEvent.type(screen.getByLabelText('Password'), 'secret123');
|
|
93
|
-
await userEvent.click(screen.getByRole('button', { name: 'Sign In' }));
|
|
94
|
-
|
|
95
|
-
expect(onSubmit).toHaveBeenCalledWith({
|
|
96
|
-
email: 'user@test.com',
|
|
97
|
-
password: 'secret123',
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('shows validation error for empty email', async () => {
|
|
102
|
-
render(<LoginForm onSubmit={vi.fn()} />);
|
|
103
|
-
await userEvent.click(screen.getByRole('button', { name: 'Sign In' }));
|
|
104
|
-
expect(screen.getByText('Email is required')).toBeInTheDocument();
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Async Testing
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
describe('UserService', () => {
|
|
113
|
-
it('fetches user by id', async () => {
|
|
114
|
-
const user = await userService.getById(1);
|
|
115
|
-
expect(user).toEqual(expect.objectContaining({ id: 1, name: 'Alice' }));
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('throws on not found', async () => {
|
|
119
|
-
await expect(userService.getById(999)).rejects.toThrow('User not found');
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Snapshot Testing (Judicious Use)
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
// Good — stable UI structure
|
|
128
|
-
it('renders navigation menu', () => {
|
|
129
|
-
const { container } = render(<NavMenu items={menuItems} />);
|
|
130
|
-
expect(container.firstChild).toMatchSnapshot();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Better — inline snapshot for small outputs
|
|
134
|
-
it('formats address', () => {
|
|
135
|
-
expect(formatAddress(address)).toMatchInlineSnapshot(`
|
|
136
|
-
"123 Main St
|
|
137
|
-
Suite 100
|
|
138
|
-
New York, NY 10001"
|
|
139
|
-
`);
|
|
140
|
-
});
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Setup and Teardown
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
describe('DatabaseService', () => {
|
|
147
|
-
let db: TestDatabase;
|
|
148
|
-
|
|
149
|
-
beforeAll(async () => {
|
|
150
|
-
db = await TestDatabase.create();
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
afterAll(async () => {
|
|
154
|
-
await db.destroy();
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
beforeEach(async () => {
|
|
158
|
-
await db.seed(testData);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
afterEach(async () => {
|
|
162
|
-
await db.truncate();
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it('creates a record', async () => {
|
|
166
|
-
const record = await db.insert({ name: 'test' });
|
|
167
|
-
expect(record.id).toBeDefined();
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## Anti-Patterns
|
|
173
|
-
|
|
174
|
-
1. **Implementation testing** — Testing that a function calls another internal function
|
|
175
|
-
rather than testing the observable output. Refactoring breaks these tests.
|
|
176
|
-
|
|
177
|
-
2. **Snapshot overuse** — Large component snapshots that nobody reviews. Snapshots
|
|
178
|
-
should be small, targeted, and meaningful.
|
|
179
|
-
|
|
180
|
-
3. **Testing framework internals** — Verifying React re-renders or state updates
|
|
181
|
-
instead of rendered output. Test what the user sees.
|
|
182
|
-
|
|
183
|
-
4. **Mocking everything** — Mocking the module under test or its direct logic.
|
|
184
|
-
Only mock external dependencies and side effects.
|
|
185
|
-
|
|
186
|
-
5. **Ignoring async cleanup** — Not awaiting cleanup in afterEach, causing test
|
|
187
|
-
pollution and flaky failures.
|
|
188
|
-
|
|
189
|
-
## Integration Points
|
|
190
|
-
|
|
191
|
-
- **Frameworks**: React (RTL), Next.js (next/jest), Express (supertest), Vue (vue-test-utils)
|
|
192
|
-
- **Workflows**: `test-framework` (initial setup), `test-automation` (coverage expansion)
|
|
193
|
-
- **Related fragments**: `fixture-architecture` (test helpers), `test-isolation` (isolation)
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: junit5-patterns
|
|
3
|
-
tier: unit-testing
|
|
4
|
-
version: '1.0'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# JUnit 5 Patterns
|
|
8
|
-
|
|
9
|
-
## Principle
|
|
10
|
-
|
|
11
|
-
Strong typing enables compile-time test safety in Java. JUnit 5's extension model
|
|
12
|
-
and parameterized test support provide flexible, type-safe test composition. Combined
|
|
13
|
-
with Mockito and Spring test slices, it covers the full testing spectrum from unit
|
|
14
|
-
to integration.
|
|
15
|
-
|
|
16
|
-
## Rationale
|
|
17
|
-
|
|
18
|
-
Java's verbose syntax makes test readability a priority. JUnit 5's annotations,
|
|
19
|
-
@Nested classes for grouping, and @ParameterizedTest for data-driven tests reduce
|
|
20
|
-
boilerplate while maintaining clarity. Spring Boot's test slices load only necessary
|
|
21
|
-
context, keeping tests fast.
|
|
22
|
-
|
|
23
|
-
## Pattern Examples
|
|
24
|
-
|
|
25
|
-
### Basic Structure
|
|
26
|
-
|
|
27
|
-
```java
|
|
28
|
-
import org.junit.jupiter.api.*;
|
|
29
|
-
import static org.assertj.core.api.Assertions.*;
|
|
30
|
-
|
|
31
|
-
class PriceCalculatorTest {
|
|
32
|
-
|
|
33
|
-
private PriceCalculator calculator;
|
|
34
|
-
|
|
35
|
-
@BeforeEach
|
|
36
|
-
void setUp() {
|
|
37
|
-
calculator = new PriceCalculator();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@Test
|
|
41
|
-
@DisplayName("applies percentage discount correctly")
|
|
42
|
-
void appliesPercentageDiscount() {
|
|
43
|
-
BigDecimal result = calculator.applyDiscount(
|
|
44
|
-
new BigDecimal("100.00"),
|
|
45
|
-
Discount.percentage(20)
|
|
46
|
-
);
|
|
47
|
-
assertThat(result).isEqualByComparingTo("80.00");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@Test
|
|
51
|
-
@DisplayName("floors discount at zero")
|
|
52
|
-
void floorsDiscountAtZero() {
|
|
53
|
-
BigDecimal result = calculator.applyDiscount(
|
|
54
|
-
new BigDecimal("10.00"),
|
|
55
|
-
Discount.fixed(new BigDecimal("20.00"))
|
|
56
|
-
);
|
|
57
|
-
assertThat(result).isEqualByComparingTo("0.00");
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Nested Groups and Parameterized Tests
|
|
63
|
-
|
|
64
|
-
```java
|
|
65
|
-
class UserServiceTest {
|
|
66
|
-
@Nested @DisplayName("when creating a user")
|
|
67
|
-
class CreateUser {
|
|
68
|
-
@Test void savesUserToDatabase() { /* ... */ }
|
|
69
|
-
@Test void sendsWelcomeEmail() { /* ... */ }
|
|
70
|
-
@Test void rejectsDuplicateEmail() { /* ... */ }
|
|
71
|
-
}
|
|
72
|
-
@Nested @DisplayName("when deleting a user")
|
|
73
|
-
class DeleteUser {
|
|
74
|
-
@Test void removesFromDatabase() { /* ... */ }
|
|
75
|
-
@Test void requiresAdminRole() { /* ... */ }
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
```java
|
|
81
|
-
@ParameterizedTest
|
|
82
|
-
@CsvSource({
|
|
83
|
-
"hello, HELLO",
|
|
84
|
-
"Hello World, HELLO WORLD",
|
|
85
|
-
"'', ''",
|
|
86
|
-
"123abc, 123ABC"
|
|
87
|
-
})
|
|
88
|
-
void convertsToUpperCase(String input, String expected) {
|
|
89
|
-
assertThat(input.toUpperCase()).isEqualTo(expected);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@ParameterizedTest
|
|
93
|
-
@MethodSource("provideInvalidEmails")
|
|
94
|
-
void rejectsInvalidEmails(String email) {
|
|
95
|
-
assertThat(validator.isValid(email)).isFalse();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
static Stream<String> provideInvalidEmails() {
|
|
99
|
-
return Stream.of("invalid", "@example.com", "user@", "", null);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Mockito Patterns
|
|
104
|
-
|
|
105
|
-
```java
|
|
106
|
-
@ExtendWith(MockitoExtension.class)
|
|
107
|
-
class OrderServiceTest {
|
|
108
|
-
@Mock private OrderRepository orderRepository;
|
|
109
|
-
@Mock private PaymentGateway paymentGateway;
|
|
110
|
-
@InjectMocks private OrderService orderService;
|
|
111
|
-
|
|
112
|
-
@Test
|
|
113
|
-
void processesOrderSuccessfully() {
|
|
114
|
-
when(paymentGateway.charge(any())).thenReturn(PaymentResult.success());
|
|
115
|
-
Order order = orderService.placeOrder(new OrderRequest("item-1", 2));
|
|
116
|
-
assertThat(order.getStatus()).isEqualTo(OrderStatus.CONFIRMED);
|
|
117
|
-
verify(orderRepository).save(order);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Testcontainers for Integration
|
|
123
|
-
|
|
124
|
-
```java
|
|
125
|
-
@Testcontainers
|
|
126
|
-
@SpringBootTest
|
|
127
|
-
class UserRepositoryIntegrationTest {
|
|
128
|
-
@Container
|
|
129
|
-
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
|
|
130
|
-
.withDatabaseName("testdb");
|
|
131
|
-
|
|
132
|
-
@DynamicPropertySource
|
|
133
|
-
static void configureProperties(DynamicPropertyRegistry registry) {
|
|
134
|
-
registry.add("spring.datasource.url", postgres::getJdbcUrl);
|
|
135
|
-
registry.add("spring.datasource.username", postgres::getUsername);
|
|
136
|
-
registry.add("spring.datasource.password", postgres::getPassword);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
@Autowired private UserRepository userRepository;
|
|
140
|
-
|
|
141
|
-
@Test
|
|
142
|
-
void savesAndRetrievesUser() {
|
|
143
|
-
userRepository.save(new User("Alice", "alice@example.com"));
|
|
144
|
-
Optional<User> found = userRepository.findByEmail("alice@example.com");
|
|
145
|
-
assertThat(found).isPresent();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Spring Boot Test Slices
|
|
151
|
-
|
|
152
|
-
```java
|
|
153
|
-
@WebMvcTest(UserController.class) // Only loads web layer
|
|
154
|
-
class UserControllerTest {
|
|
155
|
-
@Autowired private MockMvc mockMvc;
|
|
156
|
-
@MockBean private UserService userService;
|
|
157
|
-
|
|
158
|
-
@Test
|
|
159
|
-
void returnsUserById() throws Exception {
|
|
160
|
-
when(userService.findById(1L)).thenReturn(new UserDto("Alice"));
|
|
161
|
-
mockMvc.perform(get("/api/users/1"))
|
|
162
|
-
.andExpect(status().isOk())
|
|
163
|
-
.andExpect(jsonPath("$.name").value("Alice"));
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
@DataJpaTest // Only loads JPA layer
|
|
168
|
-
class OrderRepositoryTest {
|
|
169
|
-
@Autowired private TestEntityManager entityManager;
|
|
170
|
-
@Autowired private OrderRepository orderRepository;
|
|
171
|
-
|
|
172
|
-
@Test
|
|
173
|
-
void findsByStatus() {
|
|
174
|
-
entityManager.persist(new Order(OrderStatus.PENDING));
|
|
175
|
-
assertThat(orderRepository.findByStatus(OrderStatus.PENDING)).hasSize(1);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Anti-Patterns
|
|
181
|
-
|
|
182
|
-
1. **Testing private methods** — If you need to test a private method, the class likely
|
|
183
|
-
violates SRP. Extract the logic into a separate class and test its public API.
|
|
184
|
-
|
|
185
|
-
2. **Excessive mocking** — Mocking so many dependencies that the test validates nothing
|
|
186
|
-
real. If a test has 5+ mocks, consider an integration test instead.
|
|
187
|
-
|
|
188
|
-
3. **Slow test suites** — Using @SpringBootTest for everything loads the full context.
|
|
189
|
-
Use test slices (@WebMvcTest, @DataJpaTest) for focused, fast tests.
|
|
190
|
-
|
|
191
|
-
4. **Testing getters and setters** — Trivial code that cannot fail does not need tests.
|
|
192
|
-
|
|
193
|
-
5. **Ignoring test naming** — @DisplayName should describe the expected behavior,
|
|
194
|
-
not the method name. "saves user" not "testSaveUser".
|
|
195
|
-
|
|
196
|
-
## Integration Points
|
|
197
|
-
|
|
198
|
-
- **Frameworks**: Spring Boot, JPA/Hibernate, Maven Surefire (unit), Failsafe (integration)
|
|
199
|
-
- **Workflows**: `test-framework` (initial setup), `test-automation` (coverage expansion)
|
|
200
|
-
- **Related fragments**: `fixture-architecture` (factory patterns), `test-isolation` (database isolation)
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pytest-patterns
|
|
3
|
-
tier: unit-testing
|
|
4
|
-
version: '1.0'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Pytest Patterns
|
|
8
|
-
|
|
9
|
-
## Principle
|
|
10
|
-
|
|
11
|
-
Fixtures are the foundation of test architecture in Python. pytest's fixture system
|
|
12
|
-
enables composable, scoped test dependencies that eliminate setup duplication while
|
|
13
|
-
maintaining test isolation. Combine fixtures with parameterization for thorough
|
|
14
|
-
coverage without test proliferation.
|
|
15
|
-
|
|
16
|
-
## Rationale
|
|
17
|
-
|
|
18
|
-
Python's dynamic nature makes test setup verbose without fixtures. pytest's dependency
|
|
19
|
-
injection model lets tests declare what they need, not how to build it. This separation
|
|
20
|
-
of concern keeps tests focused on assertions while fixtures handle the plumbing.
|
|
21
|
-
|
|
22
|
-
## Pattern Examples
|
|
23
|
-
|
|
24
|
-
### conftest.py Hierarchy
|
|
25
|
-
|
|
26
|
-
```python
|
|
27
|
-
# tests/conftest.py — shared across all tests
|
|
28
|
-
import pytest
|
|
29
|
-
from app import create_app
|
|
30
|
-
from app.db import db as _db
|
|
31
|
-
|
|
32
|
-
@pytest.fixture(scope="session")
|
|
33
|
-
def app():
|
|
34
|
-
app = create_app(config="testing")
|
|
35
|
-
yield app
|
|
36
|
-
|
|
37
|
-
@pytest.fixture(scope="session")
|
|
38
|
-
def db(app):
|
|
39
|
-
with app.app_context():
|
|
40
|
-
_db.create_all()
|
|
41
|
-
yield _db
|
|
42
|
-
_db.drop_all()
|
|
43
|
-
|
|
44
|
-
@pytest.fixture
|
|
45
|
-
def session(db):
|
|
46
|
-
connection = db.engine.connect()
|
|
47
|
-
transaction = connection.begin()
|
|
48
|
-
session = db.create_scoped_session(bind=connection)
|
|
49
|
-
yield session
|
|
50
|
-
session.close()
|
|
51
|
-
transaction.rollback()
|
|
52
|
-
connection.close()
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Fixture Scoping
|
|
56
|
-
|
|
57
|
-
```python
|
|
58
|
-
# function — fresh per test (default, safest)
|
|
59
|
-
@pytest.fixture
|
|
60
|
-
def user():
|
|
61
|
-
return User(name="test", email="test@example.com")
|
|
62
|
-
|
|
63
|
-
# class — shared within a test class
|
|
64
|
-
@pytest.fixture(scope="class")
|
|
65
|
-
def api_client(app):
|
|
66
|
-
return app.test_client()
|
|
67
|
-
|
|
68
|
-
# module — shared within a file
|
|
69
|
-
@pytest.fixture(scope="module")
|
|
70
|
-
def expensive_resource():
|
|
71
|
-
return load_large_dataset()
|
|
72
|
-
|
|
73
|
-
# session — shared across entire test run
|
|
74
|
-
@pytest.fixture(scope="session")
|
|
75
|
-
def database_engine():
|
|
76
|
-
return create_engine("sqlite:///:memory:")
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Parameterized Tests
|
|
80
|
-
|
|
81
|
-
```python
|
|
82
|
-
@pytest.mark.parametrize("input_val,expected", [
|
|
83
|
-
("hello", "HELLO"),
|
|
84
|
-
("Hello World", "HELLO WORLD"),
|
|
85
|
-
("", ""),
|
|
86
|
-
("123abc", "123ABC"),
|
|
87
|
-
])
|
|
88
|
-
def test_uppercase(input_val, expected):
|
|
89
|
-
assert input_val.upper() == expected
|
|
90
|
-
|
|
91
|
-
@pytest.mark.parametrize("discount_type,amount,expected", [
|
|
92
|
-
("percentage", 20, 80.0),
|
|
93
|
-
("fixed", 15, 85.0),
|
|
94
|
-
("percentage", 100, 0.0),
|
|
95
|
-
("fixed", 200, 0.0),
|
|
96
|
-
])
|
|
97
|
-
def test_apply_discount(discount_type, amount, expected):
|
|
98
|
-
result = apply_discount(100, discount_type, amount)
|
|
99
|
-
assert result == expected
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Factory Fixtures
|
|
103
|
-
|
|
104
|
-
```python
|
|
105
|
-
@pytest.fixture
|
|
106
|
-
def make_user(session):
|
|
107
|
-
def _make_user(name="test", email=None, role="user"):
|
|
108
|
-
email = email or f"{name}@example.com"
|
|
109
|
-
user = User(name=name, email=email, role=role)
|
|
110
|
-
session.add(user)
|
|
111
|
-
session.commit()
|
|
112
|
-
return user
|
|
113
|
-
return _make_user
|
|
114
|
-
|
|
115
|
-
def test_admin_permissions(make_user):
|
|
116
|
-
admin = make_user(name="admin", role="admin")
|
|
117
|
-
assert admin.can("delete_users")
|
|
118
|
-
|
|
119
|
-
def test_regular_user_restrictions(make_user):
|
|
120
|
-
user = make_user(name="regular", role="user")
|
|
121
|
-
assert not user.can("delete_users")
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Mocking with pytest-mock
|
|
125
|
-
|
|
126
|
-
```python
|
|
127
|
-
def test_send_notification(mocker):
|
|
128
|
-
mock_smtp = mocker.patch("app.notifications.smtplib.SMTP")
|
|
129
|
-
send_welcome_email("user@example.com")
|
|
130
|
-
mock_smtp.return_value.sendmail.assert_called_once()
|
|
131
|
-
|
|
132
|
-
def test_external_api_call(mocker):
|
|
133
|
-
mocker.patch(
|
|
134
|
-
"app.services.requests.get",
|
|
135
|
-
return_value=mocker.Mock(status_code=200, json=lambda: {"data": "value"})
|
|
136
|
-
)
|
|
137
|
-
result = fetch_external_data()
|
|
138
|
-
assert result == {"data": "value"}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Async Testing
|
|
142
|
-
|
|
143
|
-
```python
|
|
144
|
-
import pytest
|
|
145
|
-
|
|
146
|
-
@pytest.mark.asyncio
|
|
147
|
-
async def test_async_fetch(aiohttp_client):
|
|
148
|
-
client = await aiohttp_client(app)
|
|
149
|
-
resp = await client.get("/api/data")
|
|
150
|
-
assert resp.status == 200
|
|
151
|
-
data = await resp.json()
|
|
152
|
-
assert "items" in data
|
|
153
|
-
|
|
154
|
-
@pytest.mark.asyncio
|
|
155
|
-
async def test_concurrent_operations():
|
|
156
|
-
results = await asyncio.gather(
|
|
157
|
-
process_item("a"),
|
|
158
|
-
process_item("b"),
|
|
159
|
-
process_item("c"),
|
|
160
|
-
)
|
|
161
|
-
assert all(r.success for r in results)
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## Anti-Patterns
|
|
165
|
-
|
|
166
|
-
1. **Global state between tests** — Tests modifying module-level variables create
|
|
167
|
-
ordering dependencies. Use fixtures with function scope instead.
|
|
168
|
-
|
|
169
|
-
2. **Test interdependence** — Test B relying on side effects from Test A. Each test
|
|
170
|
-
must set up its own state via fixtures.
|
|
171
|
-
|
|
172
|
-
3. **Over-mocking** — Mocking the system under test rather than its dependencies.
|
|
173
|
-
Mock at boundaries, not at the core logic.
|
|
174
|
-
|
|
175
|
-
4. **Broad fixture scope without cleanup** — Session-scoped fixtures that accumulate
|
|
176
|
-
state across tests. Always pair with proper teardown.
|
|
177
|
-
|
|
178
|
-
5. **Fixture overuse** — Simple values (strings, numbers) passed as fixtures instead
|
|
179
|
-
of inline constants. Fixtures are for complex setup, not constants.
|
|
180
|
-
|
|
181
|
-
## Integration Points
|
|
182
|
-
|
|
183
|
-
- **Frameworks**: pytest-django (Django), pytest-flask (Flask), httpx/TestClient (FastAPI)
|
|
184
|
-
- **Workflows**: `test-framework` (initial setup), `test-automation` (coverage expansion)
|
|
185
|
-
- **Related fragments**: `fixture-architecture` (fixture design), `test-isolation` (isolation strategies)
|