yii2单元测试需复用官方tests/结构,补全_bootstrap.php初始化,启用yii2模块并配置part:[orm],fixture键名须匹配模型属性而非字段名,config/test.php必须可实例化application。

Yii2 单元测试用 Codeception 上手,关键不是“装完就能跑”,而是配对、分清场景、避开默认陷阱。官方骨架已内置测试结构,硬执行 codecept bootstrap 反而容易破坏原有引导逻辑,导致 Yii::$app 为 null 或配置加载失败。
保留原 tests/ 结构,只补关键文件
Yii2 项目初始化时自带 tests/ 目录(含 _bootstrap.php、unit.suite.yml 等),这是可直接复用的基础。别删掉重来:
- 存在
tests/_bootstrap.php且内容完整(定义YII_ENV、加载 autoloader 和 Yii.php、引入config/test.php),就跳过初始化,直接运行codecept build - 若
_bootstrap.php缺失或为空,手动补三行核心初始化:define('YII_ENV', 'test');<br>require __DIR__ . '/../../vendor/autoload.php';<br>require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';<br>$config = require __DIR__ . '/../../config/test.php';<br>(new yii\web\Application($config)); -
tests/unit.suite.yml必须启用Yii2模块并指定part: [orm]—— 否则$I->haveRecord()、$I->seeRecord()等 ActiveRecord 快捷方法不可用,事务隔离和模型验证也不会自动生效
unit 测试不等于“随便 new 个 Model”
unit 套件默认不启动完整应用,Yii::$app 是 null。是否需要它,取决于测试目标:
- 只验证模型规则(如
rules()、validate())?可不用 Yii2 模块,纯 PHP 方式:$model = new User(); $model->username = ''; $this->assertFalse($model->validate()); - 要测 AR 行为(如
save()、关联查询、事务内操作)?必须启用Yii2: { part: [orm] },且config/test.php中 DB 组件必须正确定义(host/user/password/dbname 等完整) - 别在 unit 测试里调
$I->amOnPage()——那是 functional 套件专属方法,混用直接报错
fixture 数据要对得上模型属性,不是数据库字段名
测试数据靠 fixtures 注入,但键名必须与模型的 属性名 一致,而非底层字段名:
- 模型中定义
public $username;,fixture 数组就得写'username' => 'demo',不能写'user_name' => 'demo' - 若模型重写了
tableName()或用了字段映射(如通过attributes()),Codeception 不做自动转换,仍以属性名为准 - 数据库本身不需额外建 test 库——Yii2 单元测试默认走内存事务(
beginTransaction()+rollback()),每条测试用例结束后自动清空变更,真正要检查的是 fixture 是否覆盖了所有必填属性
运行前先确认 config/test.php 能实例化 Application
这个配置文件是 unit 测试的入口,出错常静默失败(尤其 PHP ≥ 8.1):
- 确保末尾返回的是完整配置数组,并最终用于构建
yii\web\Application或yii\console\Application实例 - 删掉生产环境组件(如 mailer、redis 若未启用 cachepart)、精简中间件;DB、log、cache 等依赖组件必须存在且可实例化
- 若用到 Redis 缓存,除了启用
Yii2: { part: [cachepart] },还要在config/test.php中明确定义'cache' => ['class' => 'yii\redis\Cache']等











