aigroup-workflow 2.2.0 → 2.2.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/.claude/commands/fix-build.md +10 -5
- package/.claude/commands/init-project.md +13 -8
- package/.claude/commands/plan.md +15 -8
- package/.claude/commands/review.md +12 -6
- package/.claude/commands/tdd.md +11 -5
- package/.claude/commands/workflow-start.md +20 -11
- package/.claude/settings.json +28 -0
- package/.codex/agents/architect.toml +207 -0
- package/.codex/agents/build-error-resolver.toml +110 -0
- package/.codex/agents/code-reviewer.toml +233 -0
- package/.codex/agents/doc-updater.toml +103 -0
- package/.codex/agents/e2e-runner.toml +103 -0
- package/.codex/agents/get-current-datetime.toml +23 -0
- package/.codex/agents/init-architect.toml +181 -0
- package/.codex/agents/planner.toml +208 -0
- package/.codex/agents/refactor-cleaner.toml +81 -0
- package/.codex/agents/rust-reviewer.toml +90 -0
- package/.codex/agents/security-reviewer.toml +104 -0
- package/.codex/agents/tdd-guide.toml +87 -0
- package/AGENTS.md +2 -2
- package/CLAUDE.md +23 -1
- package/LICENSE +20 -20
- package/README.md +333 -333
- package/agents/a11y-architect.md +141 -141
- package/agents/architect.md +211 -211
- package/agents/build-error-resolver.md +114 -114
- package/agents/chief-of-staff.md +151 -151
- package/agents/code-architect.md +71 -71
- package/agents/code-explorer.md +69 -69
- package/agents/code-reviewer.md +237 -237
- package/agents/code-simplifier.md +47 -47
- package/agents/comment-analyzer.md +45 -45
- package/agents/conversation-analyzer.md +52 -52
- package/agents/cpp-build-resolver.md +90 -90
- package/agents/cpp-reviewer.md +72 -72
- package/agents/csharp-reviewer.md +101 -101
- package/agents/dart-build-resolver.md +201 -201
- package/agents/database-reviewer.md +91 -91
- package/agents/doc-updater.md +107 -107
- package/agents/docs-lookup.md +68 -68
- package/agents/e2e-runner.md +107 -107
- package/agents/flutter-reviewer.md +243 -243
- package/agents/gan-evaluator.md +209 -209
- package/agents/gan-generator.md +131 -131
- package/agents/gan-planner.md +99 -99
- package/agents/get-current-datetime.md +26 -26
- package/agents/go-build-resolver.md +94 -94
- package/agents/go-reviewer.md +76 -76
- package/agents/harness-optimizer.md +35 -35
- package/agents/healthcare-reviewer.md +83 -83
- package/agents/java-build-resolver.md +153 -153
- package/agents/java-reviewer.md +92 -92
- package/agents/kotlin-build-resolver.md +118 -118
- package/agents/kotlin-reviewer.md +159 -159
- package/agents/loop-operator.md +36 -36
- package/agents/opensource-forker.md +198 -198
- package/agents/opensource-packager.md +249 -249
- package/agents/opensource-sanitizer.md +188 -188
- package/agents/performance-optimizer.md +446 -446
- package/agents/planner.md +212 -212
- package/agents/pr-test-analyzer.md +45 -45
- package/agents/python-reviewer.md +98 -98
- package/agents/pytorch-build-resolver.md +120 -120
- package/agents/refactor-cleaner.md +85 -85
- package/agents/rust-build-resolver.md +148 -148
- package/agents/rust-reviewer.md +94 -94
- package/agents/security-reviewer.md +108 -108
- package/agents/seo-specialist.md +59 -59
- package/agents/silent-failure-hunter.md +50 -50
- package/agents/tdd-guide.md +91 -91
- package/agents/type-design-analyzer.md +41 -41
- package/agents/typescript-reviewer.md +112 -112
- package/cli/commands/update.mjs +1 -1
- package/cli/utils/scaffold.mjs +53 -0
- package/docs/rules/agents.md +166 -50
- package/docs/rules/cpp/coding-style.md +44 -44
- package/docs/rules/cpp/hooks.md +39 -39
- package/docs/rules/cpp/patterns.md +51 -51
- package/docs/rules/cpp/security.md +51 -51
- package/docs/rules/cpp/testing.md +44 -44
- package/docs/rules/csharp/coding-style.md +72 -72
- package/docs/rules/csharp/hooks.md +25 -25
- package/docs/rules/csharp/patterns.md +50 -50
- package/docs/rules/csharp/security.md +58 -58
- package/docs/rules/csharp/testing.md +46 -46
- package/docs/rules/dart/coding-style.md +159 -159
- package/docs/rules/dart/hooks.md +66 -66
- package/docs/rules/dart/patterns.md +261 -261
- package/docs/rules/dart/security.md +135 -135
- package/docs/rules/dart/testing.md +215 -215
- package/docs/rules/golang/coding-style.md +32 -32
- package/docs/rules/golang/hooks.md +17 -17
- package/docs/rules/golang/patterns.md +45 -45
- package/docs/rules/golang/security.md +34 -34
- package/docs/rules/golang/testing.md +31 -31
- package/docs/rules/java/coding-style.md +114 -114
- package/docs/rules/java/hooks.md +18 -18
- package/docs/rules/java/patterns.md +146 -146
- package/docs/rules/java/security.md +100 -100
- package/docs/rules/java/testing.md +131 -131
- package/docs/rules/kotlin/coding-style.md +86 -86
- package/docs/rules/kotlin/hooks.md +17 -17
- package/docs/rules/kotlin/patterns.md +146 -146
- package/docs/rules/kotlin/security.md +82 -82
- package/docs/rules/kotlin/testing.md +128 -128
- package/docs/rules/perl/coding-style.md +46 -46
- package/docs/rules/perl/hooks.md +22 -22
- package/docs/rules/perl/patterns.md +76 -76
- package/docs/rules/perl/security.md +69 -69
- package/docs/rules/perl/testing.md +54 -54
- package/docs/rules/php/coding-style.md +40 -40
- package/docs/rules/php/hooks.md +24 -24
- package/docs/rules/php/patterns.md +33 -33
- package/docs/rules/php/security.md +37 -37
- package/docs/rules/php/testing.md +39 -39
- package/docs/rules/python/coding-style.md +42 -42
- package/docs/rules/python/hooks.md +19 -19
- package/docs/rules/python/patterns.md +39 -39
- package/docs/rules/python/security.md +30 -30
- package/docs/rules/python/testing.md +38 -38
- package/docs/rules/rust/coding-style.md +151 -151
- package/docs/rules/rust/hooks.md +16 -16
- package/docs/rules/rust/patterns.md +168 -168
- package/docs/rules/rust/security.md +141 -141
- package/docs/rules/rust/testing.md +154 -154
- package/docs/rules/swift/coding-style.md +47 -47
- package/docs/rules/swift/hooks.md +20 -20
- package/docs/rules/swift/patterns.md +66 -66
- package/docs/rules/swift/security.md +33 -33
- package/docs/rules/swift/testing.md +45 -45
- package/docs/rules/typescript/coding-style.md +199 -199
- package/docs/rules/typescript/hooks.md +22 -22
- package/docs/rules/typescript/patterns.md +52 -52
- package/docs/rules/typescript/security.md +28 -28
- package/docs/rules/typescript/testing.md +18 -18
- package/docs/rules/web/coding-style.md +96 -96
- package/docs/rules/web/design-quality.md +62 -62
- package/docs/rules/web/hooks.md +120 -120
- package/docs/rules/web/patterns.md +79 -79
- package/docs/rules/web/performance.md +64 -64
- package/docs/rules/web/security.md +57 -57
- package/docs/rules/web/testing.md +55 -55
- package/docs/templates/README.md +36 -36
- package/docs/templates/ai-project-final.md +124 -124
- package/docs/templates/ai-project.md +105 -105
- package/docs/templates/api.md +157 -157
- package/docs/templates/bug.md +62 -62
- package/docs/templates/code-review.md +87 -87
- package/docs/templates/generic.md +116 -116
- package/docs/templates/implementation-plan.md +1 -1
- package/docs/templates/meeting.md +68 -68
- package/docs/templates/prd.md +98 -98
- package/docs/templates/ui.md +134 -134
- package/docs/workflow-pipeline.md +11 -10
- package/package.json +40 -39
- package/scripts/hooks/checks/orchestration-artifacts.cjs +28 -23
- package/scripts/hooks/checks/workflow-state.cjs +4 -5
- package/scripts/orchestration/lib/orchestrator.cjs +344 -117
- package/scripts/orchestration/lib/validate.cjs +145 -0
- package/scripts/orchestration/session.cjs +88 -44
- package/skills/SUPERPOWERS-LICENSE +21 -21
- package/skills/ai-ml/fine-tuning-expert/SKILL.md +162 -162
- package/skills/ai-ml/fine-tuning-expert/references/dataset-preparation.md +540 -540
- package/skills/ai-ml/fine-tuning-expert/references/deployment-optimization.md +673 -673
- package/skills/ai-ml/fine-tuning-expert/references/evaluation-metrics.md +597 -597
- package/skills/ai-ml/fine-tuning-expert/references/hyperparameter-tuning.md +565 -565
- package/skills/ai-ml/fine-tuning-expert/references/lora-peft.md +347 -347
- package/skills/ai-ml/ml-pipeline/SKILL.md +159 -159
- package/skills/ai-ml/ml-pipeline/references/experiment-tracking.md +833 -833
- package/skills/ai-ml/ml-pipeline/references/feature-engineering.md +631 -631
- package/skills/ai-ml/ml-pipeline/references/model-validation.md +978 -978
- package/skills/ai-ml/ml-pipeline/references/pipeline-orchestration.md +907 -907
- package/skills/ai-ml/ml-pipeline/references/training-pipelines.md +782 -782
- package/skills/ai-ml/rag-architect/SKILL.md +194 -194
- package/skills/ai-ml/rag-architect/references/chunking-strategies.md +878 -878
- package/skills/ai-ml/rag-architect/references/embedding-models.md +561 -561
- package/skills/ai-ml/rag-architect/references/rag-evaluation.md +833 -833
- package/skills/ai-ml/rag-architect/references/retrieval-optimization.md +795 -795
- package/skills/ai-ml/rag-architect/references/vector-databases.md +589 -589
- package/skills/ai-ml/spark-engineer/SKILL.md +148 -148
- package/skills/ai-ml/spark-engineer/references/partitioning-caching.md +543 -543
- package/skills/ai-ml/spark-engineer/references/performance-tuning.md +544 -544
- package/skills/ai-ml/spark-engineer/references/rdd-operations.md +599 -599
- package/skills/ai-ml/spark-engineer/references/spark-sql-dataframes.md +474 -474
- package/skills/ai-ml/spark-engineer/references/streaming-patterns.md +786 -786
- package/skills/backend/api-designer/SKILL.md +217 -217
- package/skills/backend/api-designer/references/error-handling.md +541 -541
- package/skills/backend/api-designer/references/openapi.md +824 -824
- package/skills/backend/api-designer/references/pagination.md +494 -494
- package/skills/backend/api-designer/references/rest-patterns.md +335 -335
- package/skills/backend/api-designer/references/versioning.md +391 -391
- package/skills/backend/architecture-designer/SKILL.md +117 -117
- package/skills/backend/architecture-designer/references/adr-template.md +116 -116
- package/skills/backend/architecture-designer/references/architecture-patterns.md +111 -111
- package/skills/backend/architecture-designer/references/database-selection.md +102 -102
- package/skills/backend/architecture-designer/references/nfr-checklist.md +112 -112
- package/skills/backend/architecture-designer/references/system-design.md +100 -100
- package/skills/backend/code-documenter/SKILL.md +147 -147
- package/skills/backend/code-documenter/references/api-docs-fastapi-django.md +166 -166
- package/skills/backend/code-documenter/references/api-docs-nestjs-express.md +220 -220
- package/skills/backend/code-documenter/references/coverage-reports.md +125 -125
- package/skills/backend/code-documenter/references/documentation-systems.md +333 -333
- package/skills/backend/code-documenter/references/interactive-api-docs.md +531 -531
- package/skills/backend/code-documenter/references/python-docstrings.md +121 -121
- package/skills/backend/code-documenter/references/typescript-jsdoc.md +145 -145
- package/skills/backend/code-documenter/references/user-guides-tutorials.md +530 -530
- package/skills/backend/debugging-wizard/SKILL.md +105 -105
- package/skills/backend/debugging-wizard/references/common-patterns.md +132 -132
- package/skills/backend/debugging-wizard/references/debugging-tools.md +140 -140
- package/skills/backend/debugging-wizard/references/quick-fixes.md +177 -177
- package/skills/backend/debugging-wizard/references/strategies.md +142 -142
- package/skills/backend/debugging-wizard/references/systematic-debugging.md +367 -367
- package/skills/backend/feature-forge/SKILL.md +98 -98
- package/skills/backend/feature-forge/references/acceptance-criteria.md +104 -104
- package/skills/backend/feature-forge/references/ears-syntax.md +99 -99
- package/skills/backend/feature-forge/references/interview-questions.md +150 -150
- package/skills/backend/feature-forge/references/pre-discovery-subagents.md +54 -54
- package/skills/backend/feature-forge/references/specification-template.md +103 -103
- package/skills/backend/fullstack-guardian/SKILL.md +105 -105
- package/skills/backend/fullstack-guardian/references/api-design-standards.md +307 -307
- package/skills/backend/fullstack-guardian/references/architecture-decisions.md +350 -350
- package/skills/backend/fullstack-guardian/references/backend-patterns.md +237 -237
- package/skills/backend/fullstack-guardian/references/common-patterns.md +134 -134
- package/skills/backend/fullstack-guardian/references/deliverables-checklist.md +354 -354
- package/skills/backend/fullstack-guardian/references/design-template.md +91 -91
- package/skills/backend/fullstack-guardian/references/error-handling.md +135 -135
- package/skills/backend/fullstack-guardian/references/frontend-patterns.md +340 -340
- package/skills/backend/fullstack-guardian/references/integration-patterns.md +333 -333
- package/skills/backend/fullstack-guardian/references/security-checklist.md +106 -106
- package/skills/backend/graphql-architect/SKILL.md +146 -146
- package/skills/backend/graphql-architect/references/federation.md +418 -418
- package/skills/backend/graphql-architect/references/migration-from-rest.md +1141 -1141
- package/skills/backend/graphql-architect/references/resolvers.md +425 -425
- package/skills/backend/graphql-architect/references/schema-design.md +393 -393
- package/skills/backend/graphql-architect/references/security.md +569 -569
- package/skills/backend/graphql-architect/references/subscriptions.md +510 -510
- package/skills/backend/legacy-modernizer/SKILL.md +137 -137
- package/skills/backend/legacy-modernizer/references/legacy-testing.md +381 -381
- package/skills/backend/legacy-modernizer/references/migration-strategies.md +423 -423
- package/skills/backend/legacy-modernizer/references/refactoring-patterns.md +395 -395
- package/skills/backend/legacy-modernizer/references/strangler-fig-pattern.md +281 -281
- package/skills/backend/legacy-modernizer/references/system-assessment.md +487 -487
- package/skills/backend/microservices-architect/SKILL.md +164 -164
- package/skills/backend/microservices-architect/references/communication.md +499 -499
- package/skills/backend/microservices-architect/references/data.md +721 -721
- package/skills/backend/microservices-architect/references/decomposition.md +344 -344
- package/skills/backend/microservices-architect/references/observability.md +805 -805
- package/skills/backend/microservices-architect/references/patterns.md +603 -603
- package/skills/database/database-optimizer/SKILL.md +147 -147
- package/skills/database/database-optimizer/references/index-strategies.md +331 -331
- package/skills/database/database-optimizer/references/monitoring-analysis.md +501 -501
- package/skills/database/database-optimizer/references/mysql-tuning.md +452 -452
- package/skills/database/database-optimizer/references/postgresql-tuning.md +413 -413
- package/skills/database/database-optimizer/references/query-optimization.md +251 -251
- package/skills/database/postgres-pro/SKILL.md +152 -152
- package/skills/database/postgres-pro/references/extensions.md +404 -404
- package/skills/database/postgres-pro/references/jsonb.md +321 -321
- package/skills/database/postgres-pro/references/maintenance.md +481 -481
- package/skills/database/postgres-pro/references/performance.md +265 -265
- package/skills/database/postgres-pro/references/replication.md +446 -446
- package/skills/database/sql-pro/SKILL.md +129 -129
- package/skills/database/sql-pro/references/database-design.md +402 -402
- package/skills/database/sql-pro/references/dialect-differences.md +419 -419
- package/skills/database/sql-pro/references/optimization.md +384 -384
- package/skills/database/sql-pro/references/query-patterns.md +285 -285
- package/skills/database/sql-pro/references/window-functions.md +328 -328
- package/skills/dotnet/csharp-developer/SKILL.md +125 -125
- package/skills/dotnet/csharp-developer/references/aspnet-core.md +394 -394
- package/skills/dotnet/csharp-developer/references/blazor.md +553 -553
- package/skills/dotnet/csharp-developer/references/entity-framework.md +409 -409
- package/skills/dotnet/csharp-developer/references/modern-csharp.md +248 -248
- package/skills/dotnet/csharp-developer/references/performance.md +498 -498
- package/skills/dotnet/dotnet-core-expert/SKILL.md +138 -138
- package/skills/dotnet/dotnet-core-expert/references/authentication.md +546 -546
- package/skills/dotnet/dotnet-core-expert/references/clean-architecture.md +455 -455
- package/skills/dotnet/dotnet-core-expert/references/cloud-native.md +548 -548
- package/skills/dotnet/dotnet-core-expert/references/entity-framework.md +440 -440
- package/skills/dotnet/dotnet-core-expert/references/minimal-apis.md +319 -319
- package/skills/frontend/angular-architect/SKILL.md +152 -152
- package/skills/frontend/angular-architect/references/components.md +297 -297
- package/skills/frontend/angular-architect/references/ngrx.md +401 -401
- package/skills/frontend/angular-architect/references/routing.md +361 -361
- package/skills/frontend/angular-architect/references/rxjs.md +319 -319
- package/skills/frontend/angular-architect/references/testing.md +405 -405
- package/skills/frontend/design-commands/design.md +91 -91
- package/skills/frontend/design-commands/handoff.md +97 -97
- package/skills/frontend/design-commands/prototype.md +120 -120
- package/skills/frontend/design-commands/spec.md +160 -160
- package/skills/frontend/design-commands/style.md +78 -78
- package/skills/frontend/flutter-expert/SKILL.md +138 -138
- package/skills/frontend/flutter-expert/references/bloc-state.md +259 -259
- package/skills/frontend/flutter-expert/references/gorouter-navigation.md +119 -119
- package/skills/frontend/flutter-expert/references/performance.md +99 -99
- package/skills/frontend/flutter-expert/references/project-structure.md +118 -118
- package/skills/frontend/flutter-expert/references/riverpod-state.md +130 -130
- package/skills/frontend/flutter-expert/references/widget-patterns.md +123 -123
- package/skills/frontend/nextjs-developer/SKILL.md +143 -143
- package/skills/frontend/nextjs-developer/references/app-router.md +311 -311
- package/skills/frontend/nextjs-developer/references/data-fetching.md +482 -482
- package/skills/frontend/nextjs-developer/references/deployment.md +545 -545
- package/skills/frontend/nextjs-developer/references/server-actions.md +462 -462
- package/skills/frontend/nextjs-developer/references/server-components.md +384 -384
- package/skills/frontend/react-expert/SKILL.md +149 -149
- package/skills/frontend/react-expert/references/hooks-patterns.md +162 -162
- package/skills/frontend/react-expert/references/migration-class-to-modern.md +1119 -1119
- package/skills/frontend/react-expert/references/performance.md +168 -168
- package/skills/frontend/react-expert/references/react-19-features.md +174 -174
- package/skills/frontend/react-expert/references/server-components.md +143 -143
- package/skills/frontend/react-expert/references/state-management.md +171 -171
- package/skills/frontend/react-expert/references/testing-react.md +174 -174
- package/skills/frontend/react-native-expert/SKILL.md +185 -185
- package/skills/frontend/react-native-expert/references/expo-router.md +187 -187
- package/skills/frontend/react-native-expert/references/list-optimization.md +204 -204
- package/skills/frontend/react-native-expert/references/platform-handling.md +188 -188
- package/skills/frontend/react-native-expert/references/project-structure.md +171 -171
- package/skills/frontend/react-native-expert/references/storage-hooks.md +173 -173
- package/skills/frontend/senior-frontend/SKILL.md +477 -477
- package/skills/frontend/senior-frontend/references/frontend_best_practices.md +806 -806
- package/skills/frontend/senior-frontend/references/nextjs_optimization_guide.md +724 -724
- package/skills/frontend/senior-frontend/references/react_patterns.md +746 -746
- package/skills/frontend/senior-frontend/scripts/bundle_analyzer.py +407 -407
- package/skills/frontend/senior-frontend/scripts/component_generator.py +329 -329
- package/skills/frontend/senior-frontend/scripts/frontend_scaffolder.py +1005 -1005
- package/skills/frontend/ui-ux-pro-max/SKILL.md +386 -386
- package/skills/frontend/ui-ux-pro-max/data/charts.csv +26 -26
- package/skills/frontend/ui-ux-pro-max/data/colors.csv +97 -97
- package/skills/frontend/ui-ux-pro-max/data/icons.csv +101 -101
- package/skills/frontend/ui-ux-pro-max/data/landing.csv +31 -31
- package/skills/frontend/ui-ux-pro-max/data/products.csv +96 -96
- package/skills/frontend/ui-ux-pro-max/data/react-performance.csv +45 -45
- package/skills/frontend/ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/skills/frontend/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/skills/frontend/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
- package/skills/frontend/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
- package/skills/frontend/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/skills/frontend/ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
- package/skills/frontend/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/skills/frontend/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/skills/frontend/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/skills/frontend/ui-ux-pro-max/data/styles.csv +68 -68
- package/skills/frontend/ui-ux-pro-max/data/typography.csv +57 -57
- package/skills/frontend/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
- package/skills/frontend/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/skills/frontend/ui-ux-pro-max/data/web-interface.csv +31 -31
- package/skills/frontend/ui-ux-pro-max/scripts/core.py +253 -253
- package/skills/frontend/ui-ux-pro-max/scripts/design_system.py +1067 -1067
- package/skills/frontend/ui-ux-pro-max/scripts/search.py +114 -114
- package/skills/frontend/vue-expert/SKILL.md +98 -98
- package/skills/frontend/vue-expert/references/build-tooling.md +480 -480
- package/skills/frontend/vue-expert/references/components.md +448 -448
- package/skills/frontend/vue-expert/references/composition-api.md +299 -299
- package/skills/frontend/vue-expert/references/mobile-hybrid.md +636 -636
- package/skills/frontend/vue-expert/references/nuxt.md +669 -669
- package/skills/frontend/vue-expert/references/state-management.md +449 -449
- package/skills/frontend/vue-expert/references/typescript.md +584 -584
- package/skills/frontend/vue-expert-js/SKILL.md +167 -167
- package/skills/frontend/vue-expert-js/references/component-architecture.md +219 -219
- package/skills/frontend/vue-expert-js/references/composables-patterns.md +183 -183
- package/skills/frontend/vue-expert-js/references/jsdoc-typing.md +535 -535
- package/skills/frontend/vue-expert-js/references/state-management.md +249 -249
- package/skills/frontend/vue-expert-js/references/testing-patterns.md +237 -237
- package/skills/go-rust-cpp/cpp-pro/SKILL.md +115 -115
- package/skills/go-rust-cpp/cpp-pro/references/build-tooling.md +440 -440
- package/skills/go-rust-cpp/cpp-pro/references/concurrency.md +437 -437
- package/skills/go-rust-cpp/cpp-pro/references/memory-performance.md +397 -397
- package/skills/go-rust-cpp/cpp-pro/references/modern-cpp.md +304 -304
- package/skills/go-rust-cpp/cpp-pro/references/templates.md +357 -357
- package/skills/go-rust-cpp/golang-pro/SKILL.md +122 -122
- package/skills/go-rust-cpp/golang-pro/references/concurrency.md +329 -329
- package/skills/go-rust-cpp/golang-pro/references/generics.md +442 -442
- package/skills/go-rust-cpp/golang-pro/references/interfaces.md +432 -432
- package/skills/go-rust-cpp/golang-pro/references/project-structure.md +477 -477
- package/skills/go-rust-cpp/golang-pro/references/testing.md +451 -451
- package/skills/go-rust-cpp/rust-engineer/SKILL.md +167 -167
- package/skills/go-rust-cpp/rust-engineer/references/async.md +458 -458
- package/skills/go-rust-cpp/rust-engineer/references/error-handling.md +334 -334
- package/skills/go-rust-cpp/rust-engineer/references/ownership.md +278 -278
- package/skills/go-rust-cpp/rust-engineer/references/testing.md +470 -470
- package/skills/go-rust-cpp/rust-engineer/references/traits.md +413 -413
- package/skills/infra/cli-developer/SKILL.md +113 -113
- package/skills/infra/cli-developer/references/design-patterns.md +221 -221
- package/skills/infra/cli-developer/references/go-cli.md +540 -540
- package/skills/infra/cli-developer/references/node-cli.md +383 -383
- package/skills/infra/cli-developer/references/python-cli.md +422 -422
- package/skills/infra/cli-developer/references/ux-patterns.md +448 -448
- package/skills/infra/cloud-architect/SKILL.md +216 -216
- package/skills/infra/cloud-architect/references/aws.md +394 -394
- package/skills/infra/cloud-architect/references/azure.md +562 -562
- package/skills/infra/cloud-architect/references/cost.md +582 -582
- package/skills/infra/cloud-architect/references/gcp.md +633 -633
- package/skills/infra/cloud-architect/references/multi-cloud.md +483 -483
- package/skills/infra/devops-engineer/SKILL.md +144 -144
- package/skills/infra/devops-engineer/references/deployment-strategies.md +241 -241
- package/skills/infra/devops-engineer/references/docker-patterns.md +113 -113
- package/skills/infra/devops-engineer/references/github-actions.md +139 -139
- package/skills/infra/devops-engineer/references/incident-response.md +331 -331
- package/skills/infra/devops-engineer/references/kubernetes.md +154 -154
- package/skills/infra/devops-engineer/references/platform-engineering.md +417 -417
- package/skills/infra/devops-engineer/references/release-automation.md +527 -527
- package/skills/infra/devops-engineer/references/terraform-iac.md +141 -141
- package/skills/infra/kubernetes-specialist/SKILL.md +241 -241
- package/skills/infra/kubernetes-specialist/references/configuration.md +452 -452
- package/skills/infra/kubernetes-specialist/references/cost-optimization.md +458 -458
- package/skills/infra/kubernetes-specialist/references/custom-operators.md +563 -563
- package/skills/infra/kubernetes-specialist/references/gitops.md +530 -530
- package/skills/infra/kubernetes-specialist/references/helm-charts.md +912 -912
- package/skills/infra/kubernetes-specialist/references/multi-cluster.md +507 -507
- package/skills/infra/kubernetes-specialist/references/networking.md +447 -447
- package/skills/infra/kubernetes-specialist/references/service-mesh.md +459 -459
- package/skills/infra/kubernetes-specialist/references/storage.md +535 -535
- package/skills/infra/kubernetes-specialist/references/troubleshooting.md +414 -414
- package/skills/infra/kubernetes-specialist/references/workloads.md +377 -377
- package/skills/infra/mcp-developer/SKILL.md +143 -143
- package/skills/infra/mcp-developer/references/protocol.md +244 -244
- package/skills/infra/mcp-developer/references/python-sdk.md +367 -367
- package/skills/infra/mcp-developer/references/resources.md +554 -554
- package/skills/infra/mcp-developer/references/tools.md +480 -480
- package/skills/infra/mcp-developer/references/typescript-sdk.md +350 -350
- package/skills/infra/monitoring-expert/SKILL.md +176 -176
- package/skills/infra/monitoring-expert/references/alerting-rules.md +141 -141
- package/skills/infra/monitoring-expert/references/application-profiling.md +331 -331
- package/skills/infra/monitoring-expert/references/capacity-planning.md +344 -344
- package/skills/infra/monitoring-expert/references/dashboards.md +126 -126
- package/skills/infra/monitoring-expert/references/opentelemetry.md +123 -123
- package/skills/infra/monitoring-expert/references/performance-testing.md +269 -269
- package/skills/infra/monitoring-expert/references/prometheus-metrics.md +136 -136
- package/skills/infra/monitoring-expert/references/structured-logging.md +142 -142
- package/skills/infra/sre-engineer/SKILL.md +181 -181
- package/skills/infra/sre-engineer/references/automation-toil.md +492 -492
- package/skills/infra/sre-engineer/references/error-budget-policy.md +334 -334
- package/skills/infra/sre-engineer/references/incident-chaos.md +576 -576
- package/skills/infra/sre-engineer/references/monitoring-alerting.md +424 -424
- package/skills/infra/sre-engineer/references/slo-sli-management.md +238 -238
- package/skills/infra/terraform-engineer/SKILL.md +143 -143
- package/skills/infra/terraform-engineer/references/best-practices.md +583 -583
- package/skills/infra/terraform-engineer/references/module-patterns.md +297 -297
- package/skills/infra/terraform-engineer/references/providers.md +452 -452
- package/skills/infra/terraform-engineer/references/state-management.md +371 -371
- package/skills/infra/terraform-engineer/references/testing.md +486 -486
- package/skills/infra/websocket-engineer/SKILL.md +168 -168
- package/skills/infra/websocket-engineer/references/alternatives.md +391 -391
- package/skills/infra/websocket-engineer/references/patterns.md +400 -400
- package/skills/infra/websocket-engineer/references/protocol.md +195 -195
- package/skills/infra/websocket-engineer/references/scaling.md +333 -333
- package/skills/infra/websocket-engineer/references/security.md +474 -474
- package/skills/java/java-architect/SKILL.md +132 -132
- package/skills/java/java-architect/references/jpa-optimization.md +393 -393
- package/skills/java/java-architect/references/reactive-webflux.md +356 -356
- package/skills/java/java-architect/references/spring-boot-setup.md +269 -269
- package/skills/java/java-architect/references/spring-security.md +445 -445
- package/skills/java/java-architect/references/testing-patterns.md +500 -500
- package/skills/java/kotlin-specialist/SKILL.md +147 -147
- package/skills/java/kotlin-specialist/references/android-compose.md +419 -419
- package/skills/java/kotlin-specialist/references/coroutines-flow.md +276 -276
- package/skills/java/kotlin-specialist/references/dsl-idioms.md +421 -421
- package/skills/java/kotlin-specialist/references/ktor-server.md +426 -426
- package/skills/java/kotlin-specialist/references/multiplatform-kmp.md +380 -380
- package/skills/java/spring-boot-engineer/SKILL.md +195 -195
- package/skills/java/spring-boot-engineer/references/cloud.md +498 -498
- package/skills/java/spring-boot-engineer/references/data.md +381 -381
- package/skills/java/spring-boot-engineer/references/security.md +459 -459
- package/skills/java/spring-boot-engineer/references/testing.md +545 -545
- package/skills/java/spring-boot-engineer/references/web.md +295 -295
- package/skills/javascript/javascript-pro/SKILL.md +132 -132
- package/skills/javascript/javascript-pro/references/async-patterns.md +334 -334
- package/skills/javascript/javascript-pro/references/browser-apis.md +398 -398
- package/skills/javascript/javascript-pro/references/modern-syntax.md +272 -272
- package/skills/javascript/javascript-pro/references/modules.md +357 -357
- package/skills/javascript/javascript-pro/references/node-essentials.md +471 -471
- package/skills/javascript/nestjs-expert/SKILL.md +206 -206
- package/skills/javascript/nestjs-expert/references/authentication.md +166 -166
- package/skills/javascript/nestjs-expert/references/controllers-routing.md +111 -111
- package/skills/javascript/nestjs-expert/references/dtos-validation.md +153 -153
- package/skills/javascript/nestjs-expert/references/migration-from-express.md +1237 -1237
- package/skills/javascript/nestjs-expert/references/services-di.md +140 -140
- package/skills/javascript/nestjs-expert/references/testing-patterns.md +186 -186
- package/skills/javascript/typescript-pro/SKILL.md +145 -145
- package/skills/javascript/typescript-pro/references/advanced-types.md +259 -259
- package/skills/javascript/typescript-pro/references/configuration.md +445 -445
- package/skills/javascript/typescript-pro/references/patterns.md +484 -484
- package/skills/javascript/typescript-pro/references/type-guards.md +352 -352
- package/skills/javascript/typescript-pro/references/utility-types.md +329 -329
- package/skills/php/laravel-specialist/SKILL.md +262 -262
- package/skills/php/laravel-specialist/references/eloquent.md +351 -351
- package/skills/php/laravel-specialist/references/livewire.md +512 -512
- package/skills/php/laravel-specialist/references/queues.md +423 -423
- package/skills/php/laravel-specialist/references/routing.md +362 -362
- package/skills/php/laravel-specialist/references/testing.md +522 -522
- package/skills/php/php-pro/SKILL.md +206 -206
- package/skills/php/php-pro/references/async-patterns.md +412 -412
- package/skills/php/php-pro/references/laravel-patterns.md +377 -377
- package/skills/php/php-pro/references/modern-php-features.md +323 -323
- package/skills/php/php-pro/references/symfony-patterns.md +466 -466
- package/skills/php/php-pro/references/testing-quality.md +466 -466
- package/skills/product/competitive-analysis/SKILL.md +257 -257
- package/skills/product/meeting-notes/SKILL.md +266 -266
- package/skills/product/prd-template/SKILL.md +150 -150
- package/skills/product/stakeholder-update/SKILL.md +225 -225
- package/skills/product/user-research-synthesis/SKILL.md +235 -235
- package/skills/python/django-expert/SKILL.md +162 -162
- package/skills/python/django-expert/references/authentication.md +145 -145
- package/skills/python/django-expert/references/drf-serializers.md +148 -148
- package/skills/python/django-expert/references/models-orm.md +151 -151
- package/skills/python/django-expert/references/testing-django.md +204 -204
- package/skills/python/django-expert/references/viewsets-views.md +153 -153
- package/skills/python/fastapi-expert/SKILL.md +185 -185
- package/skills/python/fastapi-expert/references/async-sqlalchemy.md +146 -146
- package/skills/python/fastapi-expert/references/authentication.md +159 -159
- package/skills/python/fastapi-expert/references/endpoints-routing.md +142 -142
- package/skills/python/fastapi-expert/references/migration-from-django.md +996 -996
- package/skills/python/fastapi-expert/references/pydantic-v2.md +135 -135
- package/skills/python/fastapi-expert/references/testing-async.md +159 -159
- package/skills/python/pandas-pro/SKILL.md +178 -178
- package/skills/python/pandas-pro/references/aggregation-groupby.md +545 -545
- package/skills/python/pandas-pro/references/data-cleaning.md +500 -500
- package/skills/python/pandas-pro/references/dataframe-operations.md +420 -420
- package/skills/python/pandas-pro/references/merging-joining.md +596 -596
- package/skills/python/pandas-pro/references/performance-optimization.md +597 -597
- package/skills/python/python-pro/SKILL.md +177 -177
- package/skills/python/python-pro/references/async-patterns.md +356 -356
- package/skills/python/python-pro/references/packaging.md +460 -460
- package/skills/python/python-pro/references/standard-library.md +378 -378
- package/skills/python/python-pro/references/testing.md +404 -404
- package/skills/python/python-pro/references/type-system.md +290 -290
- package/skills/quality/chaos-engineer/SKILL.md +182 -182
- package/skills/quality/chaos-engineer/references/chaos-tools.md +511 -511
- package/skills/quality/chaos-engineer/references/experiment-design.md +229 -229
- package/skills/quality/chaos-engineer/references/game-days.md +434 -434
- package/skills/quality/chaos-engineer/references/infrastructure-chaos.md +348 -348
- package/skills/quality/chaos-engineer/references/kubernetes-chaos.md +432 -432
- package/skills/quality/code-reviewer/SKILL.md +119 -119
- package/skills/quality/code-reviewer/references/common-issues.md +142 -142
- package/skills/quality/code-reviewer/references/feedback-examples.md +144 -144
- package/skills/quality/code-reviewer/references/receiving-feedback.md +238 -238
- package/skills/quality/code-reviewer/references/report-template.md +109 -109
- package/skills/quality/code-reviewer/references/review-checklist.md +88 -88
- package/skills/quality/code-reviewer/references/spec-compliance-review.md +258 -258
- package/skills/quality/playwright-expert/SKILL.md +169 -169
- package/skills/quality/playwright-expert/references/api-mocking.md +140 -140
- package/skills/quality/playwright-expert/references/configuration.md +155 -155
- package/skills/quality/playwright-expert/references/debugging-flaky.md +150 -150
- package/skills/quality/playwright-expert/references/page-object-model.md +152 -152
- package/skills/quality/playwright-expert/references/selectors-locators.md +119 -119
- package/skills/quality/secure-code-guardian/SKILL.md +191 -191
- package/skills/quality/secure-code-guardian/references/authentication.md +136 -136
- package/skills/quality/secure-code-guardian/references/input-validation.md +146 -146
- package/skills/quality/secure-code-guardian/references/owasp-prevention.md +135 -135
- package/skills/quality/secure-code-guardian/references/security-headers.md +133 -133
- package/skills/quality/secure-code-guardian/references/xss-csrf.md +157 -157
- package/skills/quality/security-reviewer/SKILL.md +103 -103
- package/skills/quality/security-reviewer/references/infrastructure-security.md +268 -268
- package/skills/quality/security-reviewer/references/penetration-testing.md +268 -268
- package/skills/quality/security-reviewer/references/report-template.md +170 -170
- package/skills/quality/security-reviewer/references/sast-tools.md +117 -117
- package/skills/quality/security-reviewer/references/secret-scanning.md +125 -125
- package/skills/quality/security-reviewer/references/vulnerability-patterns.md +152 -152
- package/skills/quality/senior-qa/README.md +196 -196
- package/skills/quality/senior-qa/SKILL.md +399 -399
- package/skills/quality/senior-qa/references/qa_best_practices.md +964 -964
- package/skills/quality/senior-qa/references/test_automation_patterns.md +1009 -1009
- package/skills/quality/senior-qa/references/testing_strategies.md +649 -649
- package/skills/quality/senior-qa/scripts/coverage_analyzer.py +836 -836
- package/skills/quality/senior-qa/scripts/e2e_test_scaffolder.py +820 -820
- package/skills/quality/senior-qa/scripts/test_suite_generator.py +605 -605
- package/skills/quality/tdd-guide/HOW_TO_USE.md +313 -313
- package/skills/quality/tdd-guide/README.md +680 -680
- package/skills/quality/tdd-guide/SKILL.md +122 -122
- package/skills/quality/tdd-guide/assets/expected_output.json +77 -77
- package/skills/quality/tdd-guide/assets/sample_input_python.json +39 -39
- package/skills/quality/tdd-guide/assets/sample_input_typescript.json +36 -36
- package/skills/quality/tdd-guide/references/ci-integration.md +195 -195
- package/skills/quality/tdd-guide/references/framework-guide.md +206 -206
- package/skills/quality/tdd-guide/references/tdd-best-practices.md +128 -128
- package/skills/quality/tdd-guide/scripts/coverage_analyzer.py +434 -434
- package/skills/quality/tdd-guide/scripts/fixture_generator.py +440 -440
- package/skills/quality/tdd-guide/scripts/format_detector.py +384 -384
- package/skills/quality/tdd-guide/scripts/framework_adapter.py +428 -428
- package/skills/quality/tdd-guide/scripts/metrics_calculator.py +456 -456
- package/skills/quality/tdd-guide/scripts/output_formatter.py +354 -354
- package/skills/quality/tdd-guide/scripts/tdd_workflow.py +474 -474
- package/skills/quality/tdd-guide/scripts/test_generator.py +438 -438
- package/skills/quality/test-master/SKILL.md +94 -94
- package/skills/quality/test-master/references/automation-frameworks.md +294 -294
- package/skills/quality/test-master/references/e2e-testing.md +128 -128
- package/skills/quality/test-master/references/integration-testing.md +120 -120
- package/skills/quality/test-master/references/performance-testing.md +118 -118
- package/skills/quality/test-master/references/qa-methodology.md +247 -247
- package/skills/quality/test-master/references/security-testing.md +127 -127
- package/skills/quality/test-master/references/tdd-iron-laws.md +174 -174
- package/skills/quality/test-master/references/test-reports.md +104 -104
- package/skills/quality/test-master/references/testing-anti-patterns.md +231 -231
- package/skills/quality/test-master/references/unit-testing.md +113 -113
- package/skills/ruby/rails-expert/SKILL.md +154 -154
- package/skills/ruby/rails-expert/references/active-record.md +244 -244
- package/skills/ruby/rails-expert/references/api-development.md +401 -401
- package/skills/ruby/rails-expert/references/background-jobs.md +272 -272
- package/skills/ruby/rails-expert/references/hotwire-turbo.md +228 -228
- package/skills/ruby/rails-expert/references/rspec-testing.md +367 -367
- package/skills/swift/swift-expert/SKILL.md +163 -163
- package/skills/swift/swift-expert/references/async-concurrency.md +360 -360
- package/skills/swift/swift-expert/references/memory-performance.md +377 -377
- package/skills/swift/swift-expert/references/protocol-oriented.md +354 -354
- package/skills/swift/swift-expert/references/swiftui-patterns.md +291 -291
- package/skills/swift/swift-expert/references/testing-patterns.md +399 -399
- package/skills/workflow/brainstorming/SKILL.md +164 -164
- package/skills/workflow/brainstorming/scripts/frame-template.html +214 -214
- package/skills/workflow/brainstorming/scripts/helper.js +88 -88
- package/skills/workflow/brainstorming/scripts/server.cjs +354 -354
- package/skills/workflow/brainstorming/scripts/start-server.sh +148 -148
- package/skills/workflow/brainstorming/scripts/stop-server.sh +56 -56
- package/skills/workflow/brainstorming/spec-document-reviewer-prompt.md +49 -49
- package/skills/workflow/brainstorming/visual-companion.md +287 -287
- package/skills/workflow/documentation/SKILL.md +45 -45
- package/skills/workflow/entropy-management/SKILL.md +115 -115
- package/skills/workflow/executing-plans/SKILL.md +70 -70
- package/skills/workflow/finishing-a-development-branch/SKILL.md +200 -200
- package/skills/workflow/receiving-code-review/SKILL.md +213 -213
- package/skills/workflow/requesting-code-review/SKILL.md +105 -105
- package/skills/workflow/requesting-code-review/code-reviewer.md +146 -146
- package/skills/workflow/requirement-engineering/SKILL.md +111 -111
- package/skills/workflow/systematic-debugging/CREATION-LOG.md +119 -119
- package/skills/workflow/systematic-debugging/SKILL.md +296 -296
- package/skills/workflow/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/skills/workflow/systematic-debugging/condition-based-waiting.md +115 -115
- package/skills/workflow/systematic-debugging/defense-in-depth.md +122 -122
- package/skills/workflow/systematic-debugging/find-polluter.sh +63 -63
- package/skills/workflow/systematic-debugging/root-cause-tracing.md +169 -169
- package/skills/workflow/systematic-debugging/test-academic.md +14 -14
- package/skills/workflow/systematic-debugging/test-pressure-1.md +58 -58
- package/skills/workflow/systematic-debugging/test-pressure-2.md +68 -68
- package/skills/workflow/systematic-debugging/test-pressure-3.md +69 -69
- package/skills/workflow/using-git-worktrees/SKILL.md +218 -218
- package/skills/workflow/verification-before-completion/SKILL.md +139 -139
- package/skills/workflow/writing-plans/SKILL.md +151 -151
- package/skills/workflow/writing-plans/plan-document-reviewer-prompt.md +49 -49
- package/skills/workflow/writing-skills/SKILL.md +655 -655
- package/skills/workflow/writing-skills/anthropic-best-practices.md +1150 -1150
- package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -189
- package/skills/workflow/writing-skills/persuasion-principles.md +187 -187
- package/skills/workflow/writing-skills/render-graphs.js +168 -168
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +384 -384
|
@@ -1,649 +1,649 @@
|
|
|
1
|
-
# Testing Strategies for React and Next.js Applications
|
|
2
|
-
|
|
3
|
-
Comprehensive guide to test architecture, coverage targets, and CI/CD integration patterns.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
|
|
9
|
-
- [The Testing Pyramid](#the-testing-pyramid)
|
|
10
|
-
- [Testing Types Deep Dive](#testing-types-deep-dive)
|
|
11
|
-
- [Coverage Targets and Thresholds](#coverage-targets-and-thresholds)
|
|
12
|
-
- [Test Organization Patterns](#test-organization-patterns)
|
|
13
|
-
- [CI/CD Integration Strategies](#cicd-integration-strategies)
|
|
14
|
-
- [Testing Decision Framework](#testing-decision-framework)
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## The Testing Pyramid
|
|
19
|
-
|
|
20
|
-
The testing pyramid guides how to distribute testing effort across different test types for optimal ROI.
|
|
21
|
-
|
|
22
|
-
### Classic Pyramid Structure
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
/\
|
|
26
|
-
/ \ E2E Tests (5-10%)
|
|
27
|
-
/----\ - User journey validation
|
|
28
|
-
/ \ - Critical path coverage
|
|
29
|
-
/--------\ Integration Tests (20-30%)
|
|
30
|
-
/ \ - Component interactions
|
|
31
|
-
/ \ - API integration
|
|
32
|
-
/--------------\ Unit Tests (60-70%)
|
|
33
|
-
/ \ - Individual functions
|
|
34
|
-
------------------ - Isolated components
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### React/Next.js Adapted Pyramid
|
|
38
|
-
|
|
39
|
-
For frontend applications, the pyramid shifts slightly:
|
|
40
|
-
|
|
41
|
-
| Level | Percentage | Tools | Focus |
|
|
42
|
-
|-------|------------|-------|-------|
|
|
43
|
-
| Unit | 50-60% | Jest, RTL | Pure functions, hooks, isolated components |
|
|
44
|
-
| Integration | 25-35% | RTL, MSW | Component trees, API calls, context |
|
|
45
|
-
| E2E | 10-15% | Playwright | Critical user flows, cross-page navigation |
|
|
46
|
-
|
|
47
|
-
### Why This Distribution?
|
|
48
|
-
|
|
49
|
-
**Unit tests are fast and cheap:**
|
|
50
|
-
- Execute in milliseconds
|
|
51
|
-
- Pinpoint failures precisely
|
|
52
|
-
- Easy to maintain
|
|
53
|
-
- Run on every commit
|
|
54
|
-
|
|
55
|
-
**Integration tests balance coverage and cost:**
|
|
56
|
-
- Test realistic scenarios
|
|
57
|
-
- Catch component interaction bugs
|
|
58
|
-
- Moderate execution time
|
|
59
|
-
- Run on every PR
|
|
60
|
-
|
|
61
|
-
**E2E tests are expensive but essential:**
|
|
62
|
-
- Validate real user experience
|
|
63
|
-
- Catch deployment issues
|
|
64
|
-
- Slow and brittle
|
|
65
|
-
- Run on staging/production
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Testing Types Deep Dive
|
|
70
|
-
|
|
71
|
-
### Unit Testing
|
|
72
|
-
|
|
73
|
-
**Purpose:** Verify individual units of code work correctly in isolation.
|
|
74
|
-
|
|
75
|
-
**What to Unit Test:**
|
|
76
|
-
- Pure utility functions
|
|
77
|
-
- Custom hooks (with renderHook)
|
|
78
|
-
- Individual component rendering
|
|
79
|
-
- State reducers
|
|
80
|
-
- Validation logic
|
|
81
|
-
- Data transformers
|
|
82
|
-
|
|
83
|
-
**Example: Testing a Pure Function**
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
// utils/formatPrice.ts
|
|
87
|
-
export function formatPrice(cents: number, currency = 'USD'): string {
|
|
88
|
-
const formatter = new Intl.NumberFormat('en-US', {
|
|
89
|
-
style: 'currency',
|
|
90
|
-
currency,
|
|
91
|
-
});
|
|
92
|
-
return formatter.format(cents / 100);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// utils/formatPrice.test.ts
|
|
96
|
-
describe('formatPrice', () => {
|
|
97
|
-
it('formats cents to USD by default', () => {
|
|
98
|
-
expect(formatPrice(1999)).toBe('$19.99');
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('handles zero', () => {
|
|
102
|
-
expect(formatPrice(0)).toBe('$0.00');
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('supports different currencies', () => {
|
|
106
|
-
expect(formatPrice(1999, 'EUR')).toContain('€');
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('handles large numbers', () => {
|
|
110
|
-
expect(formatPrice(100000000)).toBe('$1,000,000.00');
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
**Example: Testing a Custom Hook**
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
// hooks/useCounter.ts
|
|
119
|
-
export function useCounter(initial = 0) {
|
|
120
|
-
const [count, setCount] = useState(initial);
|
|
121
|
-
const increment = () => setCount(c => c + 1);
|
|
122
|
-
const decrement = () => setCount(c => c - 1);
|
|
123
|
-
const reset = () => setCount(initial);
|
|
124
|
-
return { count, increment, decrement, reset };
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// hooks/useCounter.test.ts
|
|
128
|
-
import { renderHook, act } from '@testing-library/react';
|
|
129
|
-
import { useCounter } from './useCounter';
|
|
130
|
-
|
|
131
|
-
describe('useCounter', () => {
|
|
132
|
-
it('starts with initial value', () => {
|
|
133
|
-
const { result } = renderHook(() => useCounter(5));
|
|
134
|
-
expect(result.current.count).toBe(5);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('increments count', () => {
|
|
138
|
-
const { result } = renderHook(() => useCounter(0));
|
|
139
|
-
act(() => result.current.increment());
|
|
140
|
-
expect(result.current.count).toBe(1);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('decrements count', () => {
|
|
144
|
-
const { result } = renderHook(() => useCounter(5));
|
|
145
|
-
act(() => result.current.decrement());
|
|
146
|
-
expect(result.current.count).toBe(4);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('resets to initial value', () => {
|
|
150
|
-
const { result } = renderHook(() => useCounter(10));
|
|
151
|
-
act(() => result.current.increment());
|
|
152
|
-
act(() => result.current.reset());
|
|
153
|
-
expect(result.current.count).toBe(10);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Integration Testing
|
|
159
|
-
|
|
160
|
-
**Purpose:** Verify multiple units work together correctly.
|
|
161
|
-
|
|
162
|
-
**What to Integration Test:**
|
|
163
|
-
- Component trees with multiple children
|
|
164
|
-
- Components with context providers
|
|
165
|
-
- Form submission flows
|
|
166
|
-
- API call and response handling
|
|
167
|
-
- State management interactions
|
|
168
|
-
- Router-dependent components
|
|
169
|
-
|
|
170
|
-
**Example: Testing Component with API Call**
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
// components/UserProfile.tsx
|
|
174
|
-
export function UserProfile({ userId }: { userId: string }) {
|
|
175
|
-
const [user, setUser] = useState<User | null>(null);
|
|
176
|
-
const [loading, setLoading] = useState(true);
|
|
177
|
-
const [error, setError] = useState<string | null>(null);
|
|
178
|
-
|
|
179
|
-
useEffect(() => {
|
|
180
|
-
fetch(`/api/users/${userId}`)
|
|
181
|
-
.then(res => res.json())
|
|
182
|
-
.then(data => setUser(data))
|
|
183
|
-
.catch(err => setError(err.message))
|
|
184
|
-
.finally(() => setLoading(false));
|
|
185
|
-
}, [userId]);
|
|
186
|
-
|
|
187
|
-
if (loading) return <div>Loading...</div>;
|
|
188
|
-
if (error) return <div>Error: {error}</div>;
|
|
189
|
-
return <div>{user?.name}</div>;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// components/UserProfile.test.tsx
|
|
193
|
-
import { render, screen, waitFor } from '@testing-library/react';
|
|
194
|
-
import { rest } from 'msw';
|
|
195
|
-
import { setupServer } from 'msw/node';
|
|
196
|
-
import { UserProfile } from './UserProfile';
|
|
197
|
-
|
|
198
|
-
const server = setupServer(
|
|
199
|
-
rest.get('/api/users/:id', (req, res, ctx) => {
|
|
200
|
-
return res(ctx.json({ id: req.params.id, name: 'John Doe' }));
|
|
201
|
-
})
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
beforeAll(() => server.listen());
|
|
205
|
-
afterEach(() => server.resetHandlers());
|
|
206
|
-
afterAll(() => server.close());
|
|
207
|
-
|
|
208
|
-
describe('UserProfile', () => {
|
|
209
|
-
it('shows loading state initially', () => {
|
|
210
|
-
render(<UserProfile userId="123" />);
|
|
211
|
-
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('displays user name after loading', async () => {
|
|
215
|
-
render(<UserProfile userId="123" />);
|
|
216
|
-
await waitFor(() => {
|
|
217
|
-
expect(screen.getByText('John Doe')).toBeInTheDocument();
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('displays error on API failure', async () => {
|
|
222
|
-
server.use(
|
|
223
|
-
rest.get('/api/users/:id', (req, res, ctx) => {
|
|
224
|
-
return res(ctx.status(500));
|
|
225
|
-
})
|
|
226
|
-
);
|
|
227
|
-
render(<UserProfile userId="123" />);
|
|
228
|
-
await waitFor(() => {
|
|
229
|
-
expect(screen.getByText(/Error/)).toBeInTheDocument();
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### End-to-End Testing
|
|
236
|
-
|
|
237
|
-
**Purpose:** Verify complete user flows work in a real browser environment.
|
|
238
|
-
|
|
239
|
-
**What to E2E Test:**
|
|
240
|
-
- Critical business flows (checkout, signup, login)
|
|
241
|
-
- Cross-page navigation sequences
|
|
242
|
-
- Authentication flows
|
|
243
|
-
- Third-party integrations
|
|
244
|
-
- Payment processing
|
|
245
|
-
- Form wizards
|
|
246
|
-
|
|
247
|
-
**Example: Testing Checkout Flow**
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
// e2e/checkout.spec.ts
|
|
251
|
-
import { test, expect } from '@playwright/test';
|
|
252
|
-
|
|
253
|
-
test.describe('Checkout Flow', () => {
|
|
254
|
-
test.beforeEach(async ({ page }) => {
|
|
255
|
-
await page.goto('/');
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
test('completes purchase successfully', async ({ page }) => {
|
|
259
|
-
// Add product to cart
|
|
260
|
-
await page.goto('/products/widget-pro');
|
|
261
|
-
await page.getByRole('button', { name: 'Add to Cart' }).click();
|
|
262
|
-
|
|
263
|
-
// Verify cart updated
|
|
264
|
-
await expect(page.getByTestId('cart-count')).toHaveText('1');
|
|
265
|
-
|
|
266
|
-
// Go to checkout
|
|
267
|
-
await page.getByRole('link', { name: 'Checkout' }).click();
|
|
268
|
-
|
|
269
|
-
// Fill shipping info
|
|
270
|
-
await page.getByLabel('Email').fill('test@example.com');
|
|
271
|
-
await page.getByLabel('Address').fill('123 Test St');
|
|
272
|
-
await page.getByLabel('City').fill('Test City');
|
|
273
|
-
await page.getByLabel('Zip').fill('12345');
|
|
274
|
-
|
|
275
|
-
// Fill payment info (test card)
|
|
276
|
-
await page.getByLabel('Card Number').fill('4242424242424242');
|
|
277
|
-
await page.getByLabel('Expiry').fill('12/25');
|
|
278
|
-
await page.getByLabel('CVC').fill('123');
|
|
279
|
-
|
|
280
|
-
// Submit order
|
|
281
|
-
await page.getByRole('button', { name: 'Place Order' }).click();
|
|
282
|
-
|
|
283
|
-
// Verify confirmation
|
|
284
|
-
await expect(page).toHaveURL(/\/orders\/\w+/);
|
|
285
|
-
await expect(page.getByText('Order Confirmed')).toBeVisible();
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
test('shows validation errors for invalid input', async ({ page }) => {
|
|
289
|
-
await page.goto('/checkout');
|
|
290
|
-
await page.getByRole('button', { name: 'Place Order' }).click();
|
|
291
|
-
|
|
292
|
-
await expect(page.getByText('Email is required')).toBeVisible();
|
|
293
|
-
await expect(page.getByText('Address is required')).toBeVisible();
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Visual Regression Testing
|
|
299
|
-
|
|
300
|
-
**Purpose:** Catch unintended visual changes to UI components.
|
|
301
|
-
|
|
302
|
-
**Tools:** Playwright visual comparisons, Percy, Chromatic
|
|
303
|
-
|
|
304
|
-
**Example: Visual Snapshot Test**
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
// e2e/visual/components.spec.ts
|
|
308
|
-
import { test, expect } from '@playwright/test';
|
|
309
|
-
|
|
310
|
-
test.describe('Visual Regression', () => {
|
|
311
|
-
test('button variants render correctly', async ({ page }) => {
|
|
312
|
-
await page.goto('/storybook/button');
|
|
313
|
-
await expect(page).toHaveScreenshot('button-variants.png');
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
test('responsive header', async ({ page }) => {
|
|
317
|
-
// Desktop
|
|
318
|
-
await page.setViewportSize({ width: 1280, height: 720 });
|
|
319
|
-
await page.goto('/');
|
|
320
|
-
await expect(page.locator('header')).toHaveScreenshot('header-desktop.png');
|
|
321
|
-
|
|
322
|
-
// Mobile
|
|
323
|
-
await page.setViewportSize({ width: 375, height: 667 });
|
|
324
|
-
await expect(page.locator('header')).toHaveScreenshot('header-mobile.png');
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Accessibility Testing
|
|
330
|
-
|
|
331
|
-
**Purpose:** Ensure application is usable by people with disabilities.
|
|
332
|
-
|
|
333
|
-
**Tools:** jest-axe, @axe-core/playwright
|
|
334
|
-
|
|
335
|
-
**Example: Automated A11y Testing**
|
|
336
|
-
|
|
337
|
-
```typescript
|
|
338
|
-
// Unit/Integration level with jest-axe
|
|
339
|
-
import { render } from '@testing-library/react';
|
|
340
|
-
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
341
|
-
import { Button } from './Button';
|
|
342
|
-
|
|
343
|
-
expect.extend(toHaveNoViolations);
|
|
344
|
-
|
|
345
|
-
describe('Button accessibility', () => {
|
|
346
|
-
it('has no accessibility violations', async () => {
|
|
347
|
-
const { container } = render(<Button>Click me</Button>);
|
|
348
|
-
const results = await axe(container);
|
|
349
|
-
expect(results).toHaveNoViolations();
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
// E2E level with Playwright + Axe
|
|
354
|
-
import { test, expect } from '@playwright/test';
|
|
355
|
-
import AxeBuilder from '@axe-core/playwright';
|
|
356
|
-
|
|
357
|
-
test('homepage has no a11y violations', async ({ page }) => {
|
|
358
|
-
await page.goto('/');
|
|
359
|
-
const results = await new AxeBuilder({ page }).analyze();
|
|
360
|
-
expect(results.violations).toEqual([]);
|
|
361
|
-
});
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
## Coverage Targets and Thresholds
|
|
367
|
-
|
|
368
|
-
### Recommended Thresholds by Project Type
|
|
369
|
-
|
|
370
|
-
| Project Type | Statements | Branches | Functions | Lines |
|
|
371
|
-
|--------------|------------|----------|-----------|-------|
|
|
372
|
-
| Startup/MVP | 60% | 50% | 60% | 60% |
|
|
373
|
-
| Growing Product | 75% | 70% | 75% | 75% |
|
|
374
|
-
| Enterprise | 85% | 80% | 85% | 85% |
|
|
375
|
-
| Safety Critical | 95% | 90% | 95% | 95% |
|
|
376
|
-
|
|
377
|
-
### Coverage by Code Type
|
|
378
|
-
|
|
379
|
-
**High Coverage Priority (80%+):**
|
|
380
|
-
- Business logic
|
|
381
|
-
- State management
|
|
382
|
-
- API handlers
|
|
383
|
-
- Form validation
|
|
384
|
-
- Authentication/authorization
|
|
385
|
-
- Payment processing
|
|
386
|
-
|
|
387
|
-
**Medium Coverage Priority (60-80%):**
|
|
388
|
-
- UI components
|
|
389
|
-
- Utility functions
|
|
390
|
-
- Data transformers
|
|
391
|
-
- Custom hooks
|
|
392
|
-
|
|
393
|
-
**Lower Coverage Priority (40-60%):**
|
|
394
|
-
- Static pages
|
|
395
|
-
- Simple wrappers
|
|
396
|
-
- Configuration files
|
|
397
|
-
- Types/interfaces
|
|
398
|
-
|
|
399
|
-
### Jest Coverage Configuration
|
|
400
|
-
|
|
401
|
-
```javascript
|
|
402
|
-
// jest.config.js
|
|
403
|
-
module.exports = {
|
|
404
|
-
collectCoverageFrom: [
|
|
405
|
-
'src/**/*.{ts,tsx}',
|
|
406
|
-
'!src/**/*.d.ts',
|
|
407
|
-
'!src/**/*.stories.{ts,tsx}',
|
|
408
|
-
'!src/**/index.{ts,tsx}', // barrel files
|
|
409
|
-
'!src/types/**',
|
|
410
|
-
],
|
|
411
|
-
coverageThreshold: {
|
|
412
|
-
global: {
|
|
413
|
-
statements: 80,
|
|
414
|
-
branches: 75,
|
|
415
|
-
functions: 80,
|
|
416
|
-
lines: 80,
|
|
417
|
-
},
|
|
418
|
-
// Higher thresholds for critical paths
|
|
419
|
-
'./src/services/payment/': {
|
|
420
|
-
statements: 95,
|
|
421
|
-
branches: 90,
|
|
422
|
-
functions: 95,
|
|
423
|
-
lines: 95,
|
|
424
|
-
},
|
|
425
|
-
'./src/services/auth/': {
|
|
426
|
-
statements: 90,
|
|
427
|
-
branches: 85,
|
|
428
|
-
functions: 90,
|
|
429
|
-
lines: 90,
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
|
-
coverageReporters: ['text', 'lcov', 'html', 'json'],
|
|
433
|
-
};
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
---
|
|
437
|
-
|
|
438
|
-
## Test Organization Patterns
|
|
439
|
-
|
|
440
|
-
### Co-located Tests (Recommended for React)
|
|
441
|
-
|
|
442
|
-
```
|
|
443
|
-
src/
|
|
444
|
-
├── components/
|
|
445
|
-
│ ├── Button/
|
|
446
|
-
│ │ ├── Button.tsx
|
|
447
|
-
│ │ ├── Button.test.tsx # Unit tests
|
|
448
|
-
│ │ ├── Button.stories.tsx # Storybook
|
|
449
|
-
│ │ └── index.ts
|
|
450
|
-
│ └── Form/
|
|
451
|
-
│ ├── Form.tsx
|
|
452
|
-
│ ├── Form.test.tsx
|
|
453
|
-
│ └── Form.integration.test.tsx # Integration tests
|
|
454
|
-
├── hooks/
|
|
455
|
-
│ ├── useAuth.ts
|
|
456
|
-
│ └── useAuth.test.ts
|
|
457
|
-
└── utils/
|
|
458
|
-
├── formatters.ts
|
|
459
|
-
└── formatters.test.ts
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
### Separate Test Directory
|
|
463
|
-
|
|
464
|
-
```
|
|
465
|
-
src/
|
|
466
|
-
├── components/
|
|
467
|
-
├── hooks/
|
|
468
|
-
└── utils/
|
|
469
|
-
|
|
470
|
-
__tests__/
|
|
471
|
-
├── unit/
|
|
472
|
-
│ ├── components/
|
|
473
|
-
│ ├── hooks/
|
|
474
|
-
│ └── utils/
|
|
475
|
-
├── integration/
|
|
476
|
-
│ └── flows/
|
|
477
|
-
└── fixtures/
|
|
478
|
-
├── users.json
|
|
479
|
-
└── products.json
|
|
480
|
-
|
|
481
|
-
e2e/
|
|
482
|
-
├── specs/
|
|
483
|
-
│ ├── auth.spec.ts
|
|
484
|
-
│ └── checkout.spec.ts
|
|
485
|
-
├── fixtures/
|
|
486
|
-
│ └── auth.ts
|
|
487
|
-
└── pages/ # Page Object Models
|
|
488
|
-
├── LoginPage.ts
|
|
489
|
-
└── CheckoutPage.ts
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
### Test File Naming Conventions
|
|
493
|
-
|
|
494
|
-
| Pattern | Use Case |
|
|
495
|
-
|---------|----------|
|
|
496
|
-
| `*.test.ts` | Unit tests |
|
|
497
|
-
| `*.spec.ts` | Integration/E2E tests |
|
|
498
|
-
| `*.integration.test.ts` | Explicit integration tests |
|
|
499
|
-
| `*.e2e.spec.ts` | Explicit E2E tests |
|
|
500
|
-
| `*.a11y.test.ts` | Accessibility tests |
|
|
501
|
-
| `*.visual.spec.ts` | Visual regression tests |
|
|
502
|
-
|
|
503
|
-
---
|
|
504
|
-
|
|
505
|
-
## CI/CD Integration Strategies
|
|
506
|
-
|
|
507
|
-
### Pipeline Stages
|
|
508
|
-
|
|
509
|
-
```yaml
|
|
510
|
-
# .github/workflows/test.yml
|
|
511
|
-
name: Test Pipeline
|
|
512
|
-
|
|
513
|
-
on:
|
|
514
|
-
push:
|
|
515
|
-
branches: [main, dev]
|
|
516
|
-
pull_request:
|
|
517
|
-
branches: [main, dev]
|
|
518
|
-
|
|
519
|
-
jobs:
|
|
520
|
-
unit:
|
|
521
|
-
name: Unit Tests
|
|
522
|
-
runs-on: ubuntu-latest
|
|
523
|
-
steps:
|
|
524
|
-
- uses: actions/checkout@v4
|
|
525
|
-
- uses: actions/setup-node@v4
|
|
526
|
-
with:
|
|
527
|
-
node-version: 20
|
|
528
|
-
cache: 'npm'
|
|
529
|
-
- run: npm ci
|
|
530
|
-
- run: npm run test:unit -- --coverage
|
|
531
|
-
- uses: codecov/codecov-action@v4
|
|
532
|
-
with:
|
|
533
|
-
files: coverage/lcov.info
|
|
534
|
-
fail_ci_if_error: true
|
|
535
|
-
|
|
536
|
-
integration:
|
|
537
|
-
name: Integration Tests
|
|
538
|
-
runs-on: ubuntu-latest
|
|
539
|
-
needs: unit
|
|
540
|
-
steps:
|
|
541
|
-
- uses: actions/checkout@v4
|
|
542
|
-
- uses: actions/setup-node@v4
|
|
543
|
-
with:
|
|
544
|
-
node-version: 20
|
|
545
|
-
cache: 'npm'
|
|
546
|
-
- run: npm ci
|
|
547
|
-
- run: npm run test:integration
|
|
548
|
-
|
|
549
|
-
e2e:
|
|
550
|
-
name: E2E Tests
|
|
551
|
-
runs-on: ubuntu-latest
|
|
552
|
-
needs: integration
|
|
553
|
-
steps:
|
|
554
|
-
- uses: actions/checkout@v4
|
|
555
|
-
- uses: actions/setup-node@v4
|
|
556
|
-
with:
|
|
557
|
-
node-version: 20
|
|
558
|
-
cache: 'npm'
|
|
559
|
-
- run: npm ci
|
|
560
|
-
- run: npx playwright install --with-deps
|
|
561
|
-
- run: npm run build
|
|
562
|
-
- run: npm run test:e2e
|
|
563
|
-
- uses: actions/upload-artifact@v4
|
|
564
|
-
if: failure()
|
|
565
|
-
with:
|
|
566
|
-
name: playwright-report
|
|
567
|
-
path: playwright-report/
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
### Test Splitting for Speed
|
|
571
|
-
|
|
572
|
-
```yaml
|
|
573
|
-
# Run E2E tests in parallel across multiple machines
|
|
574
|
-
e2e:
|
|
575
|
-
strategy:
|
|
576
|
-
matrix:
|
|
577
|
-
shard: [1, 2, 3, 4]
|
|
578
|
-
steps:
|
|
579
|
-
- run: npx playwright test --shard=${{ matrix.shard }}/4
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
### PR Gating Rules
|
|
583
|
-
|
|
584
|
-
| Test Type | When to Run | Block Merge? |
|
|
585
|
-
|-----------|-------------|--------------|
|
|
586
|
-
| Unit | Every commit | Yes |
|
|
587
|
-
| Integration | Every PR | Yes |
|
|
588
|
-
| E2E (smoke) | Every PR | Yes |
|
|
589
|
-
| E2E (full) | Merge to main | No (alert only) |
|
|
590
|
-
| Visual | Every PR | No (review required) |
|
|
591
|
-
| Performance | Weekly/Release | No (alert only) |
|
|
592
|
-
|
|
593
|
-
---
|
|
594
|
-
|
|
595
|
-
## Testing Decision Framework
|
|
596
|
-
|
|
597
|
-
### When to Write Which Test
|
|
598
|
-
|
|
599
|
-
```
|
|
600
|
-
Is it a pure function with no side effects?
|
|
601
|
-
├── Yes → Unit test
|
|
602
|
-
└── No
|
|
603
|
-
├── Does it make API calls or use context?
|
|
604
|
-
│ ├── Yes → Integration test with mocking
|
|
605
|
-
│ └── No
|
|
606
|
-
│ ├── Is it a critical user flow?
|
|
607
|
-
│ │ ├── Yes → E2E test
|
|
608
|
-
│ │ └── No → Integration test
|
|
609
|
-
└── Is it UI-focused with many visual states?
|
|
610
|
-
├── Yes → Storybook + Visual test
|
|
611
|
-
└── No → Component unit test
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
### Test ROI Matrix
|
|
615
|
-
|
|
616
|
-
| Test Type | Write Time | Run Time | Maintenance | Confidence |
|
|
617
|
-
|-----------|------------|----------|-------------|------------|
|
|
618
|
-
| Unit | Low | Very Fast | Low | Medium |
|
|
619
|
-
| Integration | Medium | Fast | Medium | High |
|
|
620
|
-
| E2E | High | Slow | High | Very High |
|
|
621
|
-
| Visual | Low | Medium | Medium | High (UI) |
|
|
622
|
-
|
|
623
|
-
### When NOT to Test
|
|
624
|
-
|
|
625
|
-
- Generated code (GraphQL types, Prisma client)
|
|
626
|
-
- Third-party library internals
|
|
627
|
-
- Implementation details (internal state, private methods)
|
|
628
|
-
- Simple pass-through wrappers
|
|
629
|
-
- Type definitions
|
|
630
|
-
|
|
631
|
-
### Red Flags in Testing Strategy
|
|
632
|
-
|
|
633
|
-
| Red Flag | Problem | Solution |
|
|
634
|
-
|----------|---------|----------|
|
|
635
|
-
| E2E tests > 30% | Slow CI, flaky tests | Push logic down to integration |
|
|
636
|
-
| Only unit tests | Missing interaction bugs | Add integration tests |
|
|
637
|
-
| Testing mocks | Not testing real behavior | Test behavior, not implementation |
|
|
638
|
-
| 100% coverage goal | Diminishing returns | Focus on critical paths |
|
|
639
|
-
| No E2E tests | Missing deployment issues | Add smoke tests for critical flows |
|
|
640
|
-
|
|
641
|
-
---
|
|
642
|
-
|
|
643
|
-
## Summary
|
|
644
|
-
|
|
645
|
-
1. **Follow the pyramid:** 60% unit, 30% integration, 10% E2E
|
|
646
|
-
2. **Set thresholds by risk:** Higher coverage for critical paths
|
|
647
|
-
3. **Co-locate tests:** Keep tests close to source code
|
|
648
|
-
4. **Automate in CI:** Run tests on every PR, gate merges on failure
|
|
649
|
-
5. **Decide wisely:** Not everything needs every type of test
|
|
1
|
+
# Testing Strategies for React and Next.js Applications
|
|
2
|
+
|
|
3
|
+
Comprehensive guide to test architecture, coverage targets, and CI/CD integration patterns.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [The Testing Pyramid](#the-testing-pyramid)
|
|
10
|
+
- [Testing Types Deep Dive](#testing-types-deep-dive)
|
|
11
|
+
- [Coverage Targets and Thresholds](#coverage-targets-and-thresholds)
|
|
12
|
+
- [Test Organization Patterns](#test-organization-patterns)
|
|
13
|
+
- [CI/CD Integration Strategies](#cicd-integration-strategies)
|
|
14
|
+
- [Testing Decision Framework](#testing-decision-framework)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## The Testing Pyramid
|
|
19
|
+
|
|
20
|
+
The testing pyramid guides how to distribute testing effort across different test types for optimal ROI.
|
|
21
|
+
|
|
22
|
+
### Classic Pyramid Structure
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
/\
|
|
26
|
+
/ \ E2E Tests (5-10%)
|
|
27
|
+
/----\ - User journey validation
|
|
28
|
+
/ \ - Critical path coverage
|
|
29
|
+
/--------\ Integration Tests (20-30%)
|
|
30
|
+
/ \ - Component interactions
|
|
31
|
+
/ \ - API integration
|
|
32
|
+
/--------------\ Unit Tests (60-70%)
|
|
33
|
+
/ \ - Individual functions
|
|
34
|
+
------------------ - Isolated components
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### React/Next.js Adapted Pyramid
|
|
38
|
+
|
|
39
|
+
For frontend applications, the pyramid shifts slightly:
|
|
40
|
+
|
|
41
|
+
| Level | Percentage | Tools | Focus |
|
|
42
|
+
|-------|------------|-------|-------|
|
|
43
|
+
| Unit | 50-60% | Jest, RTL | Pure functions, hooks, isolated components |
|
|
44
|
+
| Integration | 25-35% | RTL, MSW | Component trees, API calls, context |
|
|
45
|
+
| E2E | 10-15% | Playwright | Critical user flows, cross-page navigation |
|
|
46
|
+
|
|
47
|
+
### Why This Distribution?
|
|
48
|
+
|
|
49
|
+
**Unit tests are fast and cheap:**
|
|
50
|
+
- Execute in milliseconds
|
|
51
|
+
- Pinpoint failures precisely
|
|
52
|
+
- Easy to maintain
|
|
53
|
+
- Run on every commit
|
|
54
|
+
|
|
55
|
+
**Integration tests balance coverage and cost:**
|
|
56
|
+
- Test realistic scenarios
|
|
57
|
+
- Catch component interaction bugs
|
|
58
|
+
- Moderate execution time
|
|
59
|
+
- Run on every PR
|
|
60
|
+
|
|
61
|
+
**E2E tests are expensive but essential:**
|
|
62
|
+
- Validate real user experience
|
|
63
|
+
- Catch deployment issues
|
|
64
|
+
- Slow and brittle
|
|
65
|
+
- Run on staging/production
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Testing Types Deep Dive
|
|
70
|
+
|
|
71
|
+
### Unit Testing
|
|
72
|
+
|
|
73
|
+
**Purpose:** Verify individual units of code work correctly in isolation.
|
|
74
|
+
|
|
75
|
+
**What to Unit Test:**
|
|
76
|
+
- Pure utility functions
|
|
77
|
+
- Custom hooks (with renderHook)
|
|
78
|
+
- Individual component rendering
|
|
79
|
+
- State reducers
|
|
80
|
+
- Validation logic
|
|
81
|
+
- Data transformers
|
|
82
|
+
|
|
83
|
+
**Example: Testing a Pure Function**
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// utils/formatPrice.ts
|
|
87
|
+
export function formatPrice(cents: number, currency = 'USD'): string {
|
|
88
|
+
const formatter = new Intl.NumberFormat('en-US', {
|
|
89
|
+
style: 'currency',
|
|
90
|
+
currency,
|
|
91
|
+
});
|
|
92
|
+
return formatter.format(cents / 100);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// utils/formatPrice.test.ts
|
|
96
|
+
describe('formatPrice', () => {
|
|
97
|
+
it('formats cents to USD by default', () => {
|
|
98
|
+
expect(formatPrice(1999)).toBe('$19.99');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('handles zero', () => {
|
|
102
|
+
expect(formatPrice(0)).toBe('$0.00');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('supports different currencies', () => {
|
|
106
|
+
expect(formatPrice(1999, 'EUR')).toContain('€');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('handles large numbers', () => {
|
|
110
|
+
expect(formatPrice(100000000)).toBe('$1,000,000.00');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Example: Testing a Custom Hook**
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// hooks/useCounter.ts
|
|
119
|
+
export function useCounter(initial = 0) {
|
|
120
|
+
const [count, setCount] = useState(initial);
|
|
121
|
+
const increment = () => setCount(c => c + 1);
|
|
122
|
+
const decrement = () => setCount(c => c - 1);
|
|
123
|
+
const reset = () => setCount(initial);
|
|
124
|
+
return { count, increment, decrement, reset };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// hooks/useCounter.test.ts
|
|
128
|
+
import { renderHook, act } from '@testing-library/react';
|
|
129
|
+
import { useCounter } from './useCounter';
|
|
130
|
+
|
|
131
|
+
describe('useCounter', () => {
|
|
132
|
+
it('starts with initial value', () => {
|
|
133
|
+
const { result } = renderHook(() => useCounter(5));
|
|
134
|
+
expect(result.current.count).toBe(5);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('increments count', () => {
|
|
138
|
+
const { result } = renderHook(() => useCounter(0));
|
|
139
|
+
act(() => result.current.increment());
|
|
140
|
+
expect(result.current.count).toBe(1);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('decrements count', () => {
|
|
144
|
+
const { result } = renderHook(() => useCounter(5));
|
|
145
|
+
act(() => result.current.decrement());
|
|
146
|
+
expect(result.current.count).toBe(4);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('resets to initial value', () => {
|
|
150
|
+
const { result } = renderHook(() => useCounter(10));
|
|
151
|
+
act(() => result.current.increment());
|
|
152
|
+
act(() => result.current.reset());
|
|
153
|
+
expect(result.current.count).toBe(10);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Integration Testing
|
|
159
|
+
|
|
160
|
+
**Purpose:** Verify multiple units work together correctly.
|
|
161
|
+
|
|
162
|
+
**What to Integration Test:**
|
|
163
|
+
- Component trees with multiple children
|
|
164
|
+
- Components with context providers
|
|
165
|
+
- Form submission flows
|
|
166
|
+
- API call and response handling
|
|
167
|
+
- State management interactions
|
|
168
|
+
- Router-dependent components
|
|
169
|
+
|
|
170
|
+
**Example: Testing Component with API Call**
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// components/UserProfile.tsx
|
|
174
|
+
export function UserProfile({ userId }: { userId: string }) {
|
|
175
|
+
const [user, setUser] = useState<User | null>(null);
|
|
176
|
+
const [loading, setLoading] = useState(true);
|
|
177
|
+
const [error, setError] = useState<string | null>(null);
|
|
178
|
+
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
fetch(`/api/users/${userId}`)
|
|
181
|
+
.then(res => res.json())
|
|
182
|
+
.then(data => setUser(data))
|
|
183
|
+
.catch(err => setError(err.message))
|
|
184
|
+
.finally(() => setLoading(false));
|
|
185
|
+
}, [userId]);
|
|
186
|
+
|
|
187
|
+
if (loading) return <div>Loading...</div>;
|
|
188
|
+
if (error) return <div>Error: {error}</div>;
|
|
189
|
+
return <div>{user?.name}</div>;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// components/UserProfile.test.tsx
|
|
193
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
194
|
+
import { rest } from 'msw';
|
|
195
|
+
import { setupServer } from 'msw/node';
|
|
196
|
+
import { UserProfile } from './UserProfile';
|
|
197
|
+
|
|
198
|
+
const server = setupServer(
|
|
199
|
+
rest.get('/api/users/:id', (req, res, ctx) => {
|
|
200
|
+
return res(ctx.json({ id: req.params.id, name: 'John Doe' }));
|
|
201
|
+
})
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
beforeAll(() => server.listen());
|
|
205
|
+
afterEach(() => server.resetHandlers());
|
|
206
|
+
afterAll(() => server.close());
|
|
207
|
+
|
|
208
|
+
describe('UserProfile', () => {
|
|
209
|
+
it('shows loading state initially', () => {
|
|
210
|
+
render(<UserProfile userId="123" />);
|
|
211
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('displays user name after loading', async () => {
|
|
215
|
+
render(<UserProfile userId="123" />);
|
|
216
|
+
await waitFor(() => {
|
|
217
|
+
expect(screen.getByText('John Doe')).toBeInTheDocument();
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('displays error on API failure', async () => {
|
|
222
|
+
server.use(
|
|
223
|
+
rest.get('/api/users/:id', (req, res, ctx) => {
|
|
224
|
+
return res(ctx.status(500));
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
render(<UserProfile userId="123" />);
|
|
228
|
+
await waitFor(() => {
|
|
229
|
+
expect(screen.getByText(/Error/)).toBeInTheDocument();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### End-to-End Testing
|
|
236
|
+
|
|
237
|
+
**Purpose:** Verify complete user flows work in a real browser environment.
|
|
238
|
+
|
|
239
|
+
**What to E2E Test:**
|
|
240
|
+
- Critical business flows (checkout, signup, login)
|
|
241
|
+
- Cross-page navigation sequences
|
|
242
|
+
- Authentication flows
|
|
243
|
+
- Third-party integrations
|
|
244
|
+
- Payment processing
|
|
245
|
+
- Form wizards
|
|
246
|
+
|
|
247
|
+
**Example: Testing Checkout Flow**
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
// e2e/checkout.spec.ts
|
|
251
|
+
import { test, expect } from '@playwright/test';
|
|
252
|
+
|
|
253
|
+
test.describe('Checkout Flow', () => {
|
|
254
|
+
test.beforeEach(async ({ page }) => {
|
|
255
|
+
await page.goto('/');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test('completes purchase successfully', async ({ page }) => {
|
|
259
|
+
// Add product to cart
|
|
260
|
+
await page.goto('/products/widget-pro');
|
|
261
|
+
await page.getByRole('button', { name: 'Add to Cart' }).click();
|
|
262
|
+
|
|
263
|
+
// Verify cart updated
|
|
264
|
+
await expect(page.getByTestId('cart-count')).toHaveText('1');
|
|
265
|
+
|
|
266
|
+
// Go to checkout
|
|
267
|
+
await page.getByRole('link', { name: 'Checkout' }).click();
|
|
268
|
+
|
|
269
|
+
// Fill shipping info
|
|
270
|
+
await page.getByLabel('Email').fill('test@example.com');
|
|
271
|
+
await page.getByLabel('Address').fill('123 Test St');
|
|
272
|
+
await page.getByLabel('City').fill('Test City');
|
|
273
|
+
await page.getByLabel('Zip').fill('12345');
|
|
274
|
+
|
|
275
|
+
// Fill payment info (test card)
|
|
276
|
+
await page.getByLabel('Card Number').fill('4242424242424242');
|
|
277
|
+
await page.getByLabel('Expiry').fill('12/25');
|
|
278
|
+
await page.getByLabel('CVC').fill('123');
|
|
279
|
+
|
|
280
|
+
// Submit order
|
|
281
|
+
await page.getByRole('button', { name: 'Place Order' }).click();
|
|
282
|
+
|
|
283
|
+
// Verify confirmation
|
|
284
|
+
await expect(page).toHaveURL(/\/orders\/\w+/);
|
|
285
|
+
await expect(page.getByText('Order Confirmed')).toBeVisible();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
test('shows validation errors for invalid input', async ({ page }) => {
|
|
289
|
+
await page.goto('/checkout');
|
|
290
|
+
await page.getByRole('button', { name: 'Place Order' }).click();
|
|
291
|
+
|
|
292
|
+
await expect(page.getByText('Email is required')).toBeVisible();
|
|
293
|
+
await expect(page.getByText('Address is required')).toBeVisible();
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Visual Regression Testing
|
|
299
|
+
|
|
300
|
+
**Purpose:** Catch unintended visual changes to UI components.
|
|
301
|
+
|
|
302
|
+
**Tools:** Playwright visual comparisons, Percy, Chromatic
|
|
303
|
+
|
|
304
|
+
**Example: Visual Snapshot Test**
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
// e2e/visual/components.spec.ts
|
|
308
|
+
import { test, expect } from '@playwright/test';
|
|
309
|
+
|
|
310
|
+
test.describe('Visual Regression', () => {
|
|
311
|
+
test('button variants render correctly', async ({ page }) => {
|
|
312
|
+
await page.goto('/storybook/button');
|
|
313
|
+
await expect(page).toHaveScreenshot('button-variants.png');
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
test('responsive header', async ({ page }) => {
|
|
317
|
+
// Desktop
|
|
318
|
+
await page.setViewportSize({ width: 1280, height: 720 });
|
|
319
|
+
await page.goto('/');
|
|
320
|
+
await expect(page.locator('header')).toHaveScreenshot('header-desktop.png');
|
|
321
|
+
|
|
322
|
+
// Mobile
|
|
323
|
+
await page.setViewportSize({ width: 375, height: 667 });
|
|
324
|
+
await expect(page.locator('header')).toHaveScreenshot('header-mobile.png');
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Accessibility Testing
|
|
330
|
+
|
|
331
|
+
**Purpose:** Ensure application is usable by people with disabilities.
|
|
332
|
+
|
|
333
|
+
**Tools:** jest-axe, @axe-core/playwright
|
|
334
|
+
|
|
335
|
+
**Example: Automated A11y Testing**
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
// Unit/Integration level with jest-axe
|
|
339
|
+
import { render } from '@testing-library/react';
|
|
340
|
+
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
341
|
+
import { Button } from './Button';
|
|
342
|
+
|
|
343
|
+
expect.extend(toHaveNoViolations);
|
|
344
|
+
|
|
345
|
+
describe('Button accessibility', () => {
|
|
346
|
+
it('has no accessibility violations', async () => {
|
|
347
|
+
const { container } = render(<Button>Click me</Button>);
|
|
348
|
+
const results = await axe(container);
|
|
349
|
+
expect(results).toHaveNoViolations();
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// E2E level with Playwright + Axe
|
|
354
|
+
import { test, expect } from '@playwright/test';
|
|
355
|
+
import AxeBuilder from '@axe-core/playwright';
|
|
356
|
+
|
|
357
|
+
test('homepage has no a11y violations', async ({ page }) => {
|
|
358
|
+
await page.goto('/');
|
|
359
|
+
const results = await new AxeBuilder({ page }).analyze();
|
|
360
|
+
expect(results.violations).toEqual([]);
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Coverage Targets and Thresholds
|
|
367
|
+
|
|
368
|
+
### Recommended Thresholds by Project Type
|
|
369
|
+
|
|
370
|
+
| Project Type | Statements | Branches | Functions | Lines |
|
|
371
|
+
|--------------|------------|----------|-----------|-------|
|
|
372
|
+
| Startup/MVP | 60% | 50% | 60% | 60% |
|
|
373
|
+
| Growing Product | 75% | 70% | 75% | 75% |
|
|
374
|
+
| Enterprise | 85% | 80% | 85% | 85% |
|
|
375
|
+
| Safety Critical | 95% | 90% | 95% | 95% |
|
|
376
|
+
|
|
377
|
+
### Coverage by Code Type
|
|
378
|
+
|
|
379
|
+
**High Coverage Priority (80%+):**
|
|
380
|
+
- Business logic
|
|
381
|
+
- State management
|
|
382
|
+
- API handlers
|
|
383
|
+
- Form validation
|
|
384
|
+
- Authentication/authorization
|
|
385
|
+
- Payment processing
|
|
386
|
+
|
|
387
|
+
**Medium Coverage Priority (60-80%):**
|
|
388
|
+
- UI components
|
|
389
|
+
- Utility functions
|
|
390
|
+
- Data transformers
|
|
391
|
+
- Custom hooks
|
|
392
|
+
|
|
393
|
+
**Lower Coverage Priority (40-60%):**
|
|
394
|
+
- Static pages
|
|
395
|
+
- Simple wrappers
|
|
396
|
+
- Configuration files
|
|
397
|
+
- Types/interfaces
|
|
398
|
+
|
|
399
|
+
### Jest Coverage Configuration
|
|
400
|
+
|
|
401
|
+
```javascript
|
|
402
|
+
// jest.config.js
|
|
403
|
+
module.exports = {
|
|
404
|
+
collectCoverageFrom: [
|
|
405
|
+
'src/**/*.{ts,tsx}',
|
|
406
|
+
'!src/**/*.d.ts',
|
|
407
|
+
'!src/**/*.stories.{ts,tsx}',
|
|
408
|
+
'!src/**/index.{ts,tsx}', // barrel files
|
|
409
|
+
'!src/types/**',
|
|
410
|
+
],
|
|
411
|
+
coverageThreshold: {
|
|
412
|
+
global: {
|
|
413
|
+
statements: 80,
|
|
414
|
+
branches: 75,
|
|
415
|
+
functions: 80,
|
|
416
|
+
lines: 80,
|
|
417
|
+
},
|
|
418
|
+
// Higher thresholds for critical paths
|
|
419
|
+
'./src/services/payment/': {
|
|
420
|
+
statements: 95,
|
|
421
|
+
branches: 90,
|
|
422
|
+
functions: 95,
|
|
423
|
+
lines: 95,
|
|
424
|
+
},
|
|
425
|
+
'./src/services/auth/': {
|
|
426
|
+
statements: 90,
|
|
427
|
+
branches: 85,
|
|
428
|
+
functions: 90,
|
|
429
|
+
lines: 90,
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
coverageReporters: ['text', 'lcov', 'html', 'json'],
|
|
433
|
+
};
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Test Organization Patterns
|
|
439
|
+
|
|
440
|
+
### Co-located Tests (Recommended for React)
|
|
441
|
+
|
|
442
|
+
```
|
|
443
|
+
src/
|
|
444
|
+
├── components/
|
|
445
|
+
│ ├── Button/
|
|
446
|
+
│ │ ├── Button.tsx
|
|
447
|
+
│ │ ├── Button.test.tsx # Unit tests
|
|
448
|
+
│ │ ├── Button.stories.tsx # Storybook
|
|
449
|
+
│ │ └── index.ts
|
|
450
|
+
│ └── Form/
|
|
451
|
+
│ ├── Form.tsx
|
|
452
|
+
│ ├── Form.test.tsx
|
|
453
|
+
│ └── Form.integration.test.tsx # Integration tests
|
|
454
|
+
├── hooks/
|
|
455
|
+
│ ├── useAuth.ts
|
|
456
|
+
│ └── useAuth.test.ts
|
|
457
|
+
└── utils/
|
|
458
|
+
├── formatters.ts
|
|
459
|
+
└── formatters.test.ts
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Separate Test Directory
|
|
463
|
+
|
|
464
|
+
```
|
|
465
|
+
src/
|
|
466
|
+
├── components/
|
|
467
|
+
├── hooks/
|
|
468
|
+
└── utils/
|
|
469
|
+
|
|
470
|
+
__tests__/
|
|
471
|
+
├── unit/
|
|
472
|
+
│ ├── components/
|
|
473
|
+
│ ├── hooks/
|
|
474
|
+
│ └── utils/
|
|
475
|
+
├── integration/
|
|
476
|
+
│ └── flows/
|
|
477
|
+
└── fixtures/
|
|
478
|
+
├── users.json
|
|
479
|
+
└── products.json
|
|
480
|
+
|
|
481
|
+
e2e/
|
|
482
|
+
├── specs/
|
|
483
|
+
│ ├── auth.spec.ts
|
|
484
|
+
│ └── checkout.spec.ts
|
|
485
|
+
├── fixtures/
|
|
486
|
+
│ └── auth.ts
|
|
487
|
+
└── pages/ # Page Object Models
|
|
488
|
+
├── LoginPage.ts
|
|
489
|
+
└── CheckoutPage.ts
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Test File Naming Conventions
|
|
493
|
+
|
|
494
|
+
| Pattern | Use Case |
|
|
495
|
+
|---------|----------|
|
|
496
|
+
| `*.test.ts` | Unit tests |
|
|
497
|
+
| `*.spec.ts` | Integration/E2E tests |
|
|
498
|
+
| `*.integration.test.ts` | Explicit integration tests |
|
|
499
|
+
| `*.e2e.spec.ts` | Explicit E2E tests |
|
|
500
|
+
| `*.a11y.test.ts` | Accessibility tests |
|
|
501
|
+
| `*.visual.spec.ts` | Visual regression tests |
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## CI/CD Integration Strategies
|
|
506
|
+
|
|
507
|
+
### Pipeline Stages
|
|
508
|
+
|
|
509
|
+
```yaml
|
|
510
|
+
# .github/workflows/test.yml
|
|
511
|
+
name: Test Pipeline
|
|
512
|
+
|
|
513
|
+
on:
|
|
514
|
+
push:
|
|
515
|
+
branches: [main, dev]
|
|
516
|
+
pull_request:
|
|
517
|
+
branches: [main, dev]
|
|
518
|
+
|
|
519
|
+
jobs:
|
|
520
|
+
unit:
|
|
521
|
+
name: Unit Tests
|
|
522
|
+
runs-on: ubuntu-latest
|
|
523
|
+
steps:
|
|
524
|
+
- uses: actions/checkout@v4
|
|
525
|
+
- uses: actions/setup-node@v4
|
|
526
|
+
with:
|
|
527
|
+
node-version: 20
|
|
528
|
+
cache: 'npm'
|
|
529
|
+
- run: npm ci
|
|
530
|
+
- run: npm run test:unit -- --coverage
|
|
531
|
+
- uses: codecov/codecov-action@v4
|
|
532
|
+
with:
|
|
533
|
+
files: coverage/lcov.info
|
|
534
|
+
fail_ci_if_error: true
|
|
535
|
+
|
|
536
|
+
integration:
|
|
537
|
+
name: Integration Tests
|
|
538
|
+
runs-on: ubuntu-latest
|
|
539
|
+
needs: unit
|
|
540
|
+
steps:
|
|
541
|
+
- uses: actions/checkout@v4
|
|
542
|
+
- uses: actions/setup-node@v4
|
|
543
|
+
with:
|
|
544
|
+
node-version: 20
|
|
545
|
+
cache: 'npm'
|
|
546
|
+
- run: npm ci
|
|
547
|
+
- run: npm run test:integration
|
|
548
|
+
|
|
549
|
+
e2e:
|
|
550
|
+
name: E2E Tests
|
|
551
|
+
runs-on: ubuntu-latest
|
|
552
|
+
needs: integration
|
|
553
|
+
steps:
|
|
554
|
+
- uses: actions/checkout@v4
|
|
555
|
+
- uses: actions/setup-node@v4
|
|
556
|
+
with:
|
|
557
|
+
node-version: 20
|
|
558
|
+
cache: 'npm'
|
|
559
|
+
- run: npm ci
|
|
560
|
+
- run: npx playwright install --with-deps
|
|
561
|
+
- run: npm run build
|
|
562
|
+
- run: npm run test:e2e
|
|
563
|
+
- uses: actions/upload-artifact@v4
|
|
564
|
+
if: failure()
|
|
565
|
+
with:
|
|
566
|
+
name: playwright-report
|
|
567
|
+
path: playwright-report/
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Test Splitting for Speed
|
|
571
|
+
|
|
572
|
+
```yaml
|
|
573
|
+
# Run E2E tests in parallel across multiple machines
|
|
574
|
+
e2e:
|
|
575
|
+
strategy:
|
|
576
|
+
matrix:
|
|
577
|
+
shard: [1, 2, 3, 4]
|
|
578
|
+
steps:
|
|
579
|
+
- run: npx playwright test --shard=${{ matrix.shard }}/4
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### PR Gating Rules
|
|
583
|
+
|
|
584
|
+
| Test Type | When to Run | Block Merge? |
|
|
585
|
+
|-----------|-------------|--------------|
|
|
586
|
+
| Unit | Every commit | Yes |
|
|
587
|
+
| Integration | Every PR | Yes |
|
|
588
|
+
| E2E (smoke) | Every PR | Yes |
|
|
589
|
+
| E2E (full) | Merge to main | No (alert only) |
|
|
590
|
+
| Visual | Every PR | No (review required) |
|
|
591
|
+
| Performance | Weekly/Release | No (alert only) |
|
|
592
|
+
|
|
593
|
+
---
|
|
594
|
+
|
|
595
|
+
## Testing Decision Framework
|
|
596
|
+
|
|
597
|
+
### When to Write Which Test
|
|
598
|
+
|
|
599
|
+
```
|
|
600
|
+
Is it a pure function with no side effects?
|
|
601
|
+
├── Yes → Unit test
|
|
602
|
+
└── No
|
|
603
|
+
├── Does it make API calls or use context?
|
|
604
|
+
│ ├── Yes → Integration test with mocking
|
|
605
|
+
│ └── No
|
|
606
|
+
│ ├── Is it a critical user flow?
|
|
607
|
+
│ │ ├── Yes → E2E test
|
|
608
|
+
│ │ └── No → Integration test
|
|
609
|
+
└── Is it UI-focused with many visual states?
|
|
610
|
+
├── Yes → Storybook + Visual test
|
|
611
|
+
└── No → Component unit test
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Test ROI Matrix
|
|
615
|
+
|
|
616
|
+
| Test Type | Write Time | Run Time | Maintenance | Confidence |
|
|
617
|
+
|-----------|------------|----------|-------------|------------|
|
|
618
|
+
| Unit | Low | Very Fast | Low | Medium |
|
|
619
|
+
| Integration | Medium | Fast | Medium | High |
|
|
620
|
+
| E2E | High | Slow | High | Very High |
|
|
621
|
+
| Visual | Low | Medium | Medium | High (UI) |
|
|
622
|
+
|
|
623
|
+
### When NOT to Test
|
|
624
|
+
|
|
625
|
+
- Generated code (GraphQL types, Prisma client)
|
|
626
|
+
- Third-party library internals
|
|
627
|
+
- Implementation details (internal state, private methods)
|
|
628
|
+
- Simple pass-through wrappers
|
|
629
|
+
- Type definitions
|
|
630
|
+
|
|
631
|
+
### Red Flags in Testing Strategy
|
|
632
|
+
|
|
633
|
+
| Red Flag | Problem | Solution |
|
|
634
|
+
|----------|---------|----------|
|
|
635
|
+
| E2E tests > 30% | Slow CI, flaky tests | Push logic down to integration |
|
|
636
|
+
| Only unit tests | Missing interaction bugs | Add integration tests |
|
|
637
|
+
| Testing mocks | Not testing real behavior | Test behavior, not implementation |
|
|
638
|
+
| 100% coverage goal | Diminishing returns | Focus on critical paths |
|
|
639
|
+
| No E2E tests | Missing deployment issues | Add smoke tests for critical flows |
|
|
640
|
+
|
|
641
|
+
---
|
|
642
|
+
|
|
643
|
+
## Summary
|
|
644
|
+
|
|
645
|
+
1. **Follow the pyramid:** 60% unit, 30% integration, 10% E2E
|
|
646
|
+
2. **Set thresholds by risk:** Higher coverage for critical paths
|
|
647
|
+
3. **Co-locate tests:** Keep tests close to source code
|
|
648
|
+
4. **Automate in CI:** Run tests on every PR, gate merges on failure
|
|
649
|
+
5. **Decide wisely:** Not everything needs every type of test
|