测试数据库

测试类

为了利用 CodeIgniter 为测试提供的内置数据库工具,你的测试必须扩展 CIUnitTestCase 并使用 DatabaseTestTrait:

<?php

namespace App\Database;

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;

class MyTests extends CIUnitTestCase
{
    use DatabaseTestTrait;

    // ...
}

由于在 setUp()tearDown() 阶段执行了特殊功能,所以如果你需要使用这些方法,必须确保调用父类的方法,否则你将失去这里描述的大部分功能:

<?php

namespace App\Database;

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;

class MyTests extends CIUnitTestCase
{
    use DatabaseTestTrait;

    protected function setUp(): void
    {
        parent::setUp();

        // Do something here....
    }

    protected function tearDown(): void
    {
        parent::tearDown();

        // Do something here....
    }
}

设置测试数据库

运行数据库测试时,你需要提供可在测试期间使用的数据库。框架提供了特定于 CodeIgniter 的工具,而不是使用 PHPUnit 内置的数据库功能。第一步是确保你在 app/Config/Database.php 中设置了 tests 数据库组。这指定了仅在运行测试时使用的数据库连接,以保持其他数据的安全。

如果团队中有多个开发人员,你可能希望将凭证保存在 .env 文件中。要这样做,请编辑文件以确保存在以下行并具有正确的信息:

database.tests.hostname = localhost
database.tests.database = ci4_test
database.tests.username = root
database.tests.password = root
database.tests.DBDriver = MySQLi
database.tests.DBPrefix =
database.tests.port = 3306

迁移和种子

运行测试时,你需要确保数据库具有正确的 schema 设置并且对每个测试处于已知状态。你可以使用迁移和种子来设置数据库,方法是在测试中添加一些类属性。

<?php

namespace App\Database;

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;

class MyTests extends CIUnitTestCase
{
    use DatabaseTestTrait;

    // For Migrations
    protected $migrate     = true;
    protected $migrateOnce = false;
    protected $refresh     = true;
    protected $namespace   = 'Tests\Support';

    // For Seeds
    protected $seedOnce = false;
    protected $seed     = 'TestSeeder';
    protected $basePath = 'path/to/database/files';

    // ...
}

迁移

$migrate

此布尔值确定是否在测试之前运行数据库迁移。默认情况下,始终将数据库迁移到 $namespace 定义的最新可用状态。如果为 false,则不运行迁移。如果要禁用迁移,请设置为 false

$migrateOnce

此布尔值确定是否只运行一次数据库迁移。如果要在首次测试之前运行一次迁移,请设置为 true。如果不存在或为 false,则在每次测试之前运行迁移。

$refresh

此布尔值确定是否在测试之前完全刷新数据库。如果为 true,则所有迁移都会回滚到版本 0。

$namespace

默认情况下,CodeIgniter 将在 tests/_support/Database/Migrations 中查找在测试期间应运行的迁移。你可以在 $namespace 属性中指定新命名空间来更改此位置。这不应包括 Database\Migrations 子命名空间,而只是基本命名空间。

重要

如果将此属性设置为 null,则像 php spark migrate --all 一样从所有可用的命名空间运行迁移。

种子

$seed

如果存在且非空,则指定在测试运行之前用来向数据库填充测试数据的种子文件的名称。

$seedOnce

此布尔值确定是否只运行一次数据库种子。如果要在首次测试之前运行一次数据库种子,请设置为 true。如果不存在或为 false,则在每次测试之前运行数据库种子。

$basePath

默认情况下,CodeIgniter 将在 tests/_support/Database/Seeds 中查找在测试期间应运行的种子。你可以通过指定 $basePath 属性来更改此目录。这不应包括 Seeds 目录,而是保存子目录的单个目录的路径。

帮助方法

DatabaseTestTrait 类提供了几个帮助方法来帮助测试数据库。

更改数据库状态

regressDatabase()

在上述 $refresh 期间调用,如果需要手动重置数据库,此方法可用。

migrateDatabase()

setUp() 期间调用,如果需要手动运行迁移,此方法可用。

seed($name)

允许你手动将 Seed 加载到数据库中。唯一的参数是要运行的种子的名称。种子必须存在于 $basePath 中指定的路径内。

hasInDatabase($table, $data)

将新行插入数据库中。此行在当前测试运行后被删除。$data 是一个包含要插入表中的数据的关联数组。

<?php

$data = [
    'email' => 'joe@example.com',
    'name'  => 'Joe Cool',
];
$this->hasInDatabase('users', $data);

从数据库获取数据

grabFromDatabase($table, $column, $criteria)

返回在行与 $criteria 匹配的指定表中的 $column 的值。如果找到多行,它只会返回第一行。

<?php

$username = $this->grabFromDatabase('users', 'username', ['email' => 'joe@example.com']);

断言

dontSeeInDatabase($table, $criteria)

断言与 $criteria 中的键/值对匹配的行在数据库中不存在。

<?php

$criteria = [
    'email'  => 'joe@example.com',
    'active' => 1,
];
$this->dontSeeInDatabase('users', $criteria);

seeInDatabase($table, $criteria)

断言与 $criteria 中的键/值对匹配的行在数据库中存在。

<?php

$criteria = [
    'email'  => 'joe@example.com',
    'active' => 1,
];
$this->seeInDatabase('users', $criteria);

seeNumRecords($expected, $table, $criteria)

断言在数据库中找到的与 $criteria 匹配的行数。

<?php

$criteria = [
    'active' => 1,
];
$this->seeNumRecords(2, 'users', $criteria);