验收测试失败主因是csrf拦截、url路由不匹配和浏览器驱动未连上:需在test.php中禁用csrf验证、配置正确base_url和urlmanager、设置assetmanager baseurl并确保web服务已启动。

验收测试跑不起来,基本卡在三件事上:CSRF 拦截、URL 路由不匹配、浏览器驱动没连上。不是 Behat 或 Codeception 本身有问题,而是 Yii 的安全机制和运行时上下文在测试里默认没关、没配、没启。
CSRF 验证导致表单提交直接 400
Yii 默认开启 CSRF 验证,而验收测试(尤其是用 PhpBrowser 或 WebDriver)不会自动携带或提交 _csrf 隐藏字段,页面加载后表单一提交就返回 400 Bad Request。
- 在测试专用配置文件(如
tests/_config/test.php)的components['request']中显式关闭:'enableCsrfValidation' => false - 别只改
web.php—— 验收测试走的是独立入口,必须确保test.php加载了这个配置 - 如果用 Selenium + ChromeDriver 做真实浏览器测试,且想保留 CSRF 测试逻辑,就得在步骤中手动提取
_csrf值再填入,但代价高、易断,不推荐
PhpBrowser 打不开页面或路由 404
PhpBrowser 是无头 HTTP 客户端,它不执行 JS,也不启动 Yii 应用完整生命周期;它只发请求、收响应,所以对 URL 构造和入口路径极其敏感。
-
base_url必须指向一个真实可访问的 Web 服务地址(如http://localhost:8080),不能是index.php?r=...这类 CLI 式路径 - 确认
urlManager在测试配置中设置了'hostInfo' => 'http://localhost:8080',否则生成的链接(如$urlManager->createUrl(['site/login']))会缺域名,变成相对路径 - 别在
features/下写Given I am on "/index.php?r=site/login"—— 这绕过了 Yii 的路由,PhpBrowser会当普通 PHP 文件处理,不触发应用启动 - 正确写法是
Given I am on "/site/login",前提是你的 Web 服务器已配置好重写规则(如 Apache 的.htaccess或 Nginx 的try_files)
Selenium 启动后白屏或卡死
ChromeDriver 启动了,浏览器打开了,但页面空白、JS 不执行、登录按钮点不了——大概率是 AssetBundle 资源路径错乱或 Yii 的 baseUrl 没适配测试域名。
- 在
tests/_config/test.php的components['assetManager']中强制指定:'baseUrl' => '/assets'(不要用@web/assets这类别名,别名在测试上下文里可能解析失败) - 检查
components['request']['scriptUrl']是否设为/index.php,否则生成的资源 URL 会多出错误前缀 - ChromeDriver 版本必须和 Chrome 浏览器主版本严格匹配,比如 Chrome 124 就得用
chromedriver_v124.0.0.0, mismatch 会导致 session 创建失败,日志里常出现session not created: This version of ChromeDriver only supports Chrome version XX - 运行前先手动访问一次
http://localhost:8080/site/login,确认页面能正常渲染、无 JS 报错,再让 Selenium 跑
最常被忽略的一点:验收测试不是“写完就能跑”,它依赖一个**正在监听的 Web 服务进程**。别指望 codecept run acceptance 自己拉起 Yii —— 它只负责驱动浏览器。你得提前用 php yii serve --port=8080 或 Nginx 启好服务,且确保该端口没被占用、防火墙没拦、index.php 权限可读。











