Создания арматуры в DbUnit крайне медленно. Он занимает 1,5 сек каждый раз с Core2Duo E8400 4gb Кингстоне 1333. Вы можете найти узкое место с 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::
). (PHPUnit имеет плохую конструкцию, он создает новый экземпляр каждым тестовым вызовом, поэтому вам нужно взломать имена классов для хранения переменных для каждого экземпляра или для каждого класса.) В этом сценарии вам нужно написать тесты, зависящие от eachother, с аннотацией @depend
, Например, вы можете удалить ту же строку, которую вы создали в предыдущем тесте.
К этому тестовый код 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' => '[email protected]', '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, который требует фиксации для проверки ограничений.)
Вам нужно метрику, где есть узкое место. Вероятно, это ускорит ваши потребности, если вы сможете издеваться над всей базой данных, поэтому вам вообще не нужно запускать dbunit. Тест должен проходить под 10-й секундой, что на самом деле значительно медленнее для теста. – hakre
Поскольку вы не упомянули, используете ли вы оборудование и как можно больше? – Pradeep
Я использую светильники и разделяю как можно более разумно. Есть ли способ профилировать тестового бегуна? –