文档目录
测试策略与实践

引言

本指南为 DouPHP 项目建立完整的测试策略与实践方法,覆盖测试金字塔、单元测试、集成测试、端到端测试、API 自动化测试、数据库测试、前端与小程序测试、覆盖率统计、持续集成以及性能与安全测试。目标是帮助团队在现有三端入口(前台 front、后台 admin、API api)与共享核心 core 的架构下,构建稳定、可维护、可回归的质量保障体系。

项目结构

DouPHP 采用“三端入口 + 共享核心 + 模块化”的架构:

  • 前台 front:面向访客与会员的 HTML 渲染入口
  • 后台 admin:管理员使用的 HTML 管理界面
  • API api:面向小程序/SPA/第三方的 JSON API
  • 核心 core:DI 容器、ORM、路由、安全、通用服务、模板引擎等共享能力
  • 配置 config:数据库、模块清单、路由、安全等
  • 插件 plugin:支付、第三方登录等扩展
  • 主题 theme / 语言包 languages / 小程序 miniprogram
graph TB
A["请求入口<br/>index.php"] --> B["引导与初始化<br/>core/bootstrap.php"]
B --> C["配置加载<br/>config/config.php"]
B --> D["容器与门面注册<br/>core/bootstrap.php"]
D --> E["路由分发"]
E --> F["前台控制器<br/>front/*"]
E --> G["后台控制器<br/>admin/*"]
E --> H["API 控制器<br/>api/*"]
G --> I["中间件链<br/>CSRF/权限/安全头"]
H --> J["认证中间件<br/>UserAuthMiddleware"]
F --> K["视图渲染<br/>DouView"]
G --> K
H --> L["JSON 响应<br/>ApiResponse"]
K --> M["ORM/DB<br/>DOU_DB_CONFIG"]
L --> M

核心组件

  • 引导与初始化:定义应用根路径、配置路径、存储路径、HTTP 协议常量;加载站点配置;注册自动加载、门面别名、DI 容器、路由调度器、Request 单例、全局助手;注册事件与场景。
  • 配置:数据库连接、表前缀、字符集、系统标识、调试开关、应用密钥等。
  • 控制器基类:
    • API 基类:提供会员中心导航构建、统一使用 helper/门面调用服务。
    • Admin 基类:封装 view() 渲染、布局变量注入、AI 工具栏注入、删除结果响应、布尔切换响应等。
  • 中间件:API 用户认证中间件从 Authorization 头解析 token,注入上下文并处理未认证/无工作身份的错误响应。
  • 小程序环境探测:统一判断是否处于非正式版调试环境与服务器调试模式。

架构总览

下图展示一次典型 API 请求的调用链,涵盖认证中间件、控制器、服务层与 ORM/DB 访问。

sequenceDiagram
participant Client as "客户端"
participant Router as "路由调度器"
participant MW as "UserAuthMiddleware"
participant Ctrl as "API 控制器"
participant Svc as "业务服务"
participant DB as "ORM/DB"
Client->>Router : "HTTP 请求"
Router->>MW : "鉴权中间件"
MW->>MW : "解析 Authorization Bearer Token"
MW-->>Router : "通过/拒绝"
Router->>Ctrl : "匹配控制器动作"
Ctrl->>Svc : "执行业务逻辑"
Svc->>DB : "查询/写入数据"
DB-->>Svc : "返回模型/集合"
Svc-->>Ctrl : "返回结果"
Ctrl-->>Client : "JSON 响应"

详细组件分析

测试金字塔与分层策略

  • 单元测试(底层):针对纯函数、Service、Model、工具类的行为断言,快速、稳定、隔离外部依赖。
  • 集成测试(中层):验证控制器到服务、ORM 到数据库、中间件链路的协作,通常使用事务回滚或内存数据库。
  • 端到端测试(顶层):模拟真实浏览器/小程序/第三方客户端,覆盖关键用户流程(登录、下单、支付回调)。

建议比例:单元 70%、集成 20%、E2E 10%,以平衡速度与覆盖面。

