Laravel9+Docker+Gitlab CI测试时遇SQLSTATE[HY000][2002]错误求解决
问题:Laravel 9 + GitLab CI 中迁移正常但测试时数据库连接失败
环境配置
使用 Laravel 9、Docker 和 GitLab CI,以下是 gitlab-ci.yml 配置:
image: code.scarsgaming.net:5050/beastburst/beastburst-website:latest services: - mysql:5.7 variables: DB_HOST: mysql DB_USERNAME: root MYSQL_DATABASE: test MYSQL_ROOT_PASSWORD: test APP_ENV: testing stages: - test feature_test: stage: test script: - cp .env.example .env - cp .env.example .env.testing - composer install - php artisan key:generate - php artisan config:clear - php artisan migrate - php artisan test
问题现象
php artisan migrate 可正常执行完成所有迁移,但执行 php artisan test 时出现数据库连接错误:
$ php artisan test Warning: TTY mode requires /dev/tty to be read/writable. PASS Tests\Unit\ExampleTest ✓ that true is true FAIL Tests\Feature\HomePageTest ⨯ the homepage runs fine FAIL Tests\Feature\ShopTest ⨯ the shop home page runs fine ⨯ supporter product --- • Tests\Feature\HomePageTest > the homepage runs fine PHPUnit\Framework\ExceptionWrapper SQLSTATE[HY000] [2002] No such file or directory (SQL: SHOW FULL TABLES WHERE table_type = 'BASE TABLE') at vendor/laravel/framework/src/Illuminate/Database/Connection.php:759 755▕ // If an exception occurs when attempting to run a query, we'll format the error 756▕ // message to include the bindings with SQL, which will make this exception a 757▕ // lot more helpful to the developer instead of just the database's errors. 758▕ catch (Exception $e) { ➜ 759▕ throw new QueryException( 760▕ $query, $this->prepareBindings($bindings), $e 761▕ ); 762▕ } 763▕ }
phpunit.xml 配置
<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" > <testsuites> <testsuite name="Unit"> <directory suffix="Test.php">./tests/Unit</directory> </testsuite> <testsuite name="Feature"> <directory suffix="Test.php">./tests/Feature</directory> </testsuite> </testsuites> <coverage processUncoveredFiles="true"> <include> <directory suffix=".php">./app</directory> </include> </coverage> <php> <env name="APP_ENV" value="testing"/> <env name="APP_CONFIG_CACHE" value="cache/config-testing.php" force="true"/> <env name="BCRYPT_ROUNDS" value="4"/> <env name="CACHE_DRIVER" value="array"/> <server name="DB_CONNECTION" value="testing_db" force="true"/> <!-- <env name="DB_CONNECTION" value="sqlite"/> --> <!-- <env name="DB_DATABASE" value=":memory:"/> --> <env name="MAIL_MAILER" value="array"/> <env name="QUEUE_CONNECTION" value="sync"/> <env name="SESSION_DRIVER" value="array"/> <env name="TELESCOPE_ENABLED" value="false"/> </php> </phpunit>
原因分析
- 迁移命令使用的是
APP_ENV=testing对应的数据库配置(环境变量或.env.testing),但 PHPUnit 测试时通过<server>标签强制指定了DB_CONNECTION=testing_db,而你的config/database.php中并未定义testing_db这个数据库连接的具体参数(如主机、数据库名、账号密码等),导致测试时无法找到有效的连接配置。 - 迁移时能正常连接是因为使用了默认的
mysql连接,该连接继承了 GitLab CI 环境变量中的DB_HOST、MYSQL_DATABASE等参数,而testing_db连接无对应配置,自然无法连接到 MySQL 服务。
解决方法
方法一:修改 phpunit.xml 使用已有的连接
将 phpunit.xml 中的 DB_CONNECTION 值改为你已配置好的 mysql 连接,替换掉 testing_db:
<server name="DB_CONNECTION" value="mysql" force="true"/>
这样测试时会和迁移使用相同的数据库连接配置,直接对接 GitLab CI 提供的 MySQL 服务。
方法二:添加 testing_db 连接配置
如果需要保留 testing_db 作为测试专用连接,在 config/database.php 的 connections 数组中添加以下配置,继承环境变量的参数:
'testing_db' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('MYSQL_DATABASE', 'test'), 'username' => env('DB_USERNAME', 'root'), 'password' => env('MYSQL_ROOT_PASSWORD', 'test'), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, ],
确保环境变量中的参数能正确传入这个连接配置。
额外优化
在测试脚本中可以添加 php artisan config:cache 确保配置生效,但核心问题还是数据库连接配置不匹配,解决后即可正常运行测试。
内容的提问来源于stack exchange,提问作者Venelin
相关产品推荐
相关产品推荐

