+测试编辑数据库的 artisan 命令
+Testing an artisan command that edits the database
我正在尝试测试旨在执行某些数据库维护的 artisan
命令。
特别是,它搜索没有填充列的记录,并填充它。
这是命令的fire()
方法的简化版本:
public function fire()
{
$items = Item::all();
$total = $items->count();
$updated = 0;
foreach ($items as $item) {
if ($item->myColumn != 'x') {
$item->myColumn = 'x';
$item->save();
$updated++;
}
}
$this->info("total: $total updated: $updated");
}
我的(验收)测试非常简单,执行以下操作:
- 在数据库中插入一条记录
- 调用
artisan
命令
- 检查插入的记录是否已更新
这是代码:
public function doTheTest(AcceptanceTester $I)
{
$I->wantTo('setup the myColumn when it is not set');
$id = $I->haveRecord('items', [
'myColumn' => '',
]);
$I->runShellCommand('php artisan items:updater');
$I->seeRecord('items', [
'id' => $id,
'myColumn' => 'x',
]);
}
但是测试失败,我收到以下消息:
Couldn't see record "items",{"id":101,"myColumn":"x"}:
Couldn't find items with {"id":101,"code":"x"}
可以看到,新记录的id
是101,因为db dump中已经有100条了,但是奇怪的是命令中的$this->info()
打印
total: 100 updated: 100
好像测试中使用的数据库和artisan
中使用的数据库不同
此外,如果在测试结束时我尝试抓取添加的记录,并打印它,如以下代码片段所示
public function doTheTest(AcceptanceTester $I)
{
/* ... */
$item = $I->grabRecord('items', [
'id' => $id,
]);
\Codeception\Util\Debug::debug($item);
}
和运行 codecept run acceptance --debug
命令,我得到了添加的记录
stdClass Object
(
[id] => 101
[myColumn] =>
)
我很困惑,因为只有一个数据库,但我肯定误解了这里的一些重要内容。
有人可以帮我吗?
非常感谢,
问题是每个使用 Laravel4 模块的查询都在一个事务中 运行,默认情况下,该事务将在最后回滚。如果您查看 Laravel4 文档的 Config 部分,它会指出
cleanup: boolean, default true - all db queries will be run in transaction, which will be rolled back at the end of test.
如果您重新启动 MySQL 服务器,您可以检查这个(在这种情况下,当您再次 运行 测试时,您仍然会看到 id 101),或者查看 MySQL 日志,每个测试都有如下条目:
150417 23:24:24 2 Connect root@localhost on laravel-test
2 Prepare set names 'utf8' collate 'utf8_unicode_ci'
2 Execute set names 'utf8' collate 'utf8_unicode_ci'
2 Close stmt
2 Query START TRANSACTION
2 Prepare insert into items
(myColumn
) values (?)
2 Execute insert into items
(myColumn
) values ('')
2 Close stmt
2 Query ROLLBACK
2 Quit
要解决此问题,您需要在 codeception.yml
文件中配置 Laravel4 模块的选项 cleanup
,如下所示:
modules:
config:
Laravel4:
cleanup: false
我正在尝试测试旨在执行某些数据库维护的 artisan
命令。
特别是,它搜索没有填充列的记录,并填充它。
这是命令的fire()
方法的简化版本:
public function fire()
{
$items = Item::all();
$total = $items->count();
$updated = 0;
foreach ($items as $item) {
if ($item->myColumn != 'x') {
$item->myColumn = 'x';
$item->save();
$updated++;
}
}
$this->info("total: $total updated: $updated");
}
我的(验收)测试非常简单,执行以下操作:
- 在数据库中插入一条记录
- 调用
artisan
命令 - 检查插入的记录是否已更新
这是代码:
public function doTheTest(AcceptanceTester $I)
{
$I->wantTo('setup the myColumn when it is not set');
$id = $I->haveRecord('items', [
'myColumn' => '',
]);
$I->runShellCommand('php artisan items:updater');
$I->seeRecord('items', [
'id' => $id,
'myColumn' => 'x',
]);
}
但是测试失败,我收到以下消息:
Couldn't see record "items",{"id":101,"myColumn":"x"}:
Couldn't find items with {"id":101,"code":"x"}
可以看到,新记录的id
是101,因为db dump中已经有100条了,但是奇怪的是命令中的$this->info()
打印
total: 100 updated: 100
好像测试中使用的数据库和artisan
中使用的数据库不同
此外,如果在测试结束时我尝试抓取添加的记录,并打印它,如以下代码片段所示
public function doTheTest(AcceptanceTester $I)
{
/* ... */
$item = $I->grabRecord('items', [
'id' => $id,
]);
\Codeception\Util\Debug::debug($item);
}
和运行 codecept run acceptance --debug
命令,我得到了添加的记录
stdClass Object
(
[id] => 101
[myColumn] =>
)
我很困惑,因为只有一个数据库,但我肯定误解了这里的一些重要内容。
有人可以帮我吗?
非常感谢,
问题是每个使用 Laravel4 模块的查询都在一个事务中 运行,默认情况下,该事务将在最后回滚。如果您查看 Laravel4 文档的 Config 部分,它会指出
cleanup: boolean, default true - all db queries will be run in transaction, which will be rolled back at the end of test.
如果您重新启动 MySQL 服务器,您可以检查这个(在这种情况下,当您再次 运行 测试时,您仍然会看到 id 101),或者查看 MySQL 日志,每个测试都有如下条目:
150417 23:24:24 2 Connect root@localhost on laravel-test
2 Prepare set names 'utf8' collate 'utf8_unicode_ci'
2 Execute set names 'utf8' collate 'utf8_unicode_ci'
2 Close stmt
2 Query START TRANSACTION
2 Prepare insert intoitems
(myColumn
) values (?)
2 Execute insert intoitems
(myColumn
) values ('')
2 Close stmt
2 Query ROLLBACK
2 Quit
要解决此问题,您需要在 codeception.yml
文件中配置 Laravel4 模块的选项 cleanup
,如下所示:
modules:
config:
Laravel4:
cleanup: false