单元测试实践(PHPUnit)

  • 目标:覆盖 Service、Model、工具类、校验逻辑、格式化器等。
  • 要点:
    • 使用 Mock 对象隔离 DB、Session、第三方 SDK、邮件发送等副作用。
    • 使用数据提供者(DataProvider)组织多组输入输出用例。
    • 对时间敏感逻辑使用固定时钟或时间桩。
    • 对随机性使用种子或确定性数据。
  • 示例方向:
    • 订单金额计算、折扣叠加、税费计算
    • 用户密码哈希升级、凭据校验
    • 列表分页、排序、过滤条件组合
    • 附件上传后的清理与草稿生成

提示:将测试代码放在 tests/ 目录下,按模块划分命名空间,遵循 PSR-4 自动加载。

集成测试实践

  • 目标:验证控制器到服务、中间件到控制器的完整链路。
  • 要点:
    • 使用独立测试数据库或 SQLite 内存库,避免污染生产数据。
    • 使用事务包裹每个测试用例,或在 setUp/tearDown 中清理数据。
    • 模拟外部依赖(短信、支付、云存储),仅验证接口契约。
    • 对路由与中间件进行端到端 HTTP 级集成测试(不启动真实 Web 服务器时可用内置测试客户端)。

端到端测试实践

  • 目标:验证关键业务流程在真实环境中的可用性。
  • 要点:
    • 使用浏览器自动化(如 Playwright/Puppeteer)或小程序测试框架。
    • 覆盖登录、创建订单、支付回调、退款、售后等主流程。
    • 使用稳定的测试账号与预置数据,避免依赖不稳定外部服务。
    • 对截图、网络请求、控制台日志进行断言与收集。

API 接口自动化测试

  • 目标:确保 API 的请求/响应契约稳定。
  • 要点:
    • 模拟 HTTP 请求,设置必要 Header(如 Authorization、Content-Type)。
    • 断言状态码、响应体结构、关键字段值、错误消息。
    • 覆盖正常路径与异常路径(参数缺失、权限不足、限流)。
    • 对幂等接口进行重复调用验证。
sequenceDiagram
participant Test as "测试脚本"
participant API as "API 入口"
participant Auth as "认证中间件"
participant Ctrl as "控制器"
participant Svc as "服务"
participant DB as "数据库"
Test->>API : "POST /api/order/create"
API->>Auth : "校验令牌"
Auth-->>API : "通过/拒绝"
API->>Ctrl : "路由到控制器"
Ctrl->>Svc : "创建订单"
Svc->>DB : "持久化订单"
DB-->>Svc : "返回结果"
Svc-->>Ctrl : "返回订单数据"
Ctrl-->>Test : "JSON 响应"
Test->>Test : "断言状态码与字段"

数据库测试策略

  • 隔离:使用独立测试库或内存库,避免影响其他测试与生产数据。
  • 迁移:对 schema 变更编写迁移脚本,并在测试环境中执行。
  • 事务:每个测试用例在事务中运行,结束后回滚,保证数据一致性。
  • 数据准备:使用工厂或 Fixture 生成稳定数据,减少耦合。
  • 复杂查询:对聚合、分页、排序、全文检索进行专项测试。

前端与小程序测试

  • JavaScript 单元测试:对工具函数、表单校验、数据处理逻辑进行断言。
  • 组件测试:对 UI 组件的渲染、交互、状态变化进行测试。
  • 用户交互测试:模拟点击、输入、导航,验证页面行为。
  • 小程序测试:利用小程序测试框架或真机调试,结合 env.ts 的环境探测能力,区分开发/正式环境行为。
flowchart TD
Start(["开始"]) --> DetectEnv["读取环境版本<br/>isDebugEnv/isServerDebug"]
DetectEnv --> IsRelease{"是否正式版?"}
IsRelease --> |是| Silent["静默模式<br/>关闭调试 UI"]
IsRelease --> |否| DebugUI["启用调试 UI<br/>打印日志/提示"]
DebugUI --> RunTests["执行前端/小程序测试"]
Silent --> RunTests
RunTests --> End(["结束"])

覆盖率统计与分析

  • 工具:Xdebug + PHPUnit 覆盖率报告,或 PHPBench/Blackfire 进行性能剖析。
  • 指标:语句覆盖率、分支覆盖率、函数覆盖率、行覆盖率。
  • 阈值:建议核心模块达到 80%+,新增代码保持高覆盖率。
  • 报告:生成 HTML 报告,纳入 CI 流水线,失败时阻断合并。

