Yii2功能测试本地正常,GitLab CI运行套件时单测失败
问题背景
本地运行以下测试命令均正常:
./vendor/bin/codecept run functional EndingEndUserPresenceInStructureCest ./vendor/bin/codecept run functional ./vendor/bin/codecept run
但在GitLab CI环境中,单独运行上述指定测试可通过,运行整个功能测试套件时,仅该测试失败,其余测试均正常。
测试代码
class EndingEndUserPresenceInStructureCest { public function _before(FunctionalTester $I) { } public function endingEndUserPresenceInStructure(FunctionalTester $I) { $I->haveFixtures(['user' => UtenteFixture::className()]); $I->haveFixtures(['anagrafica' => AnagraficaFixture::className()]); $user = $I->grabFixture('user', 'user'); $I->amLoggedInAs($user->id); $I->amOnRoute('anagrafica', ['tipologia' => '9']); $I->see('test_struttura', 'td'); $I->see('Nuova Anagrafica', 'a'); $enduser1 = $I->grabFixture('anagrafica', 'enduser1'); $enduser2 = $I->grabFixture('anagrafica', 'enduser2'); $I->see($enduser1->cognome, 'a'); $I->see($enduser2->cognome, 'a'); $I->amOnRoute('/passaggio/dimissione', ['anagrafica' => $enduser1->idanagrafica]); $I->see('data dimissione'); $I->fillField('Passaggio[data_uscita]', date('Y-m-d H:i:s')); $I->fillField('Passaggio[motivazione]', 'Test motivazione della dimissione'); $I->fillField('Passaggio[destinazione_uscita]', 'Test destinazione uscita'); $I->click('Salva'); $I->see('Anagrafica di ' . $enduser1->cognome, 'h1'); } }
Codeception配置
actor: Tester paths: tests: tests log: tests/_output data: tests/_data helpers: tests/_support bootstrap: _bootstrap.php settings: colors: true memory_limit: 1024M modules: config: Yii2: configFile: 'config/test.php' cleanup: false transaction: false Db: dsn: 'mysql:host=app_db;dbname=app_test' user: 'root' password: 'password' populate: true cleanup: true dump: tests/_data/app_test.sql
GitLab CI配置
app-test: stage: app-test image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG services: - name: mariadb:10.6 alias: app_db variables: MYSQL_DATABASE: app_test MYSQL_ROOT_PASSWORD: password artifacts: when: always name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME" paths: - tests/_output/* - runtime/* exclude: - runtime/cache/ expire_in: 1 week script: - composer install - cp config/{test_,}db.php - cp config/ldap_config{_example,}.php - cp config/params{_example,}.php - cp config/settings{_example,}.php - cp config/yii_env_debug{_example,}.php - ./vendor/bin/codecept -vvv run functional
排查思路
- 检查测试隔离性:当前Yii2模块配置
transaction: false,测试不会自动回滚事务。其他测试可能修改了数据库数据,导致该测试运行时数据状态异常。可尝试将transaction改为true,让每个测试在独立事务中运行并自动回滚;或在测试的_before/_after方法中手动重置fixture、清理数据。 - 确认测试执行顺序:本地与CI的测试执行顺序可能不同,该测试在CI中可能运行在修改了相同表数据的测试之后。可在CI中输出测试执行顺序日志,或强制指定该测试的执行顺序,验证是否还会失败。
- 验证fixture加载逻辑:确认
haveFixtures是否在每次测试时都正确重置数据。若其他测试未正确清理fixture数据,可能导致该测试的fixture被污染。可在_before方法中手动调用fixture的重置方法,确保初始数据干净。 - 对比数据库初始化状态:检查CI环境中
tests/_data/app_test.sql是否正确同步,或在CI运行测试前手动执行数据库初始化命令,确保本地与CI的初始数据库状态一致。 - 分析详细错误日志:CI中已用
-vvv开启详细日志,查看tests/_output中的失败详情(如元素未找到、数据库操作失败等),根据具体错误定位问题。 - 排查时间相关问题:测试中使用
date('Y-m-d H:i:s'),确认CI服务器时区与本地是否一致,时区差异可能导致时间字段验证失败,建议使用固定时间或配置统一时区。
内容的提问来源于stack exchange,提问作者Maxxer
相关产品推荐
相关产品推荐

