@umacloud/knowledge 1.0.1
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/00-governance/governance-capabilities.md +557 -0
- package/00-governance/knowledge-map.md +39 -0
- package/00-governance/maintenance-policy.md +76 -0
- package/00-governance/review-checklist.md +81 -0
- package/README.md +13 -0
- package/ai/01-standards/agent-development-complete.md +691 -0
- package/ai/01-standards/llm-application-complete.md +488 -0
- package/ai/01-standards/mlops-complete.md +798 -0
- package/ai/01-standards/prompt-engineering-complete.md +646 -0
- package/ai/01-standards/rag-architecture-complete.md +649 -0
- package/ai/02-playbooks/llm-evaluation-playbook.md +847 -0
- package/ai/03-checklists/ai-project-checklist.md +215 -0
- package/ai/04-antipatterns/ai-antipatterns.md +661 -0
- package/ai/05-cases/case-rag-production.md +147 -0
- package/ai/06-glossary/ai-glossary.md +162 -0
- package/ai/agent-evaluation-benchmark.md +53 -0
- package/ai/ai-agent-memory-context-management.md +41 -0
- package/ai/ai-cost-capacity-optimization-playbook.md +42 -0
- package/ai/ai-data-security-and-compliance-playbook.md +37 -0
- package/ai/ai-domain-index-and-checklist.md +40 -0
- package/ai/ai-governance-maturity-model.md +50 -0
- package/ai/ai-model-selection-and-routing-strategy.md +47 -0
- package/ai/ai-observability-and-oncall-runbook.md +52 -0
- package/ai/ai-rag-engineering-playbook.md +42 -0
- package/ai/ai-red-team-and-safety-evaluation.md +42 -0
- package/ai/ai-release-readiness-and-rollback-gate.md +42 -0
- package/ai/llm-agent-engineering-deep-dive.md +57 -0
- package/ai/prompt-and-tool-guardrails.md +52 -0
- package/api/01-standards/enterprise-api-standards.md +198 -0
- package/api/01-standards/rest-api-design-guide.md +63 -0
- package/api/02-playbooks/api-pagination-playbook.md +93 -0
- package/api/02-playbooks/graphql-production-playbook.md +176 -0
- package/api/03-checklists/api-review-checklist.md +55 -0
- package/api/04-antipatterns/api-antipatterns.md +112 -0
- package/architecture/01-standards/api-gateway-patterns.md +496 -0
- package/architecture/01-standards/cloud-native-patterns.md +644 -0
- package/architecture/01-standards/distributed-systems-patterns.md +591 -0
- package/architecture/01-standards/event-driven-architecture.md +595 -0
- package/architecture/01-standards/microservices-patterns-complete.md +968 -0
- package/architecture/01-standards/microservices-patterns.md +495 -0
- package/architecture/01-standards/system-design-interview.md +664 -0
- package/architecture/02-playbooks/microservices-patterns-playbook.md +137 -0
- package/architecture/02-playbooks/migration-playbook.md +780 -0
- package/architecture/02-playbooks/system-design-playbook.md +779 -0
- package/architecture/03-checklists/architecture-decision-checklist.md +297 -0
- package/architecture/04-antipatterns/architecture-antipatterns.md +417 -0
- package/architecture/05-cases/case-netflix-microservices.md +413 -0
- package/architecture/06-glossary/architecture-glossary.md +164 -0
- package/architecture/adr-template-and-examples.md +38 -0
- package/architecture/api-gateway-deep-dive.md +1291 -0
- package/architecture/configuration-management.md +1162 -0
- package/architecture/distributed-transactions.md +1220 -0
- package/architecture/microservices-complete.md +735 -0
- package/architecture/resilience-and-disaster-patterns.md +37 -0
- package/architecture/service-governance.md +1198 -0
- package/architecture/system-architecture-deep-dive.md +37 -0
- package/backend/01-standards/analytics-and-growth.md +65 -0
- package/backend/01-standards/api-and-error-conventions.md +120 -0
- package/backend/01-standards/application-layering-and-packaging.md +160 -0
- package/backend/01-standards/auth-implementation.md +104 -0
- package/backend/01-standards/backend-framework-idioms.md +74 -0
- package/backend/01-standards/background-jobs-and-async.md +66 -0
- package/backend/01-standards/caching-strategies-complete.md +390 -0
- package/backend/01-standards/config-and-observability.md +77 -0
- package/backend/01-standards/data-modeling-and-persistence.md +94 -0
- package/backend/01-standards/django-complete.md +1765 -0
- package/backend/01-standards/email-and-notifications.md +64 -0
- package/backend/01-standards/fastapi-complete.md +925 -0
- package/backend/01-standards/file-upload-and-storage.md +66 -0
- package/backend/01-standards/graphql-api-complete.md +416 -0
- package/backend/01-standards/llm-application-standard.md +78 -0
- package/backend/01-standards/message-queue-patterns.md +379 -0
- package/backend/01-standards/microservices-and-distributed.md +78 -0
- package/backend/01-standards/nestjs-complete.md +2167 -0
- package/backend/01-standards/payment-integration.md +80 -0
- package/backend/01-standards/rate-limiting-complete.md +451 -0
- package/backend/01-standards/realtime-and-websocket.md +65 -0
- package/backend/01-standards/search-and-filtering.md +64 -0
- package/backend/01-standards/spring-boot-complete.md +445 -0
- package/backend/02-playbooks/api-design-playbook.md +718 -0
- package/backend/02-playbooks/email-send-playbook.md +130 -0
- package/backend/02-playbooks/file-upload-s3-playbook.md +153 -0
- package/backend/02-playbooks/typescript-enterprise-playbook.md +133 -0
- package/backend/02-playbooks/websocket-realtime-playbook.md +154 -0
- package/backend/03-checklists/api-launch-checklist.md +189 -0
- package/backend/04-antipatterns/backend-antipatterns.md +1051 -0
- package/blockchain/01-standards/blockchain-basics.md +557 -0
- package/blockchain/01-standards/smart-contract-development.md +1315 -0
- package/cicd/01-standards/deployment-and-delivery-standard.md +96 -0
- package/cicd/01-standards/github-actions-complete.md +473 -0
- package/cicd/01-standards/release-and-store-submission.md +75 -0
- package/cicd/02-playbooks/cicd-pipeline-playbook.md +144 -0
- package/cicd/02-playbooks/release-management-playbook.md +605 -0
- package/cicd/03-checklists/pipeline-security-checklist.md +168 -0
- package/cicd/04-antipatterns/cicd-antipatterns.md +589 -0
- package/cicd/05-cases/case-deployment-automation.md +221 -0
- package/cicd/05-cases/case-gitops-transformation.md +212 -0
- package/cicd/06-glossary/cicd-glossary.md +114 -0
- package/cicd/cicd-blueprint-deep-dive.md +38 -0
- package/cicd/release-readiness-gate.md +37 -0
- package/cloud-native/01-standards/container-security.md +741 -0
- package/cloud-native/01-standards/kubernetes-complete.md +812 -0
- package/cloud-native/02-playbooks/api-gateway-playbook.md +155 -0
- package/cloud-native/02-playbooks/gitops-with-argocd.md +760 -0
- package/cloud-native/02-playbooks/k8s-troubleshooting-playbook.md +1942 -0
- package/cloud-native/02-playbooks/message-queue-playbook.md +129 -0
- package/cloud-native/02-playbooks/multicloud-governance.md +726 -0
- package/cloud-native/02-playbooks/serverless-patterns.md +788 -0
- package/cloud-native/02-playbooks/service-mesh-playbook.md +612 -0
- package/cloud-native/02-playbooks/terraform-iac-playbook.md +143 -0
- package/cloud-native/03-checklists/container-security-checklist.md +431 -0
- package/cloud-native/03-checklists/k8s-production-readiness-checklist.md +460 -0
- package/cloud-native/04-antipatterns/container-antipatterns.md +660 -0
- package/cloud-native/04-antipatterns/k8s-antipatterns.md +743 -0
- package/cloud-native/05-cases/case-k8s-migration.md +478 -0
- package/cloud-native/05-cases/case-k8s-scaling.md +642 -0
- package/cloud-native/05-cases/case-k8s-security-incident.md +397 -0
- package/cloud-native/06-glossary/cloud-native-glossary.md +337 -0
- package/cross-platform/01-standards/cross-platform-frameworks.md +83 -0
- package/cross-platform/01-standards/platform-selection-and-architecture.md +77 -0
- package/data/01-standards/elasticsearch-complete.md +2098 -0
- package/data/01-standards/postgresql-complete.md +1613 -0
- package/data/01-standards/redis-complete.md +1527 -0
- package/data/02-playbooks/database-optimization-playbook.md +403 -0
- package/data/02-playbooks/elasticsearch-production-playbook.md +132 -0
- package/data/03-checklists/database-launch-checklist.md +187 -0
- package/data/04-antipatterns/database-antipatterns.md +873 -0
- package/data/05-cases/case-database-migration.md +310 -0
- package/data/06-glossary/database-glossary.md +440 -0
- package/data/data-governance-and-modeling-deep-dive.md +39 -0
- package/data-engineering/01-standards/airflow-complete.md +523 -0
- package/data-engineering/01-standards/kafka-complete.md +1521 -0
- package/data-engineering/02-playbooks/spark-etl-playbook.md +496 -0
- package/data-engineering/03-checklists/pipeline-launch-checklist.md +194 -0
- package/data-engineering/04-antipatterns/data-pipeline-antipatterns.md +684 -0
- package/data-engineering/05-cases/case-real-time-pipeline.md +355 -0
- package/data-engineering/06-glossary/data-engineering-glossary.md +429 -0
- package/database/01-standards/database-schema-standards.md +147 -0
- package/database/02-playbooks/postgresql-optimization-quick.md +52 -0
- package/database/02-playbooks/postgresql-performance-optimization.md +58 -0
- package/database/02-playbooks/postgresql-production-playbook.md +146 -0
- package/database/02-playbooks/redis-caching-playbook.md +117 -0
- package/database/03-checklists/database-review-checklist.md +50 -0
- package/database/04-antipatterns/database-antipatterns.md +112 -0
- package/design/01-standards/ui-design-system-complete.md +423 -0
- package/design/02-playbooks/design-handoff-playbook.md +254 -0
- package/design/02-playbooks/design-review-playbook.md +388 -0
- package/design/03-checklists/design-review-checklist.md +246 -0
- package/design/04-antipatterns/design-antipatterns.md +378 -0
- package/design/05-cases/case-design-system-adoption.md +328 -0
- package/design/06-glossary/design-glossary.md +329 -0
- package/design/ui-full-lifecycle-cross-platform-playbook.md +571 -0
- package/design/ux-system-deep-dive.md +38 -0
- package/design-systems/00-craft-rules.md +71 -0
- package/design-systems/aesthetic-families.md +43 -0
- package/design-systems/anti-ai-slop.md +162 -0
- package/design-systems/bold-geometric.md +120 -0
- package/design-systems/brutalist-bold.md +103 -0
- package/design-systems/editorial-clean.md +109 -0
- package/design-systems/glass-aurora.md +108 -0
- package/design-systems/modern-minimal.md +145 -0
- package/design-systems/premium-luxury.md +106 -0
- package/design-systems/product-type-design-map.md +48 -0
- package/design-systems/soft-warm.md +123 -0
- package/design-systems/tech-utility.md +113 -0
- package/desktop/01-standards/desktop-app-standard.md +72 -0
- package/desktop/01-standards/desktop-design.md +71 -0
- package/development/00-governance/document-template.md +41 -0
- package/development/01-standards/api-versioning-strategies.md +432 -0
- package/development/01-standards/authentication-patterns-complete.md +479 -0
- package/development/01-standards/css-architecture-complete.md +550 -0
- package/development/01-standards/database-migration-strategies.md +484 -0
- package/development/01-standards/elasticsearch-complete.md +347 -0
- package/development/01-standards/git-complete.md +371 -0
- package/development/01-standards/golang-complete.md +1565 -0
- package/development/01-standards/graphql-complete.md +298 -0
- package/development/01-standards/javascript-bundlers-complete.md +469 -0
- package/development/01-standards/javascript-typescript-complete.md +528 -0
- package/development/01-standards/jest-complete.md +275 -0
- package/development/01-standards/linux-complete.md +234 -0
- package/development/01-standards/logging-observability-complete.md +526 -0
- package/development/01-standards/microservices-communication.md +502 -0
- package/development/01-standards/mongodb-complete.md +406 -0
- package/development/01-standards/oauth2-complete.md +285 -0
- package/development/01-standards/performance-optimization-complete.md +289 -0
- package/development/01-standards/playwright-complete.md +247 -0
- package/development/01-standards/postgresql-complete.md +456 -0
- package/development/01-standards/pytest-complete.md +340 -0
- package/development/01-standards/python-async-programming.md +902 -0
- package/development/01-standards/python-complete.md +956 -0
- package/development/01-standards/python-decorators-complete.md +799 -0
- package/development/01-standards/python-design-patterns.md +2854 -0
- package/development/01-standards/python-packaging-distribution.md +420 -0
- package/development/01-standards/python-testing-strategies.md +607 -0
- package/development/01-standards/python-web-frameworks-comparison.md +471 -0
- package/development/01-standards/redis-complete.md +317 -0
- package/development/01-standards/rest-api-complete.md +316 -0
- package/development/01-standards/rust-complete.md +578 -0
- package/development/01-standards/typescript-advanced-types.md +1513 -0
- package/development/01-standards/web-security-complete.md +292 -0
- package/development/02-playbooks/api-design-playbook.md +810 -0
- package/development/02-playbooks/database-migration-playbook.md +580 -0
- package/development/02-playbooks/debugging-playbook.md +692 -0
- package/development/02-playbooks/feature-delivery-playbook.md +430 -0
- package/development/02-playbooks/incident-hotfix-playbook.md +387 -0
- package/development/02-playbooks/performance-optimization-playbook.md +531 -0
- package/development/02-playbooks/performance-tuning-playbook.md +652 -0
- package/development/02-playbooks/refactor-playbook.md +403 -0
- package/development/02-playbooks/release-playbook.md +469 -0
- package/development/03-checklists/architecture-review-checklist.md +168 -0
- package/development/03-checklists/data-migration-checklist.md +157 -0
- package/development/03-checklists/oncall-handover-checklist.md +173 -0
- package/development/03-checklists/pr-checklist.md +158 -0
- package/development/03-checklists/production-readiness-checklist.md +190 -0
- package/development/03-checklists/release-readiness-checklist.md +154 -0
- package/development/03-checklists/security-review-checklist.md +182 -0
- package/development/04-antipatterns/api-antipatterns.md +657 -0
- package/development/04-antipatterns/architecture-antipatterns.md +686 -0
- package/development/04-antipatterns/backend-antipatterns.md +648 -0
- package/development/04-antipatterns/cicd-antipatterns.md +540 -0
- package/development/04-antipatterns/code-smell-antipatterns.md +571 -0
- package/development/04-antipatterns/data-antipatterns.md +658 -0
- package/development/04-antipatterns/database-antipatterns.md +578 -0
- package/development/04-antipatterns/frontend-antipatterns.md +635 -0
- package/development/04-antipatterns/reliability-antipatterns.md +700 -0
- package/development/04-antipatterns/security-antipatterns.md +747 -0
- package/development/05-cases/case-api-version-migration.md +428 -0
- package/development/05-cases/case-authorization-hardening.md +383 -0
- package/development/05-cases/case-bluegreen-rollback.md +466 -0
- package/development/05-cases/case-cache-snowball-protection.md +485 -0
- package/development/05-cases/case-ci-cd-pipeline.md +544 -0
- package/development/05-cases/case-database-scaling.md +500 -0
- package/development/05-cases/case-db-hotspot-optimization.md +487 -0
- package/development/05-cases/case-incident-mttr-reduction.md +563 -0
- package/development/05-cases/case-microservice-migration.md +375 -0
- package/development/05-cases/case-performance-optimization.md +406 -0
- package/development/05-cases/case-security-incident-response.md +345 -0
- package/development/06-glossary/full-stack-glossary.md +166 -0
- package/development/09-maturity/quarterly-audit-template.md +35 -0
- package/development/11-ui-excellence/ui-aesthetic-system.md +41 -0
- package/development/11-ui-excellence/ui-engineering-excellence.md +435 -0
- package/development/12-scenarios/development-scenarios-guide.md +565 -0
- package/development/13-implementation-assets/implementation-toolkit.md +282 -0
- package/development/13-implementation-assets/knowledge-gates-execution.md +43 -0
- package/development/14-full-lifecycle/software-lifecycle-gates.md +511 -0
- package/development/15-lifecycle-templates/project-templates-collection.md +791 -0
- package/development/api-contract-and-versioning-guide.md +36 -0
- package/development/api-governance-complete.md +43 -0
- package/development/backend-engineering-complete.md +43 -0
- package/development/code-review-quality-complete.md +43 -0
- package/development/concurrency-reliability-complete.md +43 -0
- package/development/database-engineering-complete.md +43 -0
- package/development/engineering-effectiveness-complete.md +43 -0
- package/development/engineering-standards-deep-dive.md +38 -0
- package/development/frontend-engineering-complete.md +43 -0
- package/development/performance-capacity-complete.md +43 -0
- package/development/refactor-migration-complete.md +42 -0
- package/development/refactoring-and-techdebt-playbook.md +37 -0
- package/development/security-in-development-complete.md +43 -0
- package/devops/01-standards/cicd-pipeline-complete.md +262 -0
- package/devops/01-standards/docker-complete.md +1490 -0
- package/devops/01-standards/github-actions-complete.md +337 -0
- package/devops/01-standards/kubernetes-complete.md +638 -0
- package/devops/01-standards/terraform-complete.md +2117 -0
- package/devops/02-playbooks/docker-compose-playbook.md +233 -0
- package/devops/02-playbooks/docker-k8s-production-playbook.md +186 -0
- package/devops/02-playbooks/docker-production-playbook.md +952 -0
- package/edge-iot/01-standards/edge-iot-complete.md +473 -0
- package/experts/architect/api-design.md +178 -0
- package/experts/architect/methodology.md +124 -0
- package/experts/architect/security.md +75 -0
- package/experts/backend-lead/methodology.md +216 -0
- package/experts/devops/methodology.md +160 -0
- package/experts/frontend-lead/methodology.md +178 -0
- package/experts/product-manager/industry/ecommerce.md +43 -0
- package/experts/product-manager/industry/saas.md +40 -0
- package/experts/product-manager/methodology.md +97 -0
- package/experts/qa-lead/methodology.md +123 -0
- package/experts/qa-lead/test-strategy.md +128 -0
- package/experts/uiux-designer/methodology.md +125 -0
- package/frontend/01-standards/accessibility-complete.md +532 -0
- package/frontend/01-standards/accessibility-standard.md +74 -0
- package/frontend/01-standards/admin-dashboard-and-crud.md +72 -0
- package/frontend/01-standards/design-tokens-complete.md +444 -0
- package/frontend/01-standards/forms-and-validation.md +77 -0
- package/frontend/01-standards/frontend-architecture-and-layering.md +119 -0
- package/frontend/01-standards/i18n-and-localization.md +65 -0
- package/frontend/01-standards/nextjs-complete.md +451 -0
- package/frontend/01-standards/react-complete.md +713 -0
- package/frontend/01-standards/react-hooks-complete-guide.md +1100 -0
- package/frontend/01-standards/react-hooks-complete.md +1171 -0
- package/frontend/01-standards/seo-and-web-vitals.md +77 -0
- package/frontend/01-standards/state-management-complete.md +444 -0
- package/frontend/01-standards/vue-complete.md +499 -0
- package/frontend/01-standards/vue3-complete.md +2002 -0
- package/frontend/01-standards/web-framework-best-practices.md +64 -0
- package/frontend/01-standards/web-performance-complete.md +495 -0
- package/frontend/02-playbooks/accessibility-a11y-playbook.md +161 -0
- package/frontend/02-playbooks/frontend-performance-playbook.md +707 -0
- package/frontend/02-playbooks/i18n-internationalization-playbook.md +120 -0
- package/frontend/02-playbooks/performance-optimization-playbook.md +163 -0
- package/frontend/02-playbooks/react-nextjs-production-playbook.md +167 -0
- package/frontend/02-playbooks/react-state-management-playbook.md +173 -0
- package/frontend/03-checklists/component-quality-checklist.md +166 -0
- package/frontend/03-checklists/frontend-launch-checklist.md +299 -0
- package/frontend/04-antipatterns/frontend-antipatterns.md +886 -0
- package/frontend/05-cases/case-performance-optimization.md +274 -0
- package/harmony/01-standards/harmonyos-arkts-standard.md +75 -0
- package/harmony/01-standards/harmonyos-design.md +65 -0
- package/high-quality-engineering-playbook.md +54 -0
- package/incident/01-standards/incident-response-complete.md +303 -0
- package/incident/02-playbooks/chaos-engineering-playbook.md +883 -0
- package/incident/02-playbooks/postmortem-playbook.md +398 -0
- package/incident/03-checklists/incident-readiness-checklist.md +181 -0
- package/incident/04-antipatterns/incident-antipatterns.md +490 -0
- package/incident/05-cases/case-cascade-failure.md +176 -0
- package/incident/06-glossary/incident-glossary.md +114 -0
- package/incident/postmortem-and-response-deep-dive.md +39 -0
- package/industries/ecommerce/ecommerce-complete.md +631 -0
- package/industries/education/education-complete.md +555 -0
- package/industries/fintech/fintech-complete.md +501 -0
- package/industries/gaming/gaming-complete.md +587 -0
- package/industries/healthcare/healthcare-complete.md +452 -0
- package/low-code/01-standards/low-code-complete.md +944 -0
- package/miniprogram/01-standards/ai-common-mistakes.md +61 -0
- package/miniprogram/01-standards/miniprogram-custom-navbar-capsule.md +77 -0
- package/miniprogram/01-standards/miniprogram-design.md +61 -0
- package/miniprogram/01-standards/miniprogram-standard.md +81 -0
- package/mobile/01-standards/android-material-design.md +70 -0
- package/mobile/01-standards/flutter-complete.md +384 -0
- package/mobile/01-standards/ios-design-hig.md +78 -0
- package/mobile/01-standards/mobile-app-standard.md +85 -0
- package/mobile/01-standards/react-native-complete.md +352 -0
- package/mobile/02-playbooks/mobile-cross-platform-playbook.md +175 -0
- package/mobile/02-playbooks/mobile-performance.md +473 -0
- package/mobile/03-checklists/mobile-release-checklist.md +234 -0
- package/mobile/04-antipatterns/mobile-antipatterns.md +798 -0
- package/mobile/05-cases/case-app-performance.md +500 -0
- package/mobile/05-cases/case-app-startup-optimization.md +218 -0
- package/mobile/06-glossary/mobile-glossary.md +484 -0
- package/observability/01-standards/observability-standards.md +103 -0
- package/observability/02-playbooks/prometheus-grafana-playbook.md +135 -0
- package/observability/02-playbooks/structured-logging-playbook.md +73 -0
- package/observability/03-checklists/observability-checklist.md +54 -0
- package/observability/04-antipatterns/observability-antipatterns.md +106 -0
- package/operations/01-standards/prometheus-monitoring-complete.md +1578 -0
- package/operations/02-playbooks/capacity-planning-playbook.md +620 -0
- package/operations/03-checklists/production-launch-checklist.md +365 -0
- package/operations/04-antipatterns/operations-antipatterns.md +664 -0
- package/operations/05-cases/case-sre-practices.md +581 -0
- package/operations/06-glossary/operations-glossary.md +120 -0
- package/operations/aiops-anomaly-detection.md +758 -0
- package/operations/capacity-planning.md +1061 -0
- package/operations/chaos-engineering.md +659 -0
- package/operations/incident-command-system.md +38 -0
- package/operations/observability-complete.md +442 -0
- package/operations/slo-sli-playbook.md +517 -0
- package/operations/sre-operations-deep-dive.md +39 -0
- package/package.json +8 -0
- package/performance/01-standards/performance-and-scalability.md +80 -0
- package/performance/01-standards/performance-standards.md +156 -0
- package/performance/02-playbooks/query-optimization-playbook.md +103 -0
- package/performance/03-checklists/performance-checklist.md +56 -0
- package/performance/04-antipatterns/performance-antipatterns.md +146 -0
- package/product/01-standards/product-management-complete.md +285 -0
- package/product/02-playbooks/feature-launch-playbook.md +207 -0
- package/product/02-playbooks/user-research-playbook.md +532 -0
- package/product/03-checklists/feature-launch-checklist.md +275 -0
- package/product/04-antipatterns/product-antipatterns.md +355 -0
- package/product/05-cases/case-mvp-to-scale.md +384 -0
- package/product/06-glossary/product-glossary.md +462 -0
- package/product/feature-prioritization-framework.md +40 -0
- package/product/kpi-and-metric-tree.md +37 -0
- package/product/product-discovery-and-prd-deep-dive.md +41 -0
- package/quantum/01-standards/quantum-complete.md +1186 -0
- package/security/01-standards/api-security-complete.md +511 -0
- package/security/01-standards/container-runtime-security.md +574 -0
- package/security/01-standards/data-protection-gdpr.md +543 -0
- package/security/01-standards/owasp-top10-complete.md +1890 -0
- package/security/01-standards/secure-coding-baseline.md +90 -0
- package/security/01-standards/supply-chain-security.md +441 -0
- package/security/01-standards/web-security-checklist.md +108 -0
- package/security/01-standards/zero-trust-architecture.md +521 -0
- package/security/02-playbooks/auth-sso-playbook.md +166 -0
- package/security/02-playbooks/incident-response-security-playbook.md +588 -0
- package/security/02-playbooks/owasp-api-security-playbook.md +129 -0
- package/security/02-playbooks/payment-integration-playbook.md +119 -0
- package/security/02-playbooks/penetration-testing-playbook.md +517 -0
- package/security/03-checklists/security-audit-checklist.md +356 -0
- package/security/04-antipatterns/security-coding-antipatterns.md +580 -0
- package/security/05-cases/case-log4shell-incident.md +537 -0
- package/security/05-cases/case-major-breaches.md +468 -0
- package/security/06-glossary/security-glossary.md +212 -0
- package/security/compliance-automation.md +993 -0
- package/security/container-security.md +680 -0
- package/security/devsecops-complete.md +426 -0
- package/security/sast-dast-sca.md +775 -0
- package/security/secrets-management.md +594 -0
- package/security/security-architecture-deep-dive.md +37 -0
- package/security/threat-modeling-stride-playbook.md +40 -0
- package/seed-templates/auth-system.md +59 -0
- package/seed-templates/blog-content.md +94 -0
- package/seed-templates/dashboard.md +89 -0
- package/seed-templates/docs-site.md +73 -0
- package/seed-templates/e-commerce.md +50 -0
- package/seed-templates/saas-landing.md +92 -0
- package/seed-templates/settings-page.md +51 -0
- package/testing/01-standards/test-strategy-and-layering.md +83 -0
- package/testing/01-standards/testing-strategy-complete.md +422 -0
- package/testing/01-standards/unit-testing-best-practices.md +118 -0
- package/testing/02-playbooks/e2e-testing-playbook.md +988 -0
- package/testing/02-playbooks/testing-strategy-playbook.md +126 -0
- package/testing/03-checklists/test-strategy-checklist.md +208 -0
- package/testing/04-antipatterns/testing-antipatterns.md +718 -0
- package/testing/05-cases/case-testing-transformation.md +300 -0
- package/testing/06-glossary/testing-glossary.md +110 -0
- package/testing/risk-based-test-matrix.md +36 -0
- package/testing/testing-strategy-deep-dive.md +37 -0
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: E2E 测试作战手册
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
last_updated: 2026-03-28
|
|
5
|
+
owner: qa-team
|
|
6
|
+
tags: [e2e-testing, Playwright, Cypress, test-strategy, CI-integration, parallel-execution, stability]
|
|
7
|
+
status: production
|
|
8
|
+
domain: testing
|
|
9
|
+
difficulty: intermediate
|
|
10
|
+
quality_score: 70
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# 开发:Excellent(11964948@qq.com)
|
|
14
|
+
# 功能:E2E 测试全流程作战手册
|
|
15
|
+
# 作用:指导团队建立和维护高质量的 E2E 测试体系
|
|
16
|
+
# 创建时间:2026-03-28
|
|
17
|
+
# 最后修改:2026-03-28
|
|
18
|
+
|
|
19
|
+
## 目标
|
|
20
|
+
|
|
21
|
+
建立 E2E 测试标准化实践,确保:
|
|
22
|
+
- 核心业务流程 100% 覆盖自动化 E2E 测试
|
|
23
|
+
- 测试稳定性 > 98%(Flaky Rate < 2%)
|
|
24
|
+
- CI 中 E2E 测试总耗时 < 15 分钟(并行执行)
|
|
25
|
+
- 测试数据自给自足,不依赖共享环境数据
|
|
26
|
+
- 测试报告清晰可读,失败原因可追溯(含截图/视频/Trace)
|
|
27
|
+
|
|
28
|
+
## 适用场景
|
|
29
|
+
|
|
30
|
+
- Web 应用端到端回归测试
|
|
31
|
+
- 跨服务业务流程验证
|
|
32
|
+
- 发布前门禁测试
|
|
33
|
+
- 新功能验收测试
|
|
34
|
+
- 多浏览器/多设备兼容性测试
|
|
35
|
+
|
|
36
|
+
## 前置条件
|
|
37
|
+
|
|
38
|
+
### 环境要求
|
|
39
|
+
|
|
40
|
+
| 项目 | 要求 |
|
|
41
|
+
|------|------|
|
|
42
|
+
| Node.js | 18+ |
|
|
43
|
+
| 浏览器 | Chromium / Firefox / WebKit(Playwright 自动管理)|
|
|
44
|
+
| 测试环境 | 独立 Staging 环境,不与手工测试共享 |
|
|
45
|
+
| CI 平台 | GitHub Actions / GitLab CI / Jenkins |
|
|
46
|
+
| Docker | 用于 CI 中运行浏览器(可选) |
|
|
47
|
+
|
|
48
|
+
### 工具链安装
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Playwright(推荐)
|
|
52
|
+
npm init playwright@latest
|
|
53
|
+
# 安装浏览器
|
|
54
|
+
npx playwright install --with-deps
|
|
55
|
+
|
|
56
|
+
# Cypress(备选)
|
|
57
|
+
npm install cypress --save-dev
|
|
58
|
+
npx cypress open # 首次打开安装浏览器
|
|
59
|
+
|
|
60
|
+
# 项目结构(Playwright)
|
|
61
|
+
mkdir -p tests/e2e/{pages,fixtures,helpers}
|
|
62
|
+
# tests/e2e/
|
|
63
|
+
# ├── pages/ # Page Object Models
|
|
64
|
+
# ├── fixtures/ # 测试夹具(数据/配置)
|
|
65
|
+
# ├── helpers/ # 工具函数
|
|
66
|
+
# ├── specs/ # 测试用例
|
|
67
|
+
# │ ├── auth/
|
|
68
|
+
# │ ├── order/
|
|
69
|
+
# │ └── product/
|
|
70
|
+
# └── playwright.config.ts
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 一、测试策略
|
|
76
|
+
|
|
77
|
+
### 1.1 测试金字塔与 E2E 定位
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
测试金字塔:
|
|
81
|
+
单元测试(70%): 快速/廉价/大量
|
|
82
|
+
集成测试(20%): API 级别/服务间调用
|
|
83
|
+
E2E 测试(10%): 核心业务流程/用户视角
|
|
84
|
+
|
|
85
|
+
E2E 测试原则:
|
|
86
|
+
测什么:
|
|
87
|
+
- 核心业务的关键路径(Happy Path)
|
|
88
|
+
- 涉及多个服务协作的流程
|
|
89
|
+
- 用户最常用的操作流程
|
|
90
|
+
- 涉及金钱/权限的关键操作
|
|
91
|
+
|
|
92
|
+
不测什么:
|
|
93
|
+
- 单个组件的边界条件(单元测试覆盖)
|
|
94
|
+
- 纯 API 逻辑(集成测试覆盖)
|
|
95
|
+
- 样式/布局细节(视觉回归测试覆盖)
|
|
96
|
+
- 第三方服务内部逻辑
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 1.2 用例优先级矩阵
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
P0 - 必须覆盖(阻断发布):
|
|
103
|
+
- 用户注册与登录
|
|
104
|
+
- 核心业务流程(搜索→浏览→下单→支付)
|
|
105
|
+
- 权限控制(普通用户不能访问管理后台)
|
|
106
|
+
- 数据安全(敏感信息不在页面明文展示)
|
|
107
|
+
|
|
108
|
+
P1 - 应该覆盖(影响质量评分):
|
|
109
|
+
- 搜索与筛选
|
|
110
|
+
- 个人信息管理
|
|
111
|
+
- 订单查询与取消
|
|
112
|
+
- 消息通知
|
|
113
|
+
|
|
114
|
+
P2 - 可以覆盖(提升信心):
|
|
115
|
+
- 页面导航与面包屑
|
|
116
|
+
- 表单校验提示
|
|
117
|
+
- 空状态展示
|
|
118
|
+
- 分页与排序
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 1.3 浏览器与设备覆盖
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
# Playwright 多浏览器配置
|
|
125
|
+
覆盖矩阵:
|
|
126
|
+
桌面端:
|
|
127
|
+
- Chromium(占比 ~65%,必测)
|
|
128
|
+
- Firefox(占比 ~5%,P1 流程覆盖)
|
|
129
|
+
- WebKit/Safari(占比 ~20%,P0 流程覆盖)
|
|
130
|
+
|
|
131
|
+
移动端:
|
|
132
|
+
- Mobile Chrome(Android,P0 流程)
|
|
133
|
+
- Mobile Safari(iOS,P0 流程)
|
|
134
|
+
|
|
135
|
+
分辨率:
|
|
136
|
+
- 1920×1080(桌面标准)
|
|
137
|
+
- 1366×768(笔记本常见)
|
|
138
|
+
- 375×812(iPhone)
|
|
139
|
+
- 360×800(Android)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 二、Playwright 实战
|
|
145
|
+
|
|
146
|
+
### 2.1 配置文件
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// playwright.config.ts
|
|
150
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
151
|
+
|
|
152
|
+
export default defineConfig({
|
|
153
|
+
testDir: './tests/e2e/specs',
|
|
154
|
+
outputDir: './test-results',
|
|
155
|
+
|
|
156
|
+
// 全局超时
|
|
157
|
+
timeout: 30_000,
|
|
158
|
+
expect: { timeout: 5_000 },
|
|
159
|
+
|
|
160
|
+
// 失败重试(CI 中开启)
|
|
161
|
+
retries: process.env.CI ? 2 : 0,
|
|
162
|
+
|
|
163
|
+
// 并行执行
|
|
164
|
+
fullyParallel: true,
|
|
165
|
+
workers: process.env.CI ? 4 : undefined,
|
|
166
|
+
|
|
167
|
+
// 报告
|
|
168
|
+
reporter: [
|
|
169
|
+
['html', { open: 'never' }],
|
|
170
|
+
['junit', { outputFile: 'test-results/junit.xml' }],
|
|
171
|
+
process.env.CI ? ['github'] : ['list'],
|
|
172
|
+
],
|
|
173
|
+
|
|
174
|
+
// 全局配置
|
|
175
|
+
use: {
|
|
176
|
+
baseURL: process.env.BASE_URL || 'http://localhost:3000',
|
|
177
|
+
trace: 'retain-on-failure',
|
|
178
|
+
screenshot: 'only-on-failure',
|
|
179
|
+
video: 'retain-on-failure',
|
|
180
|
+
actionTimeout: 10_000,
|
|
181
|
+
navigationTimeout: 15_000,
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
// 多浏览器/设备
|
|
185
|
+
projects: [
|
|
186
|
+
{
|
|
187
|
+
name: 'chromium',
|
|
188
|
+
use: { ...devices['Desktop Chrome'] },
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: 'firefox',
|
|
192
|
+
use: { ...devices['Desktop Firefox'] },
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: 'webkit',
|
|
196
|
+
use: { ...devices['Desktop Safari'] },
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: 'mobile-chrome',
|
|
200
|
+
use: { ...devices['Pixel 7'] },
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'mobile-safari',
|
|
204
|
+
use: { ...devices['iPhone 14'] },
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
|
|
208
|
+
// 自动启动开发服务器(本地开发时)
|
|
209
|
+
webServer: process.env.CI ? undefined : {
|
|
210
|
+
command: 'npm run dev',
|
|
211
|
+
url: 'http://localhost:3000',
|
|
212
|
+
reuseExistingServer: true,
|
|
213
|
+
timeout: 60_000,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 2.2 Page Object Model
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
// tests/e2e/pages/LoginPage.ts
|
|
222
|
+
import { Page, Locator, expect } from '@playwright/test';
|
|
223
|
+
|
|
224
|
+
export class LoginPage {
|
|
225
|
+
readonly page: Page;
|
|
226
|
+
readonly emailInput: Locator;
|
|
227
|
+
readonly passwordInput: Locator;
|
|
228
|
+
readonly submitButton: Locator;
|
|
229
|
+
readonly errorMessage: Locator;
|
|
230
|
+
|
|
231
|
+
constructor(page: Page) {
|
|
232
|
+
this.page = page;
|
|
233
|
+
this.emailInput = page.getByLabel('邮箱');
|
|
234
|
+
this.passwordInput = page.getByLabel('密码');
|
|
235
|
+
this.submitButton = page.getByRole('button', { name: '登录' });
|
|
236
|
+
this.errorMessage = page.getByTestId('login-error');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async goto() {
|
|
240
|
+
await this.page.goto('/login');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async login(email: string, password: string) {
|
|
244
|
+
await this.emailInput.fill(email);
|
|
245
|
+
await this.passwordInput.fill(password);
|
|
246
|
+
await this.submitButton.click();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async expectLoginSuccess() {
|
|
250
|
+
await expect(this.page).toHaveURL(/\/dashboard/);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async expectLoginError(message: string) {
|
|
254
|
+
await expect(this.errorMessage).toContainText(message);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// tests/e2e/pages/OrderPage.ts
|
|
259
|
+
import { Page, Locator, expect } from '@playwright/test';
|
|
260
|
+
|
|
261
|
+
export class OrderPage {
|
|
262
|
+
readonly page: Page;
|
|
263
|
+
readonly addToCartButton: Locator;
|
|
264
|
+
readonly cartBadge: Locator;
|
|
265
|
+
readonly checkoutButton: Locator;
|
|
266
|
+
readonly orderConfirmation: Locator;
|
|
267
|
+
|
|
268
|
+
constructor(page: Page) {
|
|
269
|
+
this.page = page;
|
|
270
|
+
this.addToCartButton = page.getByRole('button', { name: '加入购物车' });
|
|
271
|
+
this.cartBadge = page.getByTestId('cart-badge');
|
|
272
|
+
this.checkoutButton = page.getByRole('button', { name: '去结算' });
|
|
273
|
+
this.orderConfirmation = page.getByTestId('order-confirmation');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async addProductToCart(productId: string) {
|
|
277
|
+
await this.page.goto(`/products/${productId}`);
|
|
278
|
+
await this.addToCartButton.click();
|
|
279
|
+
await expect(this.cartBadge).toBeVisible();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async checkout() {
|
|
283
|
+
await this.page.goto('/cart');
|
|
284
|
+
await this.checkoutButton.click();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async expectOrderCreated() {
|
|
288
|
+
await expect(this.orderConfirmation).toBeVisible({ timeout: 10_000 });
|
|
289
|
+
const orderId = await this.orderConfirmation.getByTestId('order-id').textContent();
|
|
290
|
+
return orderId;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 2.3 测试用例编写
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// tests/e2e/specs/auth/login.spec.ts
|
|
299
|
+
import { test, expect } from '@playwright/test';
|
|
300
|
+
import { LoginPage } from '../../pages/LoginPage';
|
|
301
|
+
import { createTestUser, deleteTestUser } from '../../helpers/user';
|
|
302
|
+
|
|
303
|
+
test.describe('用户登录', () => {
|
|
304
|
+
let testUser: { email: string; password: string };
|
|
305
|
+
|
|
306
|
+
test.beforeAll(async () => {
|
|
307
|
+
testUser = await createTestUser();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test.afterAll(async () => {
|
|
311
|
+
await deleteTestUser(testUser.email);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
test('正确凭据登录成功', async ({ page }) => {
|
|
315
|
+
const loginPage = new LoginPage(page);
|
|
316
|
+
await loginPage.goto();
|
|
317
|
+
await loginPage.login(testUser.email, testUser.password);
|
|
318
|
+
await loginPage.expectLoginSuccess();
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test('错误密码登录失败', async ({ page }) => {
|
|
322
|
+
const loginPage = new LoginPage(page);
|
|
323
|
+
await loginPage.goto();
|
|
324
|
+
await loginPage.login(testUser.email, 'wrong-password');
|
|
325
|
+
await loginPage.expectLoginError('邮箱或密码错误');
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test('空表单提交显示校验提示', async ({ page }) => {
|
|
329
|
+
const loginPage = new LoginPage(page);
|
|
330
|
+
await loginPage.goto();
|
|
331
|
+
await loginPage.submitButton.click();
|
|
332
|
+
await expect(page.getByText('请输入邮箱')).toBeVisible();
|
|
333
|
+
await expect(page.getByText('请输入密码')).toBeVisible();
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
// tests/e2e/specs/order/purchase-flow.spec.ts
|
|
338
|
+
import { test, expect } from '@playwright/test';
|
|
339
|
+
import { LoginPage } from '../../pages/LoginPage';
|
|
340
|
+
import { OrderPage } from '../../pages/OrderPage';
|
|
341
|
+
import { createTestUser, deleteTestUser } from '../../helpers/user';
|
|
342
|
+
import { createTestProduct, deleteTestProduct } from '../../helpers/product';
|
|
343
|
+
|
|
344
|
+
test.describe('完整购买流程', () => {
|
|
345
|
+
let testUser: { email: string; password: string };
|
|
346
|
+
let productId: string;
|
|
347
|
+
|
|
348
|
+
test.beforeAll(async () => {
|
|
349
|
+
testUser = await createTestUser({ balance: 10000 });
|
|
350
|
+
productId = await createTestProduct({ name: 'Test Product', price: 99 });
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
test.afterAll(async () => {
|
|
354
|
+
await deleteTestUser(testUser.email);
|
|
355
|
+
await deleteTestProduct(productId);
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test('搜索商品 → 加入购物车 → 下单 → 支付', async ({ page }) => {
|
|
359
|
+
// 登录
|
|
360
|
+
const loginPage = new LoginPage(page);
|
|
361
|
+
await loginPage.goto();
|
|
362
|
+
await loginPage.login(testUser.email, testUser.password);
|
|
363
|
+
await loginPage.expectLoginSuccess();
|
|
364
|
+
|
|
365
|
+
// 搜索商品
|
|
366
|
+
await page.getByPlaceholder('搜索商品').fill('Test Product');
|
|
367
|
+
await page.getByPlaceholder('搜索商品').press('Enter');
|
|
368
|
+
await expect(page.getByText('Test Product')).toBeVisible();
|
|
369
|
+
await page.getByText('Test Product').click();
|
|
370
|
+
|
|
371
|
+
// 加入购物车
|
|
372
|
+
const orderPage = new OrderPage(page);
|
|
373
|
+
await orderPage.addToCartButton.click();
|
|
374
|
+
await expect(orderPage.cartBadge).toHaveText('1');
|
|
375
|
+
|
|
376
|
+
// 结算
|
|
377
|
+
await orderPage.checkout();
|
|
378
|
+
|
|
379
|
+
// 选择收货地址
|
|
380
|
+
await page.getByTestId('address-item').first().click();
|
|
381
|
+
|
|
382
|
+
// 提交订单
|
|
383
|
+
await page.getByRole('button', { name: '提交订单' }).click();
|
|
384
|
+
|
|
385
|
+
// 支付
|
|
386
|
+
await page.getByRole('button', { name: '确认支付' }).click();
|
|
387
|
+
|
|
388
|
+
// 验证
|
|
389
|
+
await expect(page.getByText('支付成功')).toBeVisible({ timeout: 15_000 });
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### 2.4 API 拦截与 Mock
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
// 拦截 API 请求用于验证或 Mock
|
|
398
|
+
import { test, expect } from '@playwright/test';
|
|
399
|
+
|
|
400
|
+
test('商品列表加载正确', async ({ page }) => {
|
|
401
|
+
// 拦截 API 并 Mock 响应
|
|
402
|
+
await page.route('**/api/v1/products*', async (route) => {
|
|
403
|
+
await route.fulfill({
|
|
404
|
+
status: 200,
|
|
405
|
+
contentType: 'application/json',
|
|
406
|
+
body: JSON.stringify({
|
|
407
|
+
code: 0,
|
|
408
|
+
data: {
|
|
409
|
+
items: [
|
|
410
|
+
{ id: '1', name: '测试商品A', price: 99.00 },
|
|
411
|
+
{ id: '2', name: '测试商品B', price: 199.00 },
|
|
412
|
+
],
|
|
413
|
+
total: 2,
|
|
414
|
+
},
|
|
415
|
+
}),
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
await page.goto('/products');
|
|
420
|
+
await expect(page.getByText('测试商品A')).toBeVisible();
|
|
421
|
+
await expect(page.getByText('测试商品B')).toBeVisible();
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
test('API 超时显示友好提示', async ({ page }) => {
|
|
425
|
+
await page.route('**/api/v1/products*', async (route) => {
|
|
426
|
+
// 模拟超时
|
|
427
|
+
await new Promise((r) => setTimeout(r, 30_000));
|
|
428
|
+
await route.abort('timedout');
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
await page.goto('/products');
|
|
432
|
+
await expect(page.getByText('加载失败')).toBeVisible({ timeout: 15_000 });
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
test('验证请求参数正确', async ({ page }) => {
|
|
436
|
+
const requestPromise = page.waitForRequest('**/api/v1/orders');
|
|
437
|
+
|
|
438
|
+
await page.goto('/checkout');
|
|
439
|
+
await page.getByRole('button', { name: '提交订单' }).click();
|
|
440
|
+
|
|
441
|
+
const request = await requestPromise;
|
|
442
|
+
const body = request.postDataJSON();
|
|
443
|
+
expect(body.items).toHaveLength(1);
|
|
444
|
+
expect(body.items[0].product_id).toBeDefined();
|
|
445
|
+
expect(body.shipping_address_id).toBeDefined();
|
|
446
|
+
});
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## 三、Cypress 实战
|
|
452
|
+
|
|
453
|
+
### 3.1 配置文件
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
// cypress.config.ts
|
|
457
|
+
import { defineConfig } from 'cypress';
|
|
458
|
+
|
|
459
|
+
export default defineConfig({
|
|
460
|
+
e2e: {
|
|
461
|
+
baseUrl: 'http://localhost:3000',
|
|
462
|
+
specPattern: 'cypress/e2e/**/*.cy.{js,ts}',
|
|
463
|
+
supportFile: 'cypress/support/e2e.ts',
|
|
464
|
+
viewportWidth: 1280,
|
|
465
|
+
viewportHeight: 720,
|
|
466
|
+
defaultCommandTimeout: 10_000,
|
|
467
|
+
requestTimeout: 15_000,
|
|
468
|
+
responseTimeout: 15_000,
|
|
469
|
+
video: true,
|
|
470
|
+
screenshotOnRunFailure: true,
|
|
471
|
+
retries: {
|
|
472
|
+
runMode: 2, // CI
|
|
473
|
+
openMode: 0, // 本地
|
|
474
|
+
},
|
|
475
|
+
experimentalMemoryManagement: true,
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### 3.2 Cypress 自定义命令
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
// cypress/support/commands.ts
|
|
484
|
+
declare global {
|
|
485
|
+
namespace Cypress {
|
|
486
|
+
interface Chainable {
|
|
487
|
+
login(email: string, password: string): Chainable<void>;
|
|
488
|
+
createTestData(type: string, data: Record<string, any>): Chainable<string>;
|
|
489
|
+
cleanupTestData(type: string, id: string): Chainable<void>;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
Cypress.Commands.add('login', (email: string, password: string) => {
|
|
495
|
+
// 通过 API 登录(比 UI 快)
|
|
496
|
+
cy.request('POST', '/api/v1/auth/login', { email, password }).then((resp) => {
|
|
497
|
+
window.localStorage.setItem('token', resp.body.data.token);
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
Cypress.Commands.add('createTestData', (type: string, data: Record<string, any>) => {
|
|
502
|
+
return cy.request({
|
|
503
|
+
method: 'POST',
|
|
504
|
+
url: `/api/v1/test-helpers/${type}`,
|
|
505
|
+
body: data,
|
|
506
|
+
headers: { 'X-Test-Helper': 'true' },
|
|
507
|
+
}).then((resp) => resp.body.data.id);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
Cypress.Commands.add('cleanupTestData', (type: string, id: string) => {
|
|
511
|
+
cy.request({
|
|
512
|
+
method: 'DELETE',
|
|
513
|
+
url: `/api/v1/test-helpers/${type}/${id}`,
|
|
514
|
+
headers: { 'X-Test-Helper': 'true' },
|
|
515
|
+
failOnStatusCode: false,
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### 3.3 Cypress 测试用例
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
// cypress/e2e/order/purchase.cy.ts
|
|
524
|
+
describe('完整购买流程', () => {
|
|
525
|
+
let productId: string;
|
|
526
|
+
|
|
527
|
+
before(() => {
|
|
528
|
+
cy.createTestData('product', { name: 'Cypress Test', price: 99 }).then((id) => {
|
|
529
|
+
productId = id;
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
after(() => {
|
|
534
|
+
cy.cleanupTestData('product', productId);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
beforeEach(() => {
|
|
538
|
+
cy.login('test@example.com', 'password123');
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it('完成下单支付流程', () => {
|
|
542
|
+
cy.visit(`/products/${productId}`);
|
|
543
|
+
cy.contains('加入购物车').click();
|
|
544
|
+
cy.get('[data-testid="cart-badge"]').should('contain', '1');
|
|
545
|
+
|
|
546
|
+
cy.visit('/cart');
|
|
547
|
+
cy.contains('去结算').click();
|
|
548
|
+
|
|
549
|
+
cy.get('[data-testid="address-item"]').first().click();
|
|
550
|
+
cy.contains('提交订单').click();
|
|
551
|
+
cy.contains('确认支付').click();
|
|
552
|
+
|
|
553
|
+
cy.contains('支付成功', { timeout: 15_000 }).should('be.visible');
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## 四、测试数据管理
|
|
561
|
+
|
|
562
|
+
### 4.1 数据策略
|
|
563
|
+
|
|
564
|
+
```yaml
|
|
565
|
+
原则:
|
|
566
|
+
- 每个测试自建自清(Self-contained)
|
|
567
|
+
- 不依赖共享测试数据(避免测试间耦合)
|
|
568
|
+
- 测试数据通过 API 创建而非 DB 直插(保证业务逻辑一致性)
|
|
569
|
+
- 并行执行时数据隔离(使用唯一前缀/随机标识)
|
|
570
|
+
|
|
571
|
+
数据层次:
|
|
572
|
+
全局种子数据:
|
|
573
|
+
- 管理员账号
|
|
574
|
+
- 商品类目
|
|
575
|
+
- 系统配置
|
|
576
|
+
- 通过 DB Seed 脚本管理
|
|
577
|
+
|
|
578
|
+
测试级别数据:
|
|
579
|
+
- 测试用户(beforeAll 创建 / afterAll 清理)
|
|
580
|
+
- 测试商品/订单
|
|
581
|
+
- 通过 Test Helper API 管理
|
|
582
|
+
|
|
583
|
+
用例级别数据:
|
|
584
|
+
- 特定场景的一次性数据
|
|
585
|
+
- beforeEach 创建 / afterEach 清理
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### 4.2 Test Helper API
|
|
589
|
+
|
|
590
|
+
```typescript
|
|
591
|
+
// 后端需提供测试数据辅助接口(仅 staging 环境启用)
|
|
592
|
+
// helpers/testData.ts
|
|
593
|
+
|
|
594
|
+
import { request } from '@playwright/test';
|
|
595
|
+
|
|
596
|
+
const API_BASE = process.env.BASE_URL || 'http://localhost:3001';
|
|
597
|
+
const TEST_HELPER_KEY = process.env.TEST_HELPER_KEY || 'test-secret';
|
|
598
|
+
|
|
599
|
+
export async function createTestUser(options?: {
|
|
600
|
+
email?: string;
|
|
601
|
+
balance?: number;
|
|
602
|
+
}) {
|
|
603
|
+
const apiContext = await request.newContext();
|
|
604
|
+
const email = options?.email || `test-${Date.now()}-${Math.random().toString(36).slice(2)}@test.com`;
|
|
605
|
+
const password = 'Test@123456';
|
|
606
|
+
|
|
607
|
+
const resp = await apiContext.post(`${API_BASE}/api/v1/test-helpers/users`, {
|
|
608
|
+
headers: { 'X-Test-Helper-Key': TEST_HELPER_KEY },
|
|
609
|
+
data: { email, password, balance: options?.balance || 0 },
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
const body = await resp.json();
|
|
613
|
+
return { email, password, id: body.data.id };
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
export async function deleteTestUser(email: string) {
|
|
617
|
+
const apiContext = await request.newContext();
|
|
618
|
+
await apiContext.delete(`${API_BASE}/api/v1/test-helpers/users`, {
|
|
619
|
+
headers: { 'X-Test-Helper-Key': TEST_HELPER_KEY },
|
|
620
|
+
data: { email },
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export async function createTestProduct(options: {
|
|
625
|
+
name: string;
|
|
626
|
+
price: number;
|
|
627
|
+
}) {
|
|
628
|
+
const apiContext = await request.newContext();
|
|
629
|
+
const resp = await apiContext.post(`${API_BASE}/api/v1/test-helpers/products`, {
|
|
630
|
+
headers: { 'X-Test-Helper-Key': TEST_HELPER_KEY },
|
|
631
|
+
data: options,
|
|
632
|
+
});
|
|
633
|
+
const body = await resp.json();
|
|
634
|
+
return body.data.id;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
export async function deleteTestProduct(id: string) {
|
|
638
|
+
const apiContext = await request.newContext();
|
|
639
|
+
await apiContext.delete(`${API_BASE}/api/v1/test-helpers/products/${id}`, {
|
|
640
|
+
headers: { 'X-Test-Helper-Key': TEST_HELPER_KEY },
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
647
|
+
## 五、CI 集成
|
|
648
|
+
|
|
649
|
+
### 5.1 GitHub Actions 配置
|
|
650
|
+
|
|
651
|
+
```yaml
|
|
652
|
+
# .github/workflows/e2e.yml
|
|
653
|
+
name: E2E Tests
|
|
654
|
+
|
|
655
|
+
on:
|
|
656
|
+
push:
|
|
657
|
+
branches: [main, develop]
|
|
658
|
+
pull_request:
|
|
659
|
+
branches: [main]
|
|
660
|
+
|
|
661
|
+
jobs:
|
|
662
|
+
e2e:
|
|
663
|
+
runs-on: ubuntu-latest
|
|
664
|
+
timeout-minutes: 30
|
|
665
|
+
|
|
666
|
+
strategy:
|
|
667
|
+
fail-fast: false
|
|
668
|
+
matrix:
|
|
669
|
+
shard: [1, 2, 3, 4] # 4 分片并行
|
|
670
|
+
|
|
671
|
+
services:
|
|
672
|
+
postgres:
|
|
673
|
+
image: postgres:16
|
|
674
|
+
env:
|
|
675
|
+
POSTGRES_DB: test
|
|
676
|
+
POSTGRES_USER: test
|
|
677
|
+
POSTGRES_PASSWORD: test
|
|
678
|
+
ports:
|
|
679
|
+
- 5432:5432
|
|
680
|
+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
|
681
|
+
|
|
682
|
+
redis:
|
|
683
|
+
image: redis:7
|
|
684
|
+
ports:
|
|
685
|
+
- 6379:6379
|
|
686
|
+
|
|
687
|
+
steps:
|
|
688
|
+
- uses: actions/checkout@v4
|
|
689
|
+
|
|
690
|
+
- uses: actions/setup-node@v4
|
|
691
|
+
with:
|
|
692
|
+
node-version: 20
|
|
693
|
+
cache: npm
|
|
694
|
+
|
|
695
|
+
- name: Install dependencies
|
|
696
|
+
run: npm ci
|
|
697
|
+
|
|
698
|
+
- name: Install Playwright browsers
|
|
699
|
+
run: npx playwright install --with-deps chromium
|
|
700
|
+
|
|
701
|
+
- name: Build application
|
|
702
|
+
run: npm run build
|
|
703
|
+
|
|
704
|
+
- name: Start application
|
|
705
|
+
run: |
|
|
706
|
+
npm run start &
|
|
707
|
+
npx wait-on http://localhost:3000 --timeout 60000
|
|
708
|
+
|
|
709
|
+
- name: Run E2E tests (shard ${{ matrix.shard }}/4)
|
|
710
|
+
run: npx playwright test --shard=${{ matrix.shard }}/4
|
|
711
|
+
env:
|
|
712
|
+
BASE_URL: http://localhost:3000
|
|
713
|
+
DATABASE_URL: postgresql://test:test@localhost:5432/test
|
|
714
|
+
TEST_HELPER_KEY: test-secret
|
|
715
|
+
|
|
716
|
+
- name: Upload test results
|
|
717
|
+
if: always()
|
|
718
|
+
uses: actions/upload-artifact@v4
|
|
719
|
+
with:
|
|
720
|
+
name: e2e-results-shard-${{ matrix.shard }}
|
|
721
|
+
path: |
|
|
722
|
+
test-results/
|
|
723
|
+
playwright-report/
|
|
724
|
+
retention-days: 7
|
|
725
|
+
|
|
726
|
+
merge-reports:
|
|
727
|
+
needs: e2e
|
|
728
|
+
if: always()
|
|
729
|
+
runs-on: ubuntu-latest
|
|
730
|
+
steps:
|
|
731
|
+
- uses: actions/checkout@v4
|
|
732
|
+
- uses: actions/setup-node@v4
|
|
733
|
+
with:
|
|
734
|
+
node-version: 20
|
|
735
|
+
|
|
736
|
+
- name: Download all shard results
|
|
737
|
+
uses: actions/download-artifact@v4
|
|
738
|
+
with:
|
|
739
|
+
pattern: e2e-results-shard-*
|
|
740
|
+
merge-multiple: true
|
|
741
|
+
path: all-results/
|
|
742
|
+
|
|
743
|
+
- name: Merge reports
|
|
744
|
+
run: npx playwright merge-reports --reporter html ./all-results
|
|
745
|
+
|
|
746
|
+
- name: Upload merged report
|
|
747
|
+
uses: actions/upload-artifact@v4
|
|
748
|
+
with:
|
|
749
|
+
name: e2e-report-merged
|
|
750
|
+
path: playwright-report/
|
|
751
|
+
retention-days: 30
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
### 5.2 GitLab CI 配置
|
|
755
|
+
|
|
756
|
+
```yaml
|
|
757
|
+
# .gitlab-ci.yml (E2E 部分)
|
|
758
|
+
e2e-tests:
|
|
759
|
+
stage: test
|
|
760
|
+
image: mcr.microsoft.com/playwright:v1.42.0-jammy
|
|
761
|
+
parallel: 4
|
|
762
|
+
services:
|
|
763
|
+
- postgres:16
|
|
764
|
+
- redis:7
|
|
765
|
+
variables:
|
|
766
|
+
DATABASE_URL: postgresql://test:test@postgres:5432/test
|
|
767
|
+
POSTGRES_DB: test
|
|
768
|
+
POSTGRES_USER: test
|
|
769
|
+
POSTGRES_PASSWORD: test
|
|
770
|
+
script:
|
|
771
|
+
- npm ci
|
|
772
|
+
- npm run build
|
|
773
|
+
- npm run start &
|
|
774
|
+
- npx wait-on http://localhost:3000 --timeout 60000
|
|
775
|
+
- npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
|
|
776
|
+
artifacts:
|
|
777
|
+
when: always
|
|
778
|
+
paths:
|
|
779
|
+
- test-results/
|
|
780
|
+
- playwright-report/
|
|
781
|
+
expire_in: 7 days
|
|
782
|
+
rules:
|
|
783
|
+
- if: $CI_MERGE_REQUEST_ID
|
|
784
|
+
- if: $CI_COMMIT_BRANCH == "main"
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
## 六、稳定性治理
|
|
790
|
+
|
|
791
|
+
### 6.1 Flaky Test 识别与处理
|
|
792
|
+
|
|
793
|
+
```yaml
|
|
794
|
+
识别方法:
|
|
795
|
+
自动检测:
|
|
796
|
+
- CI 中开启 retries=2
|
|
797
|
+
- 通过重试成功判定为 Flaky
|
|
798
|
+
- 每周统计 Flaky Rate 报告
|
|
799
|
+
|
|
800
|
+
手动标记:
|
|
801
|
+
# Playwright
|
|
802
|
+
test.fixme('购物车并发操作', async () => { ... });
|
|
803
|
+
# 标记为已知 Flaky,跳过执行但保留在报告中
|
|
804
|
+
|
|
805
|
+
常见 Flaky 原因与修复:
|
|
806
|
+
时序问题:
|
|
807
|
+
问题: 页面未加载完成就操作
|
|
808
|
+
修复: 使用 expect().toBeVisible() 等待,而非 sleep
|
|
809
|
+
# 错误
|
|
810
|
+
await page.click('#submit');
|
|
811
|
+
# 正确
|
|
812
|
+
await page.getByRole('button', { name: '提交' }).click(); # 自动等待
|
|
813
|
+
|
|
814
|
+
动画干扰:
|
|
815
|
+
问题: CSS 动画导致元素位置不稳定
|
|
816
|
+
修复: 等待动画结束或禁用动画
|
|
817
|
+
# playwright.config.ts
|
|
818
|
+
use: {
|
|
819
|
+
launchOptions: {
|
|
820
|
+
args: ['--force-prefers-reduced-motion'],
|
|
821
|
+
},
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
数据竞争:
|
|
825
|
+
问题: 并行测试共享数据导致冲突
|
|
826
|
+
修复: 每个测试使用唯一数据(见测试数据管理)
|
|
827
|
+
|
|
828
|
+
网络不稳定:
|
|
829
|
+
问题: 外部 API 偶尔超时
|
|
830
|
+
修复: Mock 外部依赖 / 增加超时 / 使用 retry 机制
|
|
831
|
+
|
|
832
|
+
时区/时间:
|
|
833
|
+
问题: 日期相关断言在不同时区失败
|
|
834
|
+
修复: 使用 UTC 或固定时区
|
|
835
|
+
# 在 CI 中设置
|
|
836
|
+
env:
|
|
837
|
+
TZ: Asia/Shanghai
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
### 6.2 性能优化
|
|
841
|
+
|
|
842
|
+
```yaml
|
|
843
|
+
测试执行加速:
|
|
844
|
+
并行执行:
|
|
845
|
+
- Playwright: fullyParallel=true, workers=4
|
|
846
|
+
- CI 分片: --shard=1/4(跨 Job 并行)
|
|
847
|
+
- 预估加速: 4 分片可将 20 分钟缩短到 ~6 分钟
|
|
848
|
+
|
|
849
|
+
减少等待:
|
|
850
|
+
- API 登录替代 UI 登录(节省 ~3s/测试)
|
|
851
|
+
- 路由拦截替代真实 API 调用(不稳定场景)
|
|
852
|
+
- 避免 page.waitForTimeout()(硬等待)
|
|
853
|
+
|
|
854
|
+
浏览器优化:
|
|
855
|
+
- CI 中只用 Chromium(除非需要跨浏览器)
|
|
856
|
+
- 禁用不必要的浏览器功能
|
|
857
|
+
launchOptions:
|
|
858
|
+
args:
|
|
859
|
+
- '--disable-gpu'
|
|
860
|
+
- '--disable-dev-shm-usage'
|
|
861
|
+
- '--disable-extensions'
|
|
862
|
+
|
|
863
|
+
数据优化:
|
|
864
|
+
- 使用 globalSetup 创建共享只读数据
|
|
865
|
+
- 使用 storageState 复用登录状态
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
### 6.3 登录状态复用
|
|
869
|
+
|
|
870
|
+
```typescript
|
|
871
|
+
// tests/e2e/auth.setup.ts
|
|
872
|
+
import { test as setup, expect } from '@playwright/test';
|
|
873
|
+
|
|
874
|
+
const authFile = 'tests/e2e/.auth/user.json';
|
|
875
|
+
|
|
876
|
+
setup('authenticate', async ({ page }) => {
|
|
877
|
+
await page.goto('/login');
|
|
878
|
+
await page.getByLabel('邮箱').fill('test@example.com');
|
|
879
|
+
await page.getByLabel('密码').fill('password123');
|
|
880
|
+
await page.getByRole('button', { name: '登录' }).click();
|
|
881
|
+
await expect(page).toHaveURL(/\/dashboard/);
|
|
882
|
+
|
|
883
|
+
// 保存登录状态
|
|
884
|
+
await page.context().storageState({ path: authFile });
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
// playwright.config.ts 中配置
|
|
888
|
+
projects: [
|
|
889
|
+
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
|
|
890
|
+
{
|
|
891
|
+
name: 'chromium',
|
|
892
|
+
use: {
|
|
893
|
+
...devices['Desktop Chrome'],
|
|
894
|
+
storageState: 'tests/e2e/.auth/user.json',
|
|
895
|
+
},
|
|
896
|
+
dependencies: ['setup'],
|
|
897
|
+
},
|
|
898
|
+
],
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
---
|
|
902
|
+
|
|
903
|
+
## 七、验证
|
|
904
|
+
|
|
905
|
+
### 7.1 测试质量指标
|
|
906
|
+
|
|
907
|
+
| 指标 | 目标 | 测量方法 |
|
|
908
|
+
|------|------|---------|
|
|
909
|
+
| P0 用例覆盖率 | 100% | 对照业务用例清单 |
|
|
910
|
+
| Flaky Rate | < 2% | CI 统计(重试成功/总运行) |
|
|
911
|
+
| 测试总耗时(CI) | < 15 分钟 | CI Pipeline 时间 |
|
|
912
|
+
| 测试通过率 | > 98% | CI 统计 |
|
|
913
|
+
| 缺陷逃逸率 | < 5% | 线上 Bug 中 E2E 应拦截未拦截的比例 |
|
|
914
|
+
|
|
915
|
+
### 7.2 测试报告审查
|
|
916
|
+
|
|
917
|
+
```bash
|
|
918
|
+
# 本地查看 Playwright 报告
|
|
919
|
+
npx playwright show-report
|
|
920
|
+
|
|
921
|
+
# 报告应包含:
|
|
922
|
+
# - 总体通过率与耗时
|
|
923
|
+
# - 失败用例的截图、视频、Trace
|
|
924
|
+
# - 每个 Shard 的执行情况
|
|
925
|
+
# - Flaky 测试标识
|
|
926
|
+
|
|
927
|
+
# 查看 Trace(调试利器)
|
|
928
|
+
npx playwright show-trace test-results/xxx/trace.zip
|
|
929
|
+
# Trace 包含:
|
|
930
|
+
# - 每一步操作的截图
|
|
931
|
+
# - 网络请求/响应
|
|
932
|
+
# - Console 日志
|
|
933
|
+
# - DOM 快照
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
---
|
|
937
|
+
|
|
938
|
+
## 八、回滚
|
|
939
|
+
|
|
940
|
+
### E2E 测试失败时的处理
|
|
941
|
+
|
|
942
|
+
```yaml
|
|
943
|
+
CI 中 E2E 失败:
|
|
944
|
+
阻断发布:
|
|
945
|
+
- P0 用例失败 → 阻止合并/部署
|
|
946
|
+
- 修复优先级高于新功能开发
|
|
947
|
+
|
|
948
|
+
不阻断但需跟进:
|
|
949
|
+
- P1/P2 用例失败 → 允许合并,创建 Bug 跟踪
|
|
950
|
+
- 已知 Flaky 且重试通过 → 不阻断,但需在 Sprint 内修复
|
|
951
|
+
|
|
952
|
+
回滚测试环境:
|
|
953
|
+
# 当测试环境被污染时
|
|
954
|
+
# 1. 重置数据库
|
|
955
|
+
npm run db:reset
|
|
956
|
+
# 2. 重新 Seed
|
|
957
|
+
npm run db:seed
|
|
958
|
+
# 3. 重启服务
|
|
959
|
+
docker-compose restart
|
|
960
|
+
|
|
961
|
+
回滚测试框架升级:
|
|
962
|
+
# 当 Playwright/Cypress 升级导致大面积失败
|
|
963
|
+
# 1. 回退版本
|
|
964
|
+
npm install playwright@previous-version
|
|
965
|
+
# 2. 检查 Breaking Changes
|
|
966
|
+
# 3. 逐步适配后再升级
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
---
|
|
970
|
+
|
|
971
|
+
## Agent Checklist
|
|
972
|
+
|
|
973
|
+
供自动化 Agent 在执行 E2E 测试流程时逐项核查:
|
|
974
|
+
|
|
975
|
+
- [ ] 测试工具已安装(Playwright / Cypress + 浏览器)
|
|
976
|
+
- [ ] 测试策略已制定(覆盖范围/优先级/浏览器矩阵)
|
|
977
|
+
- [ ] Page Object Model 已建立
|
|
978
|
+
- [ ] P0 核心业务流程已有对应测试用例
|
|
979
|
+
- [ ] 测试数据管理方案已实施(自建自清/Test Helper API)
|
|
980
|
+
- [ ] 多浏览器配置已完成
|
|
981
|
+
- [ ] CI 集成已配置(分片并行/报告上传)
|
|
982
|
+
- [ ] 登录状态复用已实现(storageState)
|
|
983
|
+
- [ ] Flaky Test 监控机制已建立
|
|
984
|
+
- [ ] 测试执行总耗时 < 15 分钟
|
|
985
|
+
- [ ] Flaky Rate < 2%
|
|
986
|
+
- [ ] 测试报告含截图/视频/Trace
|
|
987
|
+
- [ ] P0 用例失败会阻断发布
|
|
988
|
+
- [ ] 测试环境回滚方案就绪
|