持续集成中的测试自动化

  • 触发:Push/Pull Request 触发全量或增量测试。
  • 步骤:
    • 安装依赖(Composer)、初始化数据库、执行迁移。
    • 运行单元测试、集成测试、E2E 测试。
    • 生成覆盖率报告与测试报告。
    • 缓存依赖与构建产物,加速流水线。
  • 质量门禁:覆盖率不达标、测试失败、静态检查失败均阻断合并。

性能测试

  • 目标:识别瓶颈(CPU、I/O、DB 查询、序列化)。
  • 方法:
    • 基准测试:对热点函数进行微基准测试。
    • 负载测试:模拟并发请求,观察吞吐与延迟。
    • 压测:逐步增加负载,找到拐点与资源上限。
  • 优化:索引优化、查询改写、缓存引入、异步任务拆分。

安全测试

  • 目标:发现常见漏洞(SQL 注入、XSS、CSRF、越权、敏感信息泄露)。
  • 方法:
    • 静态扫描:SAST 工具扫描代码。
    • 动态扫描:DAST 工具对运行环境进行渗透测试。
    • 依赖审计:定期更新依赖,修复已知漏洞。
    • 安全中间件:CSRF、XSS、安全响应头、限流、审计日志。
  • 合规:遵循最小权限原则,敏感配置加密存储。

依赖关系分析

  • 引导阶段依赖:bootstrap.php 依赖 config.php 的数据库与系统配置,注册容器、门面、路由、Request 单例与全局助手。
  • 控制器依赖:API/Admin 控制器基类依赖中间件、服务、ORM、模板引擎。
  • 中间件依赖:API 认证中间件依赖 Request、Auth、ApiResponse。
  • 小程序依赖:env.ts 依赖 site.js 的配置与环境变量。
graph LR
Boot["引导 bootstrap.php"] --> Cfg["配置 config.php"]
Boot --> Facade["门面与助手"]
Boot --> Container["DI 容器"]
Boot --> Route["路由调度器"]
Route --> CtrlAPI["API 控制器"]
Route --> CtrlAdmin["Admin 控制器"]
CtrlAPI --> MW["认证中间件"]
CtrlAdmin --> View["视图渲染"]
CtrlAPI --> Svc["业务服务"]
CtrlAdmin --> Svc
Svc --> DB["ORM/DB"]

性能考虑

  • 测试环境应与生产环境配置接近,避免误判。
  • 使用内存数据库或轻量 DB 提升集成测试速度。
  • 对慢查询与热点接口进行专项压测。
  • 引入缓存与异步任务,降低同步阻塞。
  • 监控 CPU、内存、I/O、DB 连接池使用情况。

故障排查指南

  • 常见问题:
    • 数据库连接失败:检查 DOU_DB_CONFIG 与 config.php 配置。
    • 路由不生效:确认引导阶段已注册路由调度器与 Request 单例。
    • 认证失败:检查 Authorization 头格式与中间件实现。
    • 视图渲染异常:确认模板路径与布局变量注入。
  • 定位方法:
    • 开启调试模式,查看错误堆栈与日志。
    • 使用断点与日志输出,追踪调用链。
    • 隔离外部依赖,逐步缩小问题范围。

结论

通过分层测试策略与完善的自动化流水线,DouPHP 可以在保持三端入口与共享核心架构灵活性的同时,确保代码质量与交付稳定性。建议优先落地单元测试与集成测试,逐步完善 E2E 与性能/安全测试,形成闭环的质量保障体系。

附录

关键入口与基类参考

  • 引导与初始化:bootstrap.php:24-180
  • 配置项:config.php:15-52
  • API 控制器基类:BaseController.php(API):24-60
  • Admin 控制器基类:BaseController.php(Admin):45-370
  • API 认证中间件:UserAuthMiddleware.php:25-93
  • 小程序环境探测:env.ts:1-37
  • 云服务 API 依赖声明:_'.api\composer.json:1-24
添加日期:2026-10-05