GitHub Actions 能自动运行 PHP 测试,但失败多因环境不一致;需用 shivammathur/setup-php 显式声明 PHP 版本与扩展(如 mbstring、xml、pdo),配合 php-actions/composer 安装依赖,并按 PHP 大版本选用兼容的 PHPUnit 版本,执行前确保 autoloader 刷新。

直接上结论:GitHub Actions 能自动跑 PHP 测试,但失败率高往往不是测试本身有问题,而是环境没对齐、扩展缺失或 PHPUnit 版本错配。只要把 shivammathur/setup-php、php-actions/composer 和 vendor/bin/phpunit 三者串对,90% 的问题就解决了。
PHP 环境必须显式声明版本和扩展
Ubuntu runner 默认不带 PHP,更不会装mbstring、xml、pdo 这些 PHPUnit 强依赖的扩展。只写 php-version: '8.2' 不够,漏掉 extensions 字段,composer install 就可能卡在 autoload 或 XML 解析上。
- 必须用
shivammathur/setup-php@v2,不能靠系统包管理器 -
php-version值要和composer.json中require.php完全一致(比如'8.2',不是'8') -
extensions至少包含:mbstring,xml,zip,curl,pdo(gd和intl按需加) - 加
coverage: none关掉 Xdebug,否则phpunit启动慢、内存溢出概率高
Composer 依赖安装必须带参数且走专用 Action
用run: composer install 看似简单,实则容易出错:版本不匹配、dev 包混入、交互提示卡住、缓存污染。
- 用
php-actions/composer@v6,别用curl -sS <a href="https://www.php.cn/link/e910517884e11c8a741c3b1da823f47e">https://www.php.cn/link/e910517884e11c8a741c3b1da823f47e</a> -
composer install必须带:--no-interaction --prefer-dist --optimize-autoloader - 如果项目有私有包,得在
composer install前加一行:composer config github-oauth.github.com ${{ secrets.GITHUB_TOKEN }} - 检查
composer.json的config.platform.php,它必须和 workflow 中php-version一致,否则 Composer 会“假装”用旧 PHP 解析依赖
PHPUnit 版本必须按 PHP 大版本动态适配
PHP 8.2 装phpunit/phpunit:^9.6 没问题,但 PHP 7.4 装 ^9.x 就会报 Class "PHPUnit\Framework\TestCase" not found —— 因为 PHPUnit 9+ 要求 PHP ≥ 7.3,但实际兼容性边界更细。
- PHP < 7.4:用
composer require "phpunit/phpunit:^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8" --dev --no-update - PHP ≥ 7.4:用
composer require "phpunit/phpunit:^9.3.3" --dev --no-update - 执行完再
composer update --no-interaction,确保锁文件更新 - 别直接写
vendor/bin/phpunit --version查版本,它可能显示本地缓存结果,应以composer show phpunit/phpunit为准
测试命令执行前必须确认 autoloader 已生成
很多项目 CI 报错Class not found,其实只是 autoload 没刷新。尤其是改过 composer.json 的 autoload 段后,composer install 不一定触发 dump。
- 在
composer install后加一步:composer dump-autoload --optimize - 如果用的是 PSR-4 自动加载,且测试类路径没注册进
autoload-dev,phpunit就找不到测试文件 -
vendor/bin/phpunit启动时加--verbose或--debug,能快速看出是加载失败还是断言失败
最常被忽略的一点:GitHub Actions 的 job 是隔离的,上一步 composer require 改了 composer.json,下一步 composer install 不加 --no-cache 就可能复用旧 lock 文件,导致 PHPUnit 版本没真正升级。



















