@ruaruababa/vibe-kit 1.0.0
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/CATALOG.md +317 -0
- package/README.md +121 -0
- package/aliases.json +65 -0
- package/bin/vibe.js +2 -0
- package/bundles.json +265 -0
- package/catalog.json +1560 -0
- package/dist/antigravity-skills/bin/cli.js +438 -0
- package/dist/antigravity-skills/lib/skill-utils.js +158 -0
- package/dist/antigravity-skills/scripts/build-catalog.js +305 -0
- package/dist/antigravity-skills/scripts/normalize-frontmatter.js +144 -0
- package/dist/antigravity-skills/scripts/validate-skills.js +230 -0
- package/dist/bin/vibe.js +2 -0
- package/dist/dist/src/cli/index.js +26 -0
- package/dist/lib/skill-utils.js +158 -0
- package/dist/scripts/build-catalog.js +50 -0
- package/dist/scripts/normalize-frontmatter.js +144 -0
- package/dist/scripts/validate-skills.js +56 -0
- package/dist/src/cli/index.js +146 -0
- package/dist/src/types/index.js +13 -0
- package/dist/src/utils/fs.js +1 -0
- package/package.json +43 -0
- package/skills/accessibility-compliance-accessibility-audit/SKILL.md +42 -0
- package/skills/accessibility-compliance-accessibility-audit/resources/implementation-playbook.md +502 -0
- package/skills/agent-orchestration-improve-agent/SKILL.md +349 -0
- package/skills/agent-orchestration-multi-agent-optimize/SKILL.md +239 -0
- package/skills/agent-orchestrator/SKILL.md +24 -0
- package/skills/ai-engineer/SKILL.md +171 -0
- package/skills/airflow-dag-patterns/SKILL.md +41 -0
- package/skills/airflow-dag-patterns/resources/implementation-playbook.md +509 -0
- package/skills/angular-migration/SKILL.md +428 -0
- package/skills/anti-reversing-techniques/SKILL.md +42 -0
- package/skills/anti-reversing-techniques/resources/implementation-playbook.md +539 -0
- package/skills/api-design-principles/SKILL.md +37 -0
- package/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/skills/api-documenter/SKILL.md +184 -0
- package/skills/api-testing-observability-api-mock/SKILL.md +46 -0
- package/skills/api-testing-observability-api-mock/resources/implementation-playbook.md +1327 -0
- package/skills/application-performance-performance-optimization/SKILL.md +154 -0
- package/skills/architect-review/SKILL.md +174 -0
- package/skills/architecture-decision-records/SKILL.md +441 -0
- package/skills/architecture-patterns/SKILL.md +37 -0
- package/skills/architecture-patterns/resources/implementation-playbook.md +479 -0
- package/skills/arm-cortex-expert/SKILL.md +306 -0
- package/skills/async-python-patterns/SKILL.md +39 -0
- package/skills/async-python-patterns/resources/implementation-playbook.md +678 -0
- package/skills/attack-tree-construction/SKILL.md +38 -0
- package/skills/attack-tree-construction/resources/implementation-playbook.md +671 -0
- package/skills/auth-implementation-patterns/SKILL.md +39 -0
- package/skills/auth-implementation-patterns/resources/implementation-playbook.md +618 -0
- package/skills/backend-architect/SKILL.md +333 -0
- package/skills/backend-development-feature-development/SKILL.md +180 -0
- package/skills/backend-security-coder/SKILL.md +156 -0
- package/skills/backtesting-frameworks/SKILL.md +39 -0
- package/skills/backtesting-frameworks/resources/implementation-playbook.md +647 -0
- package/skills/bash-defensive-patterns/SKILL.md +43 -0
- package/skills/bash-defensive-patterns/resources/implementation-playbook.md +517 -0
- package/skills/bash-pro/SKILL.md +310 -0
- package/skills/bats-testing-patterns/SKILL.md +34 -0
- package/skills/bats-testing-patterns/resources/implementation-playbook.md +614 -0
- package/skills/bazel-build-optimization/SKILL.md +397 -0
- package/skills/billing-automation/SKILL.md +42 -0
- package/skills/billing-automation/resources/implementation-playbook.md +544 -0
- package/skills/binary-analysis-patterns/SKILL.md +450 -0
- package/skills/blockchain-developer/SKILL.md +208 -0
- package/skills/business-analyst/SKILL.md +182 -0
- package/skills/c-pro/SKILL.md +56 -0
- package/skills/c4-architecture-c4-architecture/SKILL.md +389 -0
- package/skills/c4-code/SKILL.md +244 -0
- package/skills/c4-component/SKILL.md +153 -0
- package/skills/c4-container/SKILL.md +171 -0
- package/skills/c4-context/SKILL.md +150 -0
- package/skills/changelog-automation/SKILL.md +38 -0
- package/skills/changelog-automation/resources/implementation-playbook.md +538 -0
- package/skills/cicd-automation-workflow-automate/SKILL.md +51 -0
- package/skills/cicd-automation-workflow-automate/resources/implementation-playbook.md +1333 -0
- package/skills/clean-markdown/SKILL.md +23 -0
- package/skills/cloud-architect/SKILL.md +135 -0
- package/skills/code-documentation-code-explain/SKILL.md +46 -0
- package/skills/code-documentation-code-explain/resources/implementation-playbook.md +802 -0
- package/skills/code-documentation-doc-generate/SKILL.md +48 -0
- package/skills/code-documentation-doc-generate/resources/implementation-playbook.md +640 -0
- package/skills/code-refactoring-context-restore/SKILL.md +179 -0
- package/skills/code-refactoring-refactor-clean/SKILL.md +51 -0
- package/skills/code-refactoring-refactor-clean/resources/implementation-playbook.md +879 -0
- package/skills/code-refactoring-tech-debt/SKILL.md +386 -0
- package/skills/code-review-ai-ai-review/SKILL.md +450 -0
- package/skills/code-review-excellence/SKILL.md +40 -0
- package/skills/code-review-excellence/resources/implementation-playbook.md +515 -0
- package/skills/code-reviewer/SKILL.md +178 -0
- package/skills/codebase-cleanup-deps-audit/SKILL.md +51 -0
- package/skills/codebase-cleanup-deps-audit/resources/implementation-playbook.md +766 -0
- package/skills/codebase-cleanup-refactor-clean/SKILL.md +51 -0
- package/skills/codebase-cleanup-refactor-clean/resources/implementation-playbook.md +879 -0
- package/skills/codebase-cleanup-tech-debt/SKILL.md +386 -0
- package/skills/competitive-landscape/SKILL.md +34 -0
- package/skills/competitive-landscape/resources/implementation-playbook.md +494 -0
- package/skills/comprehensive-review-full-review/SKILL.md +146 -0
- package/skills/comprehensive-review-pr-enhance/SKILL.md +46 -0
- package/skills/comprehensive-review-pr-enhance/resources/implementation-playbook.md +691 -0
- package/skills/conductor-implement/SKILL.md +388 -0
- package/skills/conductor-manage/SKILL.md +39 -0
- package/skills/conductor-manage/resources/implementation-playbook.md +1120 -0
- package/skills/conductor-new-track/SKILL.md +433 -0
- package/skills/conductor-revert/SKILL.md +372 -0
- package/skills/conductor-setup/SKILL.md +426 -0
- package/skills/conductor-status/SKILL.md +338 -0
- package/skills/conductor-validator/SKILL.md +62 -0
- package/skills/content-marketer/SKILL.md +170 -0
- package/skills/context-driven-development/SKILL.md +400 -0
- package/skills/context-management-context-restore/SKILL.md +179 -0
- package/skills/context-management-context-save/SKILL.md +177 -0
- package/skills/context-manager/SKILL.md +185 -0
- package/skills/cost-optimization/SKILL.md +286 -0
- package/skills/cpp-pro/SKILL.md +59 -0
- package/skills/cqrs-implementation/SKILL.md +35 -0
- package/skills/cqrs-implementation/resources/implementation-playbook.md +540 -0
- package/skills/csharp-pro/SKILL.md +59 -0
- package/skills/customer-support/SKILL.md +170 -0
- package/skills/data-engineer/SKILL.md +224 -0
- package/skills/data-engineering-data-driven-feature/SKILL.md +182 -0
- package/skills/data-engineering-data-pipeline/SKILL.md +201 -0
- package/skills/data-quality-frameworks/SKILL.md +40 -0
- package/skills/data-quality-frameworks/resources/implementation-playbook.md +573 -0
- package/skills/data-scientist/SKILL.md +199 -0
- package/skills/data-storytelling/SKILL.md +465 -0
- package/skills/database-admin/SKILL.md +165 -0
- package/skills/database-architect/SKILL.md +268 -0
- package/skills/database-cloud-optimization-cost-optimize/SKILL.md +44 -0
- package/skills/database-cloud-optimization-cost-optimize/resources/implementation-playbook.md +1441 -0
- package/skills/database-migration/SKILL.md +436 -0
- package/skills/database-migrations-migration-observability/SKILL.md +420 -0
- package/skills/database-migrations-sql-migrations/SKILL.md +53 -0
- package/skills/database-migrations-sql-migrations/resources/implementation-playbook.md +499 -0
- package/skills/database-optimizer/SKILL.md +167 -0
- package/skills/dbt-transformation-patterns/SKILL.md +34 -0
- package/skills/dbt-transformation-patterns/resources/implementation-playbook.md +547 -0
- package/skills/debugger/SKILL.md +49 -0
- package/skills/debugging-strategies/SKILL.md +34 -0
- package/skills/debugging-strategies/resources/implementation-playbook.md +511 -0
- package/skills/debugging-toolkit-smart-debug/SKILL.md +197 -0
- package/skills/defi-protocol-templates/SKILL.md +466 -0
- package/skills/dependency-management-deps-audit/SKILL.md +44 -0
- package/skills/dependency-management-deps-audit/resources/implementation-playbook.md +766 -0
- package/skills/dependency-upgrade/SKILL.md +421 -0
- package/skills/deployment-engineer/SKILL.md +170 -0
- package/skills/deployment-pipeline-design/SKILL.md +371 -0
- package/skills/deployment-validation-config-validate/SKILL.md +496 -0
- package/skills/devops-troubleshooter/SKILL.md +161 -0
- package/skills/distributed-debugging-debug-trace/SKILL.md +44 -0
- package/skills/distributed-debugging-debug-trace/resources/implementation-playbook.md +1307 -0
- package/skills/distributed-tracing/SKILL.md +450 -0
- package/skills/django-pro/SKILL.md +180 -0
- package/skills/docs-architect/SKILL.md +98 -0
- package/skills/documentation-generation-doc-generate/SKILL.md +48 -0
- package/skills/documentation-generation-doc-generate/resources/implementation-playbook.md +640 -0
- package/skills/dotnet-architect/SKILL.md +197 -0
- package/skills/dotnet-backend-patterns/SKILL.md +37 -0
- package/skills/dotnet-backend-patterns/assets/repository-template.cs +523 -0
- package/skills/dotnet-backend-patterns/assets/service-template.cs +336 -0
- package/skills/dotnet-backend-patterns/references/dapper-patterns.md +544 -0
- package/skills/dotnet-backend-patterns/references/ef-core-best-practices.md +355 -0
- package/skills/dotnet-backend-patterns/resources/implementation-playbook.md +799 -0
- package/skills/dummy-skill/SKILL.md +5 -0
- package/skills/dx-optimizer/SKILL.md +83 -0
- package/skills/e2e-testing-patterns/SKILL.md +41 -0
- package/skills/e2e-testing-patterns/resources/implementation-playbook.md +531 -0
- package/skills/elixir-pro/SKILL.md +59 -0
- package/skills/embedding-strategies/SKILL.md +491 -0
- package/skills/employment-contract-templates/SKILL.md +39 -0
- package/skills/employment-contract-templates/resources/implementation-playbook.md +493 -0
- package/skills/error-debugging-error-analysis/SKILL.md +47 -0
- package/skills/error-debugging-error-analysis/resources/implementation-playbook.md +1143 -0
- package/skills/error-debugging-error-trace/SKILL.md +43 -0
- package/skills/error-debugging-error-trace/resources/implementation-playbook.md +1361 -0
- package/skills/error-debugging-multi-agent-review/SKILL.md +216 -0
- package/skills/error-detective/SKILL.md +53 -0
- package/skills/error-diagnostics-error-analysis/SKILL.md +47 -0
- package/skills/error-diagnostics-error-analysis/resources/implementation-playbook.md +1143 -0
- package/skills/error-diagnostics-error-trace/SKILL.md +48 -0
- package/skills/error-diagnostics-error-trace/resources/implementation-playbook.md +1371 -0
- package/skills/error-diagnostics-smart-debug/SKILL.md +197 -0
- package/skills/error-handling-patterns/SKILL.md +35 -0
- package/skills/error-handling-patterns/resources/implementation-playbook.md +635 -0
- package/skills/event-sourcing-architect/SKILL.md +58 -0
- package/skills/event-store-design/SKILL.md +449 -0
- package/skills/fastapi-pro/SKILL.md +192 -0
- package/skills/fastapi-templates/SKILL.md +32 -0
- package/skills/fastapi-templates/resources/implementation-playbook.md +566 -0
- package/skills/final-test/SKILL.md +5 -0
- package/skills/firmware-analyst/SKILL.md +320 -0
- package/skills/flutter-expert/SKILL.md +200 -0
- package/skills/framework-migration-code-migrate/SKILL.md +48 -0
- package/skills/framework-migration-code-migrate/resources/implementation-playbook.md +1052 -0
- package/skills/framework-migration-deps-upgrade/SKILL.md +48 -0
- package/skills/framework-migration-deps-upgrade/resources/implementation-playbook.md +755 -0
- package/skills/framework-migration-legacy-modernize/SKILL.md +132 -0
- package/skills/frontend-developer/SKILL.md +171 -0
- package/skills/frontend-mobile-development-component-scaffold/SKILL.md +403 -0
- package/skills/frontend-mobile-security-xss-scan/SKILL.md +322 -0
- package/skills/frontend-security-coder/SKILL.md +170 -0
- package/skills/full-stack-orchestration-full-stack-feature/SKILL.md +135 -0
- package/skills/gdpr-data-handling/SKILL.md +33 -0
- package/skills/gdpr-data-handling/resources/implementation-playbook.md +615 -0
- package/skills/git-advanced-workflows/SKILL.md +412 -0
- package/skills/git-pr-workflows-git-workflow/SKILL.md +140 -0
- package/skills/git-pr-workflows-onboard/SKILL.md +416 -0
- package/skills/git-pr-workflows-pr-enhance/SKILL.md +48 -0
- package/skills/git-pr-workflows-pr-enhance/resources/implementation-playbook.md +701 -0
- package/skills/github-actions-templates/SKILL.md +345 -0
- package/skills/gitlab-ci-patterns/SKILL.md +283 -0
- package/skills/gitops-workflow/SKILL.md +303 -0
- package/skills/gitops-workflow/references/argocd-setup.md +134 -0
- package/skills/gitops-workflow/references/sync-policies.md +131 -0
- package/skills/go-concurrency-patterns/SKILL.md +33 -0
- package/skills/go-concurrency-patterns/resources/implementation-playbook.md +654 -0
- package/skills/godot-gdscript-patterns/SKILL.md +33 -0
- package/skills/godot-gdscript-patterns/resources/implementation-playbook.md +804 -0
- package/skills/golang-pro/SKILL.md +179 -0
- package/skills/grafana-dashboards/SKILL.md +381 -0
- package/skills/graphql-architect/SKILL.md +182 -0
- package/skills/haskell-pro/SKILL.md +56 -0
- package/skills/helm-chart-scaffolding/SKILL.md +34 -0
- package/skills/helm-chart-scaffolding/assets/Chart.yaml.template +42 -0
- package/skills/helm-chart-scaffolding/assets/values.yaml.template +185 -0
- package/skills/helm-chart-scaffolding/references/chart-structure.md +500 -0
- package/skills/helm-chart-scaffolding/resources/implementation-playbook.md +543 -0
- package/skills/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
- package/skills/hr-pro/SKILL.md +126 -0
- package/skills/hybrid-cloud-architect/SKILL.md +168 -0
- package/skills/hybrid-cloud-networking/SKILL.md +238 -0
- package/skills/hybrid-search-implementation/SKILL.md +32 -0
- package/skills/hybrid-search-implementation/resources/implementation-playbook.md +567 -0
- package/skills/incident-responder/SKILL.md +213 -0
- package/skills/incident-response-incident-response/SKILL.md +168 -0
- package/skills/incident-response-smart-fix/SKILL.md +29 -0
- package/skills/incident-response-smart-fix/resources/implementation-playbook.md +838 -0
- package/skills/incident-runbook-templates/SKILL.md +395 -0
- package/skills/ios-developer/SKILL.md +219 -0
- package/skills/istio-traffic-management/SKILL.md +337 -0
- package/skills/java-pro/SKILL.md +177 -0
- package/skills/javascript-pro/SKILL.md +57 -0
- package/skills/javascript-testing-patterns/SKILL.md +35 -0
- package/skills/javascript-testing-patterns/resources/implementation-playbook.md +1024 -0
- package/skills/javascript-typescript-typescript-scaffold/SKILL.md +361 -0
- package/skills/julia-pro/SKILL.md +209 -0
- package/skills/k8s-manifest-generator/SKILL.md +35 -0
- package/skills/k8s-manifest-generator/assets/configmap-template.yaml +296 -0
- package/skills/k8s-manifest-generator/assets/deployment-template.yaml +203 -0
- package/skills/k8s-manifest-generator/assets/service-template.yaml +171 -0
- package/skills/k8s-manifest-generator/references/deployment-spec.md +753 -0
- package/skills/k8s-manifest-generator/references/service-spec.md +724 -0
- package/skills/k8s-manifest-generator/resources/implementation-playbook.md +510 -0
- package/skills/k8s-security-policies/SKILL.md +346 -0
- package/skills/k8s-security-policies/assets/network-policy-template.yaml +177 -0
- package/skills/k8s-security-policies/references/rbac-patterns.md +187 -0
- package/skills/kpi-dashboard-design/SKILL.md +440 -0
- package/skills/kubernetes-architect/SKILL.md +170 -0
- package/skills/langchain-architecture/SKILL.md +350 -0
- package/skills/legacy-modernizer/SKILL.md +53 -0
- package/skills/legal-advisor/SKILL.md +70 -0
- package/skills/linkerd-patterns/SKILL.md +321 -0
- package/skills/llm-application-dev-ai-assistant/SKILL.md +35 -0
- package/skills/llm-application-dev-ai-assistant/resources/implementation-playbook.md +1236 -0
- package/skills/llm-application-dev-langchain-agent/SKILL.md +246 -0
- package/skills/llm-application-dev-prompt-optimize/SKILL.md +37 -0
- package/skills/llm-application-dev-prompt-optimize/resources/implementation-playbook.md +591 -0
- package/skills/llm-evaluation/SKILL.md +483 -0
- package/skills/machine-learning-ops-ml-pipeline/SKILL.md +314 -0
- package/skills/malware-analyst/SKILL.md +247 -0
- package/skills/market-sizing-analysis/SKILL.md +425 -0
- package/skills/market-sizing-analysis/examples/saas-market-sizing.md +349 -0
- package/skills/market-sizing-analysis/references/data-sources.md +360 -0
- package/skills/memory-forensics/SKILL.md +491 -0
- package/skills/memory-safety-patterns/SKILL.md +33 -0
- package/skills/memory-safety-patterns/resources/implementation-playbook.md +603 -0
- package/skills/mermaid-expert/SKILL.md +59 -0
- package/skills/microservices-patterns/SKILL.md +35 -0
- package/skills/microservices-patterns/resources/implementation-playbook.md +607 -0
- package/skills/minecraft-bukkit-pro/SKILL.md +126 -0
- package/skills/ml-engineer/SKILL.md +168 -0
- package/skills/ml-pipeline-workflow/SKILL.md +257 -0
- package/skills/mlops-engineer/SKILL.md +219 -0
- package/skills/mobile-developer/SKILL.md +205 -0
- package/skills/mobile-security-coder/SKILL.md +184 -0
- package/skills/modern-javascript-patterns/SKILL.md +35 -0
- package/skills/modern-javascript-patterns/resources/implementation-playbook.md +910 -0
- package/skills/monorepo-architect/SKILL.md +61 -0
- package/skills/monorepo-management/SKILL.md +35 -0
- package/skills/monorepo-management/resources/implementation-playbook.md +621 -0
- package/skills/mtls-configuration/SKILL.md +359 -0
- package/skills/multi-cloud-architecture/SKILL.md +189 -0
- package/skills/multi-platform-apps-multi-platform/SKILL.md +203 -0
- package/skills/network-engineer/SKILL.md +169 -0
- package/skills/nextjs-app-router-patterns/SKILL.md +33 -0
- package/skills/nextjs-app-router-patterns/resources/implementation-playbook.md +543 -0
- package/skills/nft-standards/SKILL.md +395 -0
- package/skills/node-expert/SKILL.md +23 -0
- package/skills/nodejs-backend-patterns/SKILL.md +35 -0
- package/skills/nodejs-backend-patterns/resources/implementation-playbook.md +1019 -0
- package/skills/nx-workspace-patterns/SKILL.md +464 -0
- package/skills/observability-engineer/SKILL.md +237 -0
- package/skills/observability-monitoring-monitor-setup/SKILL.md +48 -0
- package/skills/observability-monitoring-monitor-setup/resources/implementation-playbook.md +505 -0
- package/skills/observability-monitoring-slo-implement/SKILL.md +43 -0
- package/skills/observability-monitoring-slo-implement/resources/implementation-playbook.md +1077 -0
- package/skills/on-call-handoff-patterns/SKILL.md +453 -0
- package/skills/openapi-spec-generation/SKILL.md +33 -0
- package/skills/openapi-spec-generation/resources/implementation-playbook.md +1027 -0
- package/skills/payment-integration/SKILL.md +77 -0
- package/skills/paypal-integration/SKILL.md +479 -0
- package/skills/pci-compliance/SKILL.md +478 -0
- package/skills/performance-engineer/SKILL.md +180 -0
- package/skills/performance-testing-review-ai-review/SKILL.md +450 -0
- package/skills/performance-testing-review-multi-agent-review/SKILL.md +216 -0
- package/skills/php-pro/SKILL.md +63 -0
- package/skills/posix-shell-pro/SKILL.md +304 -0
- package/skills/postgresql/SKILL.md +230 -0
- package/skills/postmortem-writing/SKILL.md +386 -0
- package/skills/projection-patterns/SKILL.md +33 -0
- package/skills/projection-patterns/resources/implementation-playbook.md +501 -0
- package/skills/prometheus-configuration/SKILL.md +404 -0
- package/skills/prompt-engineer/SKILL.md +272 -0
- package/skills/prompt-engineering-patterns/SKILL.md +213 -0
- package/skills/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
- package/skills/prompt-engineering-patterns/assets/prompt-template-library.md +246 -0
- package/skills/prompt-engineering-patterns/references/chain-of-thought.md +399 -0
- package/skills/prompt-engineering-patterns/references/few-shot-learning.md +369 -0
- package/skills/prompt-engineering-patterns/references/prompt-optimization.md +414 -0
- package/skills/prompt-engineering-patterns/references/prompt-templates.md +470 -0
- package/skills/prompt-engineering-patterns/references/system-prompts.md +189 -0
- package/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
- package/skills/protocol-reverse-engineering/SKILL.md +29 -0
- package/skills/protocol-reverse-engineering/resources/implementation-playbook.md +509 -0
- package/skills/python-development-python-scaffold/SKILL.md +331 -0
- package/skills/python-packaging/SKILL.md +36 -0
- package/skills/python-packaging/resources/implementation-playbook.md +869 -0
- package/skills/python-performance-optimization/SKILL.md +36 -0
- package/skills/python-performance-optimization/resources/implementation-playbook.md +868 -0
- package/skills/python-pro/SKILL.md +158 -0
- package/skills/python-testing-patterns/SKILL.md +37 -0
- package/skills/python-testing-patterns/resources/implementation-playbook.md +906 -0
- package/skills/quant-analyst/SKILL.md +53 -0
- package/skills/rag-implementation/SKILL.md +421 -0
- package/skills/react-modernization/SKILL.md +34 -0
- package/skills/react-modernization/resources/implementation-playbook.md +512 -0
- package/skills/react-native-architecture/SKILL.md +33 -0
- package/skills/react-native-architecture/resources/implementation-playbook.md +670 -0
- package/skills/react-state-management/SKILL.md +441 -0
- package/skills/reference-builder/SKILL.md +188 -0
- package/skills/reverse-engineer/SKILL.md +173 -0
- package/skills/risk-manager/SKILL.md +61 -0
- package/skills/risk-metrics-calculation/SKILL.md +33 -0
- package/skills/risk-metrics-calculation/resources/implementation-playbook.md +554 -0
- package/skills/ruby-pro/SKILL.md +56 -0
- package/skills/rust-async-patterns/SKILL.md +33 -0
- package/skills/rust-async-patterns/resources/implementation-playbook.md +516 -0
- package/skills/rust-pro/SKILL.md +178 -0
- package/skills/saga-orchestration/SKILL.md +496 -0
- package/skills/sales-automator/SKILL.md +55 -0
- package/skills/sast-configuration/SKILL.md +212 -0
- package/skills/scala-pro/SKILL.md +82 -0
- package/skills/screen-reader-testing/SKILL.md +33 -0
- package/skills/screen-reader-testing/resources/implementation-playbook.md +544 -0
- package/skills/search-specialist/SKILL.md +80 -0
- package/skills/secrets-management/SKILL.md +364 -0
- package/skills/security-auditor/SKILL.md +169 -0
- package/skills/security-compliance-compliance-check/SKILL.md +55 -0
- package/skills/security-compliance-compliance-check/resources/implementation-playbook.md +963 -0
- package/skills/security-requirement-extraction/SKILL.md +33 -0
- package/skills/security-requirement-extraction/resources/implementation-playbook.md +676 -0
- package/skills/security-scanning-security-dependencies/SKILL.md +43 -0
- package/skills/security-scanning-security-dependencies/resources/implementation-playbook.md +544 -0
- package/skills/security-scanning-security-hardening/SKILL.md +147 -0
- package/skills/security-scanning-security-sast/SKILL.md +495 -0
- package/skills/seo-authority-builder/SKILL.md +136 -0
- package/skills/seo-cannibalization-detector/SKILL.md +123 -0
- package/skills/seo-content-auditor/SKILL.md +83 -0
- package/skills/seo-content-planner/SKILL.md +108 -0
- package/skills/seo-content-refresher/SKILL.md +118 -0
- package/skills/seo-content-writer/SKILL.md +96 -0
- package/skills/seo-keyword-strategist/SKILL.md +95 -0
- package/skills/seo-meta-optimizer/SKILL.md +92 -0
- package/skills/seo-snippet-hunter/SKILL.md +114 -0
- package/skills/seo-structure-architect/SKILL.md +108 -0
- package/skills/service-mesh-expert/SKILL.md +58 -0
- package/skills/service-mesh-observability/SKILL.md +395 -0
- package/skills/shellcheck-configuration/SKILL.md +466 -0
- package/skills/similarity-search-patterns/SKILL.md +33 -0
- package/skills/similarity-search-patterns/resources/implementation-playbook.md +557 -0
- package/skills/slo-implementation/SKILL.md +341 -0
- package/skills/solidity-security/SKILL.md +34 -0
- package/skills/solidity-security/resources/implementation-playbook.md +524 -0
- package/skills/spark-optimization/SKILL.md +427 -0
- package/skills/sql-optimization-patterns/SKILL.md +35 -0
- package/skills/sql-optimization-patterns/resources/implementation-playbook.md +504 -0
- package/skills/sql-pro/SKILL.md +173 -0
- package/skills/startup-analyst/SKILL.md +328 -0
- package/skills/startup-business-analyst-business-case/SKILL.md +487 -0
- package/skills/startup-business-analyst-financial-projections/SKILL.md +353 -0
- package/skills/startup-business-analyst-market-opportunity/SKILL.md +240 -0
- package/skills/startup-financial-modeling/SKILL.md +467 -0
- package/skills/startup-metrics-framework/SKILL.md +34 -0
- package/skills/startup-metrics-framework/resources/implementation-playbook.md +500 -0
- package/skills/stride-analysis-patterns/SKILL.md +33 -0
- package/skills/stride-analysis-patterns/resources/implementation-playbook.md +655 -0
- package/skills/stripe-integration/SKILL.md +454 -0
- package/skills/systems-programming-rust-project/SKILL.md +440 -0
- package/skills/tailwind-design-system/SKILL.md +33 -0
- package/skills/tailwind-design-system/resources/implementation-playbook.md +665 -0
- package/skills/tdd-orchestrator/SKILL.md +205 -0
- package/skills/tdd-workflows-tdd-cycle/SKILL.md +221 -0
- package/skills/tdd-workflows-tdd-green/SKILL.md +73 -0
- package/skills/tdd-workflows-tdd-green/resources/implementation-playbook.md +870 -0
- package/skills/tdd-workflows-tdd-red/SKILL.md +164 -0
- package/skills/tdd-workflows-tdd-refactor/SKILL.md +187 -0
- package/skills/team-collaboration-issue/SKILL.md +37 -0
- package/skills/team-collaboration-issue/resources/implementation-playbook.md +640 -0
- package/skills/team-collaboration-standup-notes/SKILL.md +44 -0
- package/skills/team-collaboration-standup-notes/resources/implementation-playbook.md +768 -0
- package/skills/team-composition-analysis/SKILL.md +413 -0
- package/skills/temporal-python-pro/SKILL.md +370 -0
- package/skills/temporal-python-testing/SKILL.md +170 -0
- package/skills/temporal-python-testing/resources/integration-testing.md +455 -0
- package/skills/temporal-python-testing/resources/local-setup.md +553 -0
- package/skills/temporal-python-testing/resources/replay-testing.md +462 -0
- package/skills/temporal-python-testing/resources/unit-testing.md +328 -0
- package/skills/terraform-module-library/SKILL.md +261 -0
- package/skills/terraform-module-library/references/aws-modules.md +63 -0
- package/skills/terraform-specialist/SKILL.md +166 -0
- package/skills/test-automator/SKILL.md +224 -0
- package/skills/threat-mitigation-mapping/SKILL.md +33 -0
- package/skills/threat-mitigation-mapping/resources/implementation-playbook.md +744 -0
- package/skills/threat-modeling-expert/SKILL.md +60 -0
- package/skills/track-management/SKILL.md +38 -0
- package/skills/track-management/resources/implementation-playbook.md +591 -0
- package/skills/turborepo-caching/SKILL.md +419 -0
- package/skills/tutorial-engineer/SKILL.md +139 -0
- package/skills/typescript-advanced-types/SKILL.md +35 -0
- package/skills/typescript-advanced-types/resources/implementation-playbook.md +716 -0
- package/skills/typescript-pro/SKILL.md +55 -0
- package/skills/ui-minimal/SKILL.md +23 -0
- package/skills/ui-ux-designer/SKILL.md +209 -0
- package/skills/ui-visual-validator/SKILL.md +214 -0
- package/skills/unit-testing-test-generate/SKILL.md +319 -0
- package/skills/unity-developer/SKILL.md +230 -0
- package/skills/unity-ecs-patterns/SKILL.md +33 -0
- package/skills/unity-ecs-patterns/resources/implementation-playbook.md +625 -0
- package/skills/uv-package-manager/SKILL.md +37 -0
- package/skills/uv-package-manager/resources/implementation-playbook.md +830 -0
- package/skills/vector-database-engineer/SKILL.md +60 -0
- package/skills/vector-index-tuning/SKILL.md +42 -0
- package/skills/vector-index-tuning/resources/implementation-playbook.md +507 -0
- package/skills/wcag-audit-patterns/SKILL.md +41 -0
- package/skills/wcag-audit-patterns/resources/implementation-playbook.md +541 -0
- package/skills/web3-testing/SKILL.md +427 -0
- package/skills/workflow-orchestration-patterns/SKILL.md +333 -0
- package/skills/workflow-patterns/SKILL.md +38 -0
- package/skills/workflow-patterns/resources/implementation-playbook.md +621 -0
|
@@ -0,0 +1,906 @@
|
|
|
1
|
+
# Python Testing Patterns Implementation Playbook
|
|
2
|
+
|
|
3
|
+
This file contains detailed patterns, checklists, and code samples referenced by the skill.
|
|
4
|
+
|
|
5
|
+
# Python Testing Patterns
|
|
6
|
+
|
|
7
|
+
Comprehensive guide to implementing robust testing strategies in Python using pytest, fixtures, mocking, parameterization, and test-driven development practices.
|
|
8
|
+
|
|
9
|
+
## When to Use This Skill
|
|
10
|
+
|
|
11
|
+
- Writing unit tests for Python code
|
|
12
|
+
- Setting up test suites and test infrastructure
|
|
13
|
+
- Implementing test-driven development (TDD)
|
|
14
|
+
- Creating integration tests for APIs and services
|
|
15
|
+
- Mocking external dependencies and services
|
|
16
|
+
- Testing async code and concurrent operations
|
|
17
|
+
- Setting up continuous testing in CI/CD
|
|
18
|
+
- Implementing property-based testing
|
|
19
|
+
- Testing database operations
|
|
20
|
+
- Debugging failing tests
|
|
21
|
+
|
|
22
|
+
## Core Concepts
|
|
23
|
+
|
|
24
|
+
### 1. Test Types
|
|
25
|
+
- **Unit Tests**: Test individual functions/classes in isolation
|
|
26
|
+
- **Integration Tests**: Test interaction between components
|
|
27
|
+
- **Functional Tests**: Test complete features end-to-end
|
|
28
|
+
- **Performance Tests**: Measure speed and resource usage
|
|
29
|
+
|
|
30
|
+
### 2. Test Structure (AAA Pattern)
|
|
31
|
+
- **Arrange**: Set up test data and preconditions
|
|
32
|
+
- **Act**: Execute the code under test
|
|
33
|
+
- **Assert**: Verify the results
|
|
34
|
+
|
|
35
|
+
### 3. Test Coverage
|
|
36
|
+
- Measure what code is exercised by tests
|
|
37
|
+
- Identify untested code paths
|
|
38
|
+
- Aim for meaningful coverage, not just high percentages
|
|
39
|
+
|
|
40
|
+
### 4. Test Isolation
|
|
41
|
+
- Tests should be independent
|
|
42
|
+
- No shared state between tests
|
|
43
|
+
- Each test should clean up after itself
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
# test_example.py
|
|
49
|
+
def add(a, b):
|
|
50
|
+
return a + b
|
|
51
|
+
|
|
52
|
+
def test_add():
|
|
53
|
+
"""Basic test example."""
|
|
54
|
+
result = add(2, 3)
|
|
55
|
+
assert result == 5
|
|
56
|
+
|
|
57
|
+
def test_add_negative():
|
|
58
|
+
"""Test with negative numbers."""
|
|
59
|
+
assert add(-1, 1) == 0
|
|
60
|
+
|
|
61
|
+
# Run with: pytest test_example.py
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Fundamental Patterns
|
|
65
|
+
|
|
66
|
+
### Pattern 1: Basic pytest Tests
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
# test_calculator.py
|
|
70
|
+
import pytest
|
|
71
|
+
|
|
72
|
+
class Calculator:
|
|
73
|
+
"""Simple calculator for testing."""
|
|
74
|
+
|
|
75
|
+
def add(self, a: float, b: float) -> float:
|
|
76
|
+
return a + b
|
|
77
|
+
|
|
78
|
+
def subtract(self, a: float, b: float) -> float:
|
|
79
|
+
return a - b
|
|
80
|
+
|
|
81
|
+
def multiply(self, a: float, b: float) -> float:
|
|
82
|
+
return a * b
|
|
83
|
+
|
|
84
|
+
def divide(self, a: float, b: float) -> float:
|
|
85
|
+
if b == 0:
|
|
86
|
+
raise ValueError("Cannot divide by zero")
|
|
87
|
+
return a / b
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_addition():
|
|
91
|
+
"""Test addition."""
|
|
92
|
+
calc = Calculator()
|
|
93
|
+
assert calc.add(2, 3) == 5
|
|
94
|
+
assert calc.add(-1, 1) == 0
|
|
95
|
+
assert calc.add(0, 0) == 0
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_subtraction():
|
|
99
|
+
"""Test subtraction."""
|
|
100
|
+
calc = Calculator()
|
|
101
|
+
assert calc.subtract(5, 3) == 2
|
|
102
|
+
assert calc.subtract(0, 5) == -5
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_multiplication():
|
|
106
|
+
"""Test multiplication."""
|
|
107
|
+
calc = Calculator()
|
|
108
|
+
assert calc.multiply(3, 4) == 12
|
|
109
|
+
assert calc.multiply(0, 5) == 0
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_division():
|
|
113
|
+
"""Test division."""
|
|
114
|
+
calc = Calculator()
|
|
115
|
+
assert calc.divide(6, 3) == 2
|
|
116
|
+
assert calc.divide(5, 2) == 2.5
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_division_by_zero():
|
|
120
|
+
"""Test division by zero raises error."""
|
|
121
|
+
calc = Calculator()
|
|
122
|
+
with pytest.raises(ValueError, match="Cannot divide by zero"):
|
|
123
|
+
calc.divide(5, 0)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Pattern 2: Fixtures for Setup and Teardown
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
# test_database.py
|
|
130
|
+
import pytest
|
|
131
|
+
from typing import Generator
|
|
132
|
+
|
|
133
|
+
class Database:
|
|
134
|
+
"""Simple database class."""
|
|
135
|
+
|
|
136
|
+
def __init__(self, connection_string: str):
|
|
137
|
+
self.connection_string = connection_string
|
|
138
|
+
self.connected = False
|
|
139
|
+
|
|
140
|
+
def connect(self):
|
|
141
|
+
"""Connect to database."""
|
|
142
|
+
self.connected = True
|
|
143
|
+
|
|
144
|
+
def disconnect(self):
|
|
145
|
+
"""Disconnect from database."""
|
|
146
|
+
self.connected = False
|
|
147
|
+
|
|
148
|
+
def query(self, sql: str) -> list:
|
|
149
|
+
"""Execute query."""
|
|
150
|
+
if not self.connected:
|
|
151
|
+
raise RuntimeError("Not connected")
|
|
152
|
+
return [{"id": 1, "name": "Test"}]
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@pytest.fixture
|
|
156
|
+
def db() -> Generator[Database, None, None]:
|
|
157
|
+
"""Fixture that provides connected database."""
|
|
158
|
+
# Setup
|
|
159
|
+
database = Database("sqlite:///:memory:")
|
|
160
|
+
database.connect()
|
|
161
|
+
|
|
162
|
+
# Provide to test
|
|
163
|
+
yield database
|
|
164
|
+
|
|
165
|
+
# Teardown
|
|
166
|
+
database.disconnect()
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_database_query(db):
|
|
170
|
+
"""Test database query with fixture."""
|
|
171
|
+
results = db.query("SELECT * FROM users")
|
|
172
|
+
assert len(results) == 1
|
|
173
|
+
assert results[0]["name"] == "Test"
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@pytest.fixture(scope="session")
|
|
177
|
+
def app_config():
|
|
178
|
+
"""Session-scoped fixture - created once per test session."""
|
|
179
|
+
return {
|
|
180
|
+
"database_url": "postgresql://localhost/test",
|
|
181
|
+
"api_key": "test-key",
|
|
182
|
+
"debug": True
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@pytest.fixture(scope="module")
|
|
187
|
+
def api_client(app_config):
|
|
188
|
+
"""Module-scoped fixture - created once per test module."""
|
|
189
|
+
# Setup expensive resource
|
|
190
|
+
client = {"config": app_config, "session": "active"}
|
|
191
|
+
yield client
|
|
192
|
+
# Cleanup
|
|
193
|
+
client["session"] = "closed"
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def test_api_client(api_client):
|
|
197
|
+
"""Test using api client fixture."""
|
|
198
|
+
assert api_client["session"] == "active"
|
|
199
|
+
assert api_client["config"]["debug"] is True
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Pattern 3: Parameterized Tests
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
# test_validation.py
|
|
206
|
+
import pytest
|
|
207
|
+
|
|
208
|
+
def is_valid_email(email: str) -> bool:
|
|
209
|
+
"""Check if email is valid."""
|
|
210
|
+
return "@" in email and "." in email.split("@")[1]
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
@pytest.mark.parametrize("email,expected", [
|
|
214
|
+
("user@example.com", True),
|
|
215
|
+
("test.user@domain.co.uk", True),
|
|
216
|
+
("invalid.email", False),
|
|
217
|
+
("@example.com", False),
|
|
218
|
+
("user@domain", False),
|
|
219
|
+
("", False),
|
|
220
|
+
])
|
|
221
|
+
def test_email_validation(email, expected):
|
|
222
|
+
"""Test email validation with various inputs."""
|
|
223
|
+
assert is_valid_email(email) == expected
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@pytest.mark.parametrize("a,b,expected", [
|
|
227
|
+
(2, 3, 5),
|
|
228
|
+
(0, 0, 0),
|
|
229
|
+
(-1, 1, 0),
|
|
230
|
+
(100, 200, 300),
|
|
231
|
+
(-5, -5, -10),
|
|
232
|
+
])
|
|
233
|
+
def test_addition_parameterized(a, b, expected):
|
|
234
|
+
"""Test addition with multiple parameter sets."""
|
|
235
|
+
from test_calculator import Calculator
|
|
236
|
+
calc = Calculator()
|
|
237
|
+
assert calc.add(a, b) == expected
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
# Using pytest.param for special cases
|
|
241
|
+
@pytest.mark.parametrize("value,expected", [
|
|
242
|
+
pytest.param(1, True, id="positive"),
|
|
243
|
+
pytest.param(0, False, id="zero"),
|
|
244
|
+
pytest.param(-1, False, id="negative"),
|
|
245
|
+
])
|
|
246
|
+
def test_is_positive(value, expected):
|
|
247
|
+
"""Test with custom test IDs."""
|
|
248
|
+
assert (value > 0) == expected
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Pattern 4: Mocking with unittest.mock
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
# test_api_client.py
|
|
255
|
+
import pytest
|
|
256
|
+
from unittest.mock import Mock, patch, MagicMock
|
|
257
|
+
import requests
|
|
258
|
+
|
|
259
|
+
class APIClient:
|
|
260
|
+
"""Simple API client."""
|
|
261
|
+
|
|
262
|
+
def __init__(self, base_url: str):
|
|
263
|
+
self.base_url = base_url
|
|
264
|
+
|
|
265
|
+
def get_user(self, user_id: int) -> dict:
|
|
266
|
+
"""Fetch user from API."""
|
|
267
|
+
response = requests.get(f"{self.base_url}/users/{user_id}")
|
|
268
|
+
response.raise_for_status()
|
|
269
|
+
return response.json()
|
|
270
|
+
|
|
271
|
+
def create_user(self, data: dict) -> dict:
|
|
272
|
+
"""Create new user."""
|
|
273
|
+
response = requests.post(f"{self.base_url}/users", json=data)
|
|
274
|
+
response.raise_for_status()
|
|
275
|
+
return response.json()
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def test_get_user_success():
|
|
279
|
+
"""Test successful API call with mock."""
|
|
280
|
+
client = APIClient("https://api.example.com")
|
|
281
|
+
|
|
282
|
+
mock_response = Mock()
|
|
283
|
+
mock_response.json.return_value = {"id": 1, "name": "John Doe"}
|
|
284
|
+
mock_response.raise_for_status.return_value = None
|
|
285
|
+
|
|
286
|
+
with patch("requests.get", return_value=mock_response) as mock_get:
|
|
287
|
+
user = client.get_user(1)
|
|
288
|
+
|
|
289
|
+
assert user["id"] == 1
|
|
290
|
+
assert user["name"] == "John Doe"
|
|
291
|
+
mock_get.assert_called_once_with("https://api.example.com/users/1")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def test_get_user_not_found():
|
|
295
|
+
"""Test API call with 404 error."""
|
|
296
|
+
client = APIClient("https://api.example.com")
|
|
297
|
+
|
|
298
|
+
mock_response = Mock()
|
|
299
|
+
mock_response.raise_for_status.side_effect = requests.HTTPError("404 Not Found")
|
|
300
|
+
|
|
301
|
+
with patch("requests.get", return_value=mock_response):
|
|
302
|
+
with pytest.raises(requests.HTTPError):
|
|
303
|
+
client.get_user(999)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@patch("requests.post")
|
|
307
|
+
def test_create_user(mock_post):
|
|
308
|
+
"""Test user creation with decorator syntax."""
|
|
309
|
+
client = APIClient("https://api.example.com")
|
|
310
|
+
|
|
311
|
+
mock_post.return_value.json.return_value = {"id": 2, "name": "Jane Doe"}
|
|
312
|
+
mock_post.return_value.raise_for_status.return_value = None
|
|
313
|
+
|
|
314
|
+
user_data = {"name": "Jane Doe", "email": "jane@example.com"}
|
|
315
|
+
result = client.create_user(user_data)
|
|
316
|
+
|
|
317
|
+
assert result["id"] == 2
|
|
318
|
+
mock_post.assert_called_once()
|
|
319
|
+
call_args = mock_post.call_args
|
|
320
|
+
assert call_args.kwargs["json"] == user_data
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Pattern 5: Testing Exceptions
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
# test_exceptions.py
|
|
327
|
+
import pytest
|
|
328
|
+
|
|
329
|
+
def divide(a: float, b: float) -> float:
|
|
330
|
+
"""Divide a by b."""
|
|
331
|
+
if b == 0:
|
|
332
|
+
raise ZeroDivisionError("Division by zero")
|
|
333
|
+
if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
|
|
334
|
+
raise TypeError("Arguments must be numbers")
|
|
335
|
+
return a / b
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def test_zero_division():
|
|
339
|
+
"""Test exception is raised for division by zero."""
|
|
340
|
+
with pytest.raises(ZeroDivisionError):
|
|
341
|
+
divide(10, 0)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def test_zero_division_with_message():
|
|
345
|
+
"""Test exception message."""
|
|
346
|
+
with pytest.raises(ZeroDivisionError, match="Division by zero"):
|
|
347
|
+
divide(5, 0)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def test_type_error():
|
|
351
|
+
"""Test type error exception."""
|
|
352
|
+
with pytest.raises(TypeError, match="must be numbers"):
|
|
353
|
+
divide("10", 5)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def test_exception_info():
|
|
357
|
+
"""Test accessing exception info."""
|
|
358
|
+
with pytest.raises(ValueError) as exc_info:
|
|
359
|
+
int("not a number")
|
|
360
|
+
|
|
361
|
+
assert "invalid literal" in str(exc_info.value)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Advanced Patterns
|
|
365
|
+
|
|
366
|
+
### Pattern 6: Testing Async Code
|
|
367
|
+
|
|
368
|
+
```python
|
|
369
|
+
# test_async.py
|
|
370
|
+
import pytest
|
|
371
|
+
import asyncio
|
|
372
|
+
|
|
373
|
+
async def fetch_data(url: str) -> dict:
|
|
374
|
+
"""Fetch data asynchronously."""
|
|
375
|
+
await asyncio.sleep(0.1)
|
|
376
|
+
return {"url": url, "data": "result"}
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
@pytest.mark.asyncio
|
|
380
|
+
async def test_fetch_data():
|
|
381
|
+
"""Test async function."""
|
|
382
|
+
result = await fetch_data("https://api.example.com")
|
|
383
|
+
assert result["url"] == "https://api.example.com"
|
|
384
|
+
assert "data" in result
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@pytest.mark.asyncio
|
|
388
|
+
async def test_concurrent_fetches():
|
|
389
|
+
"""Test concurrent async operations."""
|
|
390
|
+
urls = ["url1", "url2", "url3"]
|
|
391
|
+
tasks = [fetch_data(url) for url in urls]
|
|
392
|
+
results = await asyncio.gather(*tasks)
|
|
393
|
+
|
|
394
|
+
assert len(results) == 3
|
|
395
|
+
assert all("data" in r for r in results)
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
@pytest.fixture
|
|
399
|
+
async def async_client():
|
|
400
|
+
"""Async fixture."""
|
|
401
|
+
client = {"connected": True}
|
|
402
|
+
yield client
|
|
403
|
+
client["connected"] = False
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
@pytest.mark.asyncio
|
|
407
|
+
async def test_with_async_fixture(async_client):
|
|
408
|
+
"""Test using async fixture."""
|
|
409
|
+
assert async_client["connected"] is True
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Pattern 7: Monkeypatch for Testing
|
|
413
|
+
|
|
414
|
+
```python
|
|
415
|
+
# test_environment.py
|
|
416
|
+
import os
|
|
417
|
+
import pytest
|
|
418
|
+
|
|
419
|
+
def get_database_url() -> str:
|
|
420
|
+
"""Get database URL from environment."""
|
|
421
|
+
return os.environ.get("DATABASE_URL", "sqlite:///:memory:")
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def test_database_url_default():
|
|
425
|
+
"""Test default database URL."""
|
|
426
|
+
# Will use actual environment variable if set
|
|
427
|
+
url = get_database_url()
|
|
428
|
+
assert url
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def test_database_url_custom(monkeypatch):
|
|
432
|
+
"""Test custom database URL with monkeypatch."""
|
|
433
|
+
monkeypatch.setenv("DATABASE_URL", "postgresql://localhost/test")
|
|
434
|
+
assert get_database_url() == "postgresql://localhost/test"
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def test_database_url_not_set(monkeypatch):
|
|
438
|
+
"""Test when env var is not set."""
|
|
439
|
+
monkeypatch.delenv("DATABASE_URL", raising=False)
|
|
440
|
+
assert get_database_url() == "sqlite:///:memory:"
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
class Config:
|
|
444
|
+
"""Configuration class."""
|
|
445
|
+
|
|
446
|
+
def __init__(self):
|
|
447
|
+
self.api_key = "production-key"
|
|
448
|
+
|
|
449
|
+
def get_api_key(self):
|
|
450
|
+
return self.api_key
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def test_monkeypatch_attribute(monkeypatch):
|
|
454
|
+
"""Test monkeypatching object attributes."""
|
|
455
|
+
config = Config()
|
|
456
|
+
monkeypatch.setattr(config, "api_key", "test-key")
|
|
457
|
+
assert config.get_api_key() == "test-key"
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Pattern 8: Temporary Files and Directories
|
|
461
|
+
|
|
462
|
+
```python
|
|
463
|
+
# test_file_operations.py
|
|
464
|
+
import pytest
|
|
465
|
+
from pathlib import Path
|
|
466
|
+
|
|
467
|
+
def save_data(filepath: Path, data: str):
|
|
468
|
+
"""Save data to file."""
|
|
469
|
+
filepath.write_text(data)
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
def load_data(filepath: Path) -> str:
|
|
473
|
+
"""Load data from file."""
|
|
474
|
+
return filepath.read_text()
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def test_file_operations(tmp_path):
|
|
478
|
+
"""Test file operations with temporary directory."""
|
|
479
|
+
# tmp_path is a pathlib.Path object
|
|
480
|
+
test_file = tmp_path / "test_data.txt"
|
|
481
|
+
|
|
482
|
+
# Save data
|
|
483
|
+
save_data(test_file, "Hello, World!")
|
|
484
|
+
|
|
485
|
+
# Verify file exists
|
|
486
|
+
assert test_file.exists()
|
|
487
|
+
|
|
488
|
+
# Load and verify data
|
|
489
|
+
data = load_data(test_file)
|
|
490
|
+
assert data == "Hello, World!"
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def test_multiple_files(tmp_path):
|
|
494
|
+
"""Test with multiple temporary files."""
|
|
495
|
+
files = {
|
|
496
|
+
"file1.txt": "Content 1",
|
|
497
|
+
"file2.txt": "Content 2",
|
|
498
|
+
"file3.txt": "Content 3"
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
for filename, content in files.items():
|
|
502
|
+
filepath = tmp_path / filename
|
|
503
|
+
save_data(filepath, content)
|
|
504
|
+
|
|
505
|
+
# Verify all files created
|
|
506
|
+
assert len(list(tmp_path.iterdir())) == 3
|
|
507
|
+
|
|
508
|
+
# Verify contents
|
|
509
|
+
for filename, expected_content in files.items():
|
|
510
|
+
filepath = tmp_path / filename
|
|
511
|
+
assert load_data(filepath) == expected_content
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Pattern 9: Custom Fixtures and Conftest
|
|
515
|
+
|
|
516
|
+
```python
|
|
517
|
+
# conftest.py
|
|
518
|
+
"""Shared fixtures for all tests."""
|
|
519
|
+
import pytest
|
|
520
|
+
|
|
521
|
+
@pytest.fixture(scope="session")
|
|
522
|
+
def database_url():
|
|
523
|
+
"""Provide database URL for all tests."""
|
|
524
|
+
return "postgresql://localhost/test_db"
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
@pytest.fixture(autouse=True)
|
|
528
|
+
def reset_database(database_url):
|
|
529
|
+
"""Auto-use fixture that runs before each test."""
|
|
530
|
+
# Setup: Clear database
|
|
531
|
+
print(f"Clearing database: {database_url}")
|
|
532
|
+
yield
|
|
533
|
+
# Teardown: Clean up
|
|
534
|
+
print("Test completed")
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
@pytest.fixture
|
|
538
|
+
def sample_user():
|
|
539
|
+
"""Provide sample user data."""
|
|
540
|
+
return {
|
|
541
|
+
"id": 1,
|
|
542
|
+
"name": "Test User",
|
|
543
|
+
"email": "test@example.com"
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
@pytest.fixture
|
|
548
|
+
def sample_users():
|
|
549
|
+
"""Provide list of sample users."""
|
|
550
|
+
return [
|
|
551
|
+
{"id": 1, "name": "User 1"},
|
|
552
|
+
{"id": 2, "name": "User 2"},
|
|
553
|
+
{"id": 3, "name": "User 3"},
|
|
554
|
+
]
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
# Parametrized fixture
|
|
558
|
+
@pytest.fixture(params=["sqlite", "postgresql", "mysql"])
|
|
559
|
+
def db_backend(request):
|
|
560
|
+
"""Fixture that runs tests with different database backends."""
|
|
561
|
+
return request.param
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
def test_with_db_backend(db_backend):
|
|
565
|
+
"""This test will run 3 times with different backends."""
|
|
566
|
+
print(f"Testing with {db_backend}")
|
|
567
|
+
assert db_backend in ["sqlite", "postgresql", "mysql"]
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Pattern 10: Property-Based Testing
|
|
571
|
+
|
|
572
|
+
```python
|
|
573
|
+
# test_properties.py
|
|
574
|
+
from hypothesis import given, strategies as st
|
|
575
|
+
import pytest
|
|
576
|
+
|
|
577
|
+
def reverse_string(s: str) -> str:
|
|
578
|
+
"""Reverse a string."""
|
|
579
|
+
return s[::-1]
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
@given(st.text())
|
|
583
|
+
def test_reverse_twice_is_original(s):
|
|
584
|
+
"""Property: reversing twice returns original."""
|
|
585
|
+
assert reverse_string(reverse_string(s)) == s
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
@given(st.text())
|
|
589
|
+
def test_reverse_length(s):
|
|
590
|
+
"""Property: reversed string has same length."""
|
|
591
|
+
assert len(reverse_string(s)) == len(s)
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
@given(st.integers(), st.integers())
|
|
595
|
+
def test_addition_commutative(a, b):
|
|
596
|
+
"""Property: addition is commutative."""
|
|
597
|
+
assert a + b == b + a
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
@given(st.lists(st.integers()))
|
|
601
|
+
def test_sorted_list_properties(lst):
|
|
602
|
+
"""Property: sorted list is ordered."""
|
|
603
|
+
sorted_lst = sorted(lst)
|
|
604
|
+
|
|
605
|
+
# Same length
|
|
606
|
+
assert len(sorted_lst) == len(lst)
|
|
607
|
+
|
|
608
|
+
# All elements present
|
|
609
|
+
assert set(sorted_lst) == set(lst)
|
|
610
|
+
|
|
611
|
+
# Is ordered
|
|
612
|
+
for i in range(len(sorted_lst) - 1):
|
|
613
|
+
assert sorted_lst[i] <= sorted_lst[i + 1]
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
## Testing Best Practices
|
|
617
|
+
|
|
618
|
+
### Test Organization
|
|
619
|
+
|
|
620
|
+
```python
|
|
621
|
+
# tests/
|
|
622
|
+
# __init__.py
|
|
623
|
+
# conftest.py # Shared fixtures
|
|
624
|
+
# test_unit/ # Unit tests
|
|
625
|
+
# test_models.py
|
|
626
|
+
# test_utils.py
|
|
627
|
+
# test_integration/ # Integration tests
|
|
628
|
+
# test_api.py
|
|
629
|
+
# test_database.py
|
|
630
|
+
# test_e2e/ # End-to-end tests
|
|
631
|
+
# test_workflows.py
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Test Naming
|
|
635
|
+
|
|
636
|
+
```python
|
|
637
|
+
# Good test names
|
|
638
|
+
def test_user_creation_with_valid_data():
|
|
639
|
+
"""Clear name describes what is being tested."""
|
|
640
|
+
pass
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
def test_login_fails_with_invalid_password():
|
|
644
|
+
"""Name describes expected behavior."""
|
|
645
|
+
pass
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
def test_api_returns_404_for_missing_resource():
|
|
649
|
+
"""Specific about inputs and expected outcomes."""
|
|
650
|
+
pass
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
# Bad test names
|
|
654
|
+
def test_1(): # Not descriptive
|
|
655
|
+
pass
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
def test_user(): # Too vague
|
|
659
|
+
pass
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
def test_function(): # Doesn't explain what's tested
|
|
663
|
+
pass
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### Test Markers
|
|
667
|
+
|
|
668
|
+
```python
|
|
669
|
+
# test_markers.py
|
|
670
|
+
import pytest
|
|
671
|
+
|
|
672
|
+
@pytest.mark.slow
|
|
673
|
+
def test_slow_operation():
|
|
674
|
+
"""Mark slow tests."""
|
|
675
|
+
import time
|
|
676
|
+
time.sleep(2)
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
@pytest.mark.integration
|
|
680
|
+
def test_database_integration():
|
|
681
|
+
"""Mark integration tests."""
|
|
682
|
+
pass
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
@pytest.mark.skip(reason="Feature not implemented yet")
|
|
686
|
+
def test_future_feature():
|
|
687
|
+
"""Skip tests temporarily."""
|
|
688
|
+
pass
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
@pytest.mark.skipif(os.name == "nt", reason="Unix only test")
|
|
692
|
+
def test_unix_specific():
|
|
693
|
+
"""Conditional skip."""
|
|
694
|
+
pass
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
@pytest.mark.xfail(reason="Known bug #123")
|
|
698
|
+
def test_known_bug():
|
|
699
|
+
"""Mark expected failures."""
|
|
700
|
+
assert False
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
# Run with:
|
|
704
|
+
# pytest -m slow # Run only slow tests
|
|
705
|
+
# pytest -m "not slow" # Skip slow tests
|
|
706
|
+
# pytest -m integration # Run integration tests
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### Coverage Reporting
|
|
710
|
+
|
|
711
|
+
```bash
|
|
712
|
+
# Install coverage
|
|
713
|
+
pip install pytest-cov
|
|
714
|
+
|
|
715
|
+
# Run tests with coverage
|
|
716
|
+
pytest --cov=myapp tests/
|
|
717
|
+
|
|
718
|
+
# Generate HTML report
|
|
719
|
+
pytest --cov=myapp --cov-report=html tests/
|
|
720
|
+
|
|
721
|
+
# Fail if coverage below threshold
|
|
722
|
+
pytest --cov=myapp --cov-fail-under=80 tests/
|
|
723
|
+
|
|
724
|
+
# Show missing lines
|
|
725
|
+
pytest --cov=myapp --cov-report=term-missing tests/
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
## Testing Database Code
|
|
729
|
+
|
|
730
|
+
```python
|
|
731
|
+
# test_database_models.py
|
|
732
|
+
import pytest
|
|
733
|
+
from sqlalchemy import create_engine, Column, Integer, String
|
|
734
|
+
from sqlalchemy.ext.declarative import declarative_base
|
|
735
|
+
from sqlalchemy.orm import sessionmaker, Session
|
|
736
|
+
|
|
737
|
+
Base = declarative_base()
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
class User(Base):
|
|
741
|
+
"""User model."""
|
|
742
|
+
__tablename__ = "users"
|
|
743
|
+
|
|
744
|
+
id = Column(Integer, primary_key=True)
|
|
745
|
+
name = Column(String(50))
|
|
746
|
+
email = Column(String(100), unique=True)
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
@pytest.fixture(scope="function")
|
|
750
|
+
def db_session() -> Session:
|
|
751
|
+
"""Create in-memory database for testing."""
|
|
752
|
+
engine = create_engine("sqlite:///:memory:")
|
|
753
|
+
Base.metadata.create_all(engine)
|
|
754
|
+
|
|
755
|
+
SessionLocal = sessionmaker(bind=engine)
|
|
756
|
+
session = SessionLocal()
|
|
757
|
+
|
|
758
|
+
yield session
|
|
759
|
+
|
|
760
|
+
session.close()
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
def test_create_user(db_session):
|
|
764
|
+
"""Test creating a user."""
|
|
765
|
+
user = User(name="Test User", email="test@example.com")
|
|
766
|
+
db_session.add(user)
|
|
767
|
+
db_session.commit()
|
|
768
|
+
|
|
769
|
+
assert user.id is not None
|
|
770
|
+
assert user.name == "Test User"
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
def test_query_user(db_session):
|
|
774
|
+
"""Test querying users."""
|
|
775
|
+
user1 = User(name="User 1", email="user1@example.com")
|
|
776
|
+
user2 = User(name="User 2", email="user2@example.com")
|
|
777
|
+
|
|
778
|
+
db_session.add_all([user1, user2])
|
|
779
|
+
db_session.commit()
|
|
780
|
+
|
|
781
|
+
users = db_session.query(User).all()
|
|
782
|
+
assert len(users) == 2
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
def test_unique_email_constraint(db_session):
|
|
786
|
+
"""Test unique email constraint."""
|
|
787
|
+
from sqlalchemy.exc import IntegrityError
|
|
788
|
+
|
|
789
|
+
user1 = User(name="User 1", email="same@example.com")
|
|
790
|
+
user2 = User(name="User 2", email="same@example.com")
|
|
791
|
+
|
|
792
|
+
db_session.add(user1)
|
|
793
|
+
db_session.commit()
|
|
794
|
+
|
|
795
|
+
db_session.add(user2)
|
|
796
|
+
|
|
797
|
+
with pytest.raises(IntegrityError):
|
|
798
|
+
db_session.commit()
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
## CI/CD Integration
|
|
802
|
+
|
|
803
|
+
```yaml
|
|
804
|
+
# .github/workflows/test.yml
|
|
805
|
+
name: Tests
|
|
806
|
+
|
|
807
|
+
on: [push, pull_request]
|
|
808
|
+
|
|
809
|
+
jobs:
|
|
810
|
+
test:
|
|
811
|
+
runs-on: ubuntu-latest
|
|
812
|
+
|
|
813
|
+
strategy:
|
|
814
|
+
matrix:
|
|
815
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
816
|
+
|
|
817
|
+
steps:
|
|
818
|
+
- uses: actions/checkout@v3
|
|
819
|
+
|
|
820
|
+
- name: Set up Python
|
|
821
|
+
uses: actions/setup-python@v4
|
|
822
|
+
with:
|
|
823
|
+
python-version: ${{ matrix.python-version }}
|
|
824
|
+
|
|
825
|
+
- name: Install dependencies
|
|
826
|
+
run: |
|
|
827
|
+
pip install -e ".[dev]"
|
|
828
|
+
pip install pytest pytest-cov
|
|
829
|
+
|
|
830
|
+
- name: Run tests
|
|
831
|
+
run: |
|
|
832
|
+
pytest --cov=myapp --cov-report=xml
|
|
833
|
+
|
|
834
|
+
- name: Upload coverage
|
|
835
|
+
uses: codecov/codecov-action@v3
|
|
836
|
+
with:
|
|
837
|
+
file: ./coverage.xml
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
## Configuration Files
|
|
841
|
+
|
|
842
|
+
```ini
|
|
843
|
+
# pytest.ini
|
|
844
|
+
[pytest]
|
|
845
|
+
testpaths = tests
|
|
846
|
+
python_files = test_*.py
|
|
847
|
+
python_classes = Test*
|
|
848
|
+
python_functions = test_*
|
|
849
|
+
addopts =
|
|
850
|
+
-v
|
|
851
|
+
--strict-markers
|
|
852
|
+
--tb=short
|
|
853
|
+
--cov=myapp
|
|
854
|
+
--cov-report=term-missing
|
|
855
|
+
markers =
|
|
856
|
+
slow: marks tests as slow
|
|
857
|
+
integration: marks integration tests
|
|
858
|
+
unit: marks unit tests
|
|
859
|
+
e2e: marks end-to-end tests
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
```toml
|
|
863
|
+
# pyproject.toml
|
|
864
|
+
[tool.pytest.ini_options]
|
|
865
|
+
testpaths = ["tests"]
|
|
866
|
+
python_files = ["test_*.py"]
|
|
867
|
+
addopts = [
|
|
868
|
+
"-v",
|
|
869
|
+
"--cov=myapp",
|
|
870
|
+
"--cov-report=term-missing",
|
|
871
|
+
]
|
|
872
|
+
|
|
873
|
+
[tool.coverage.run]
|
|
874
|
+
source = ["myapp"]
|
|
875
|
+
omit = ["*/tests/*", "*/migrations/*"]
|
|
876
|
+
|
|
877
|
+
[tool.coverage.report]
|
|
878
|
+
exclude_lines = [
|
|
879
|
+
"pragma: no cover",
|
|
880
|
+
"def __repr__",
|
|
881
|
+
"raise AssertionError",
|
|
882
|
+
"raise NotImplementedError",
|
|
883
|
+
]
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
## Resources
|
|
887
|
+
|
|
888
|
+
- **pytest documentation**: https://docs.pytest.org/
|
|
889
|
+
- **unittest.mock**: https://docs.python.org/3/library/unittest.mock.html
|
|
890
|
+
- **hypothesis**: Property-based testing
|
|
891
|
+
- **pytest-asyncio**: Testing async code
|
|
892
|
+
- **pytest-cov**: Coverage reporting
|
|
893
|
+
- **pytest-mock**: pytest wrapper for mock
|
|
894
|
+
|
|
895
|
+
## Best Practices Summary
|
|
896
|
+
|
|
897
|
+
1. **Write tests first** (TDD) or alongside code
|
|
898
|
+
2. **One assertion per test** when possible
|
|
899
|
+
3. **Use descriptive test names** that explain behavior
|
|
900
|
+
4. **Keep tests independent** and isolated
|
|
901
|
+
5. **Use fixtures** for setup and teardown
|
|
902
|
+
6. **Mock external dependencies** appropriately
|
|
903
|
+
7. **Parametrize tests** to reduce duplication
|
|
904
|
+
8. **Test edge cases** and error conditions
|
|
905
|
+
9. **Measure coverage** but focus on quality
|
|
906
|
+
10. **Run tests in CI/CD** on every commit
|