1

我有一个测试数据模型的测试:

<?php
namespace Tests\Model\SQL;

/**
 * @group Model_Users
 * @group Model
 */
class UsersTest extends TestCase {

/** @var Users */
private $model;

public function setUp() {
    parent::setUp();
    $this->connection->execute( file_get_contents(
        __DIR__ . '/fixtures/countries.sql' ) );
    $this->model = new \Users(
        $this->connection
    );
}

    public function testUserExists() {
            $exists = $this->model->userExists( 'johndoe' );
            $this->assertTrue( $exists );
    }

}

使用SQLiteTests\Model\SQL\TestCase作为数据库以尽可能快地保持测试。无论如何,正如您所料,SQLite 与Postgres不是同一个数据库,因此可能有一些特殊的数据库,它们在 SQLite 上会失败并在 PostgreSQL 上传递,反之亦然。

我的问题是

如何有效地(在牢记 DRY 的情况下)设计架构以仅使用 SQLite 运行测试,然后仅使用 Postgres。

当我说DRY时,我的意思是理想情况下,当我只为一个模型编写一个测试用例并且我的测试架构会处理这个问题时,我将能够像这样运行测试:

php tests/run.php --group=MockedDbWithSqlite # fast way, prefered, default

php tests/run.php --group=RealDb # slower way, but with more precise results
4

2 回答 2

1

因此,从评论来看,这个问题与任何具体的存储问题无关,更多的是关于如何将自定义参数传递给 PHPUnit

因为,使用此参数,您将关闭数据库驱动程序。

有几个选项可以做到这一点,但没有官方支持的“自定义参数”对象或其他东西。即便如此,如果有人能添加这个可能会很好:)

我的建议是使用以下选项之一:

环境变量

使测试/引导代码依赖于$_ENV变量。

$dbDriverFactory->getInstanceFor(getenv('DB'));

并使用以下方法之一

export DB=postgress
phpunit

或者

DB=postpress; phpunit;

或使用 phpunits xml 配置来设置环境或任何你喜欢的。

通过这样做,您可以提供两个 xml 配置phpunit-sqlite.xml&phpunit-pg.xml并运行:

phpunit -c phpunit-sqlite.xml

它不必环境。文档部分中列出的任何方法Setting PHP INI settings, Constants and Global Variables都可以使用。

“自定义”cli 参数

像这样调用 phpunit:

phpunit --colors --usePostgres

并在测试用例或引导代码中添加类似的内容:

if (in_array('--usePostgress', $_SERVER['argv'], true) {
    $db = $this->setupPG();
} else {
    $db = $this->setupSqlite();
}
于 2012-10-03T20:26:24.327 回答
0

我对edorian的阅读方式不同。我喜欢对这种事情使用继承。优点是您可以在同一个测试运行中同时运行 SQLite 和 Postgres 测试。缺点是您必须向要使用两个数据库运行的每个测试文件添加一些代码。您必须对每个要测试的新数据库重复此操作。下面是它的工作原理:

class UsersTestBase extends TestCase {
    //Unchanged
}

class UsersTestSQLite extends UsersTestBase{}

class UsersTestPostgres extends UsersTestBase {
    function __construct(){
        parent::_construct("postgres");
    }
}

因此,UsersTest 完全相同,只是名称已更改为附加“Base”。然后你有一个派生的 UsersTestSQLite 类。这无济于事。在这一点上,我们没有得到或失去任何东西。

然后我们有了UsersTestPostgres。这以某种方式告诉对象使用 postgres 而不是 sqlite。在这种情况下,我假设 TestCase 有一个构造函数,可以将数据库用作可选参数(默认为“sqlite”)。显然有很多替代方案,但我希望你能看到总体思路。

最后,您需要将合适的@group标签添加到派生类中,以便您控制它们何时运行。

于 2012-10-15T02:34:42.153 回答