DbUnit 中的夹具创建非常缓慢。每次使用 core2duo e8400 4gb kingston 1333 需要 1.5 秒。您可以使用 xdebug 找到瓶颈并修复它(如果可以),或者您可以执行以下操作之一:
1.)
您只能运行您当前使用自定义引导 xml 开发的测试文件:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://phpunit.de/phpunit.xsd"
backupGlobals="false"
verbose="true"
bootstrap="test/bootstrap.php">
<testsuites>
<testsuite>
<directory>test/integration</directory>
<exclude>test/integration/database/RoleDataTest.php</exclude>
</testsuite>
</testsuites>
<php>
<env name="APPLICATION_MODE" value="test"/>
</php>
</phpunit>
排除部分在这里很重要。您也可以使用测试组。
2.)
namespace test\integration;
abstract class AbstractTestCase extends \PHPUnit_Extensions_Database_TestCase
{
static protected $pdo;
static protected $connection;
/**
* @return \PHPUnit_Extensions_Database_DB_IDatabaseConnection
*/
public function getConnection()
{
if (!isset(static::$pdo)) {
static::$pdo = new \PDO('pgsql:host=localhost;port=5432;dbname=dobra_test', 'postgres', 'inflames', array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION));
static::$connection = $this->createDefaultDBConnection(static::$pdo);
}
return static::$connection;
}
/**
* @return \PHPUnit_Extensions_Database_Operation_DatabaseOperation
*/
static protected $fixtureSet = false;
protected function getSetUpOperation()
{
$c = get_class($this;
if (!$c::$fixtureSet) {
$c::$fixtureSet = true;
return \PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT(true);
}
return \PHPUnit_Extensions_Database_Operation_Factory::NONE();
}
static protected $dataSet;
/**
* @return \PHPUnit_Extensions_Database_DataSet_IDataSet
*/
public function getDataSet()
{
$c = get_class($this;
if (!isset($c::$dataSet)) {
$c::$dataSet = $this->createDataSet();
}
return $c::$dataSet;
}
/**
* @return \PHPUnit_Extensions_Database_DataSet_IDataSet
*/
abstract protected function createDataSet();
protected function dataSetToRows($tableName, array $ids)
{
$transformer = new DataSetRowsTransformer($this->getDataSet());
$transformer->findRowsByIds($tableName, $ids);
$transformer->cutColumnPrefix();
return $transformer->getRows();
}
}
您可以覆盖 TestCase。在此示例中,每个测试用例仅使用一个 pdo 连接(您可以使用依赖注入将其注入代码),通过覆盖设置操作,您可以为每个测试用例仅设置一次夹具或为每个测试仅设置一次(取决于self::
或$cls = get_class($this); $cls::
)。@depend
(PHPUnit 的设计很糟糕,它会在每次测试调用时创建新实例,因此您必须使用类名来存储每个实例或每个类的变量。)在这种情况下,您必须编写测试以通过注释相互依赖。例如,您可以删除在上一个测试中创建的同一行。
通过这个测试代码1.5 secs
而不是6 x 1.5 = 9 secs
:
namespace test\integration\database;
use Authorization\PermissionData;
use test\integration\AbstractTestCase;
use test\integration\ArrayDataSet;
class PermissionDataTest extends AbstractTestCase
{
static protected $fixtureSet = false;
static protected $dataSet;
/** @var PermissionData */
protected $permissionData;
/**
* @return \PHPUnit_Extensions_Database_DataSet_IDataSet
*/
public function createDataSet()
{
return new ArrayDataSet(array(
'permission' => array(
array('permission_id' => '1', 'permission_method' => 'GET', 'permission_resource' => '^/$'),
array('permission_id' => '2', 'permission_method' => 'POST', 'permission_resource' => '^/$'),
array('permission_id' => '3', 'permission_method' => 'DELETE', 'permission_resource' => '^/$')
),
'user' => array(
array('user_id' => '1', 'user_name' => 'Jánszky László', 'user_email' => 'a@b.d', 'user_salt' => '12435')
),
'user_permission' => array(
array('user_permission_id' => '1', 'user_id' => '1', 'permission_id' => '1'),
array('user_permission_id' => '2', 'user_id' => '1', 'permission_id' => '2')
),
'role' => array(
array('role_id' => '1', 'role_name' => 'admin')
),
'role_permission' => array(
array('role_permission_id' => '1', 'role_id' => '1', 'permission_id' => '1')
),
'permission_cache' => array(
array('permission_cache_id' => '1', 'user_id' => '1', 'permission_id' => '1'),
array('permission_cache_id' => '2', 'user_id' => '1', 'permission_id' => '2'),
)
));
}
public function testReadAllShouldReturnEveryRow()
{
$this->assertEquals($this->permissionData->readAll(), $this->dataSetToRows('permission', array(3, 2, 1)));
}
/** @depends testReadAllShouldReturnEveryRow */
public function testReadAllByRoleIdShouldReturnEveryRowRelatedToRoleId()
{
$this->assertEquals($this->permissionData->readAllByRoleId(1), $this->dataSetToRows('permission', array(1)));
}
/** @depends testReadAllByRoleIdShouldReturnEveryRowRelatedToRoleId */
public function testReadAllByUserIdShouldReturnEveryRowRelatedToUserId()
{
$this->assertEquals($this->permissionData->readAllByUserId(1), $this->dataSetToRows('permission', array(2, 1)));
}
/** @depends testReadAllByUserIdShouldReturnEveryRowRelatedToUserId */
public function testCreateShouldAddNewRow()
{
$method = 'PUT';
$resource = '^/$';
$createdRow = $this->permissionData->create($method, $resource);
$this->assertTrue($createdRow['id'] > 0);
$this->assertEquals($this->getDataSet()->getTable('permission')->getRowCount() + 1, $this->getConnection()->getRowCount('permission'));
return $createdRow;
}
/** @depends testCreateShouldAddNewRow */
public function testDeleteShouldRemoveRow(array $createdRow)
{
$this->permissionData->delete($createdRow['id']);
$this->assertEquals($this->getDataSet()->getTable('permission')->getRowCount(), $this->getConnection()->getRowCount('permission'));
}
/** @depends testDeleteShouldRemoveRow */
public function testDeleteShouldRemoveRowAndRelations()
{
$this->permissionData->delete(1);
$this->assertEquals($this->getDataSet()->getTable('permission')->getRowCount() - 1, $this->getConnection()->getRowCount('permission'));
$this->assertEquals($this->getDataSet()->getTable('user_permission')->getRowCount() - 1, $this->getConnection()->getRowCount('user_permission'));
$this->assertEquals($this->getDataSet()->getTable('role_permission')->getRowCount() - 1, $this->getConnection()->getRowCount('role_permission'));
$this->assertEquals($this->getDataSet()->getTable('permission_cache')->getRowCount() - 1, $this->getConnection()->getRowCount('permission_cache'));
}
public function setUp()
{
parent::setUp();
$this->permissionData = new PermissionData($this->getConnection()->getConnection());
}
}
3.)
另一种解决方案是每个项目只创建一次夹具,然后在事务中使用每个测试并在每次测试后回滚。(如果您有需要提交以检查约束的 pgsql 延迟代码,这将不起作用。)