有没有办法只为给定的 PHPUnit 测试加载特定的装置?
Is there a way to only load specific fixtures for a given PHPUnit test?
我们使用的是 Yii 1.1,但我怀疑这个问题适用于任何使用 PHPUnit 的人。
我们的一些单元测试依赖于数据库中的特定数据,因此我们使用了固定装置。不幸的是,您 define fixtures 是基于每个测试 class,而不是基于每个测试函数。
示例:
class AccountTest extends CDbTestCase
{
public $fixtures = array(
'users' => 'User',
'email_accounts' => 'EmailAccount',
'histories' => 'History',
'email_queue' => 'EmailQueue',
'org_unit' => 'OrgUnit',
);
// ...
public function testIsValid_preventsWhiteSpaceAroundNumber()
{
// ... (test logic)...
}
// ... (more tests)...
}
我们的帐户模型的一些测试需要更新几个不同的表以匹配定义的固定装置,但相同 class 的其他测试根本不依赖于任何固定装置。不幸的是,我们 AccountTest.php 文件(其中包含我们的帐户模型的测试)中的所有测试都增加了重新加载数据库中这五个表的固定装置的延迟。
作为一个具体的例子,Account->isValid()
函数现在有七个单元测试来确认关于它做什么或不认为有效的各种事情。我对 运行 进行了 testIsValid
单元测试,使用和不使用固定装置(这些测试不需要):使用固定装置花费 2.95 秒,不使用固定装置花费 0.068 秒。
我们已经尝试(试图解决不同的问题)创建两个不同的 AccountTest.php 文件(在不同的文件夹中)以将我们的单元测试分成不同的组,但这导致了比它更多的问题已解决。
我的最终目标是能够为特定测试定义是否需要加载任何数据库装置(如果需要,加载哪些)以便测试不需要不依赖固定装置可以 运行 快得多,没有等待数据库(不必要地)更新的延迟。
因此我的问题是:有没有办法只为给定的 PHPUnit 测试加载特定的固定装置?
这个怎么样?假设您的测试 class 扩展 \CDbTestCase ...
- 将 $fixtures 的名称更改为 $optionalFixtures
添加以下...
public function loadFixtures($fixtures=null)
{
if ($fixtures === null) {
$fixtures = $this->optionalFixtures;
}
if(is_array($fixtures))
$this->getFixtureManager()->load($fixtures);
$this->fixtures = $fixtures;
}
然后,在您想要加载夹具的所有测试中,添加对该方法的调用(使用可选数组)。没有该调用的测试应该以 运行 结束,而不会加载固定装置,尽管固定装置可能仍然存在于之前测试的数据库中。
你可以这样试试:
protected $fixtures = array();
/**
* @return array
*/
public function fixturesProvider()
{
return array(
array(
array(
'id' => 1,
)
),
);
}
/**
*@dataProvider fixturesProvider
*/
public function testMethodName($fixtures)
{
$x = $this->service->method($fixtures['id]);
$this->assertInternalType('type',$x);
}
你在那里模拟你的固定装置,我喜欢这个,我有几个不同的数据库,我使用 setUp() 函数通过路由获取服务,并使用其中的方法来获取带有自定义变量的对象。
但不知道它在这个框架中是如何工作的
我们使用的是 Yii 1.1,但我怀疑这个问题适用于任何使用 PHPUnit 的人。
我们的一些单元测试依赖于数据库中的特定数据,因此我们使用了固定装置。不幸的是,您 define fixtures 是基于每个测试 class,而不是基于每个测试函数。
示例:
class AccountTest extends CDbTestCase
{
public $fixtures = array(
'users' => 'User',
'email_accounts' => 'EmailAccount',
'histories' => 'History',
'email_queue' => 'EmailQueue',
'org_unit' => 'OrgUnit',
);
// ...
public function testIsValid_preventsWhiteSpaceAroundNumber()
{
// ... (test logic)...
}
// ... (more tests)...
}
我们的帐户模型的一些测试需要更新几个不同的表以匹配定义的固定装置,但相同 class 的其他测试根本不依赖于任何固定装置。不幸的是,我们 AccountTest.php 文件(其中包含我们的帐户模型的测试)中的所有测试都增加了重新加载数据库中这五个表的固定装置的延迟。
作为一个具体的例子,Account->isValid()
函数现在有七个单元测试来确认关于它做什么或不认为有效的各种事情。我对 运行 进行了 testIsValid
单元测试,使用和不使用固定装置(这些测试不需要):使用固定装置花费 2.95 秒,不使用固定装置花费 0.068 秒。
我们已经尝试(试图解决不同的问题)创建两个不同的 AccountTest.php 文件(在不同的文件夹中)以将我们的单元测试分成不同的组,但这导致了比它更多的问题已解决。
我的最终目标是能够为特定测试定义是否需要加载任何数据库装置(如果需要,加载哪些)以便测试不需要不依赖固定装置可以 运行 快得多,没有等待数据库(不必要地)更新的延迟。
因此我的问题是:有没有办法只为给定的 PHPUnit 测试加载特定的固定装置?
这个怎么样?假设您的测试 class 扩展 \CDbTestCase ...
- 将 $fixtures 的名称更改为 $optionalFixtures
添加以下...
public function loadFixtures($fixtures=null) { if ($fixtures === null) { $fixtures = $this->optionalFixtures; } if(is_array($fixtures)) $this->getFixtureManager()->load($fixtures); $this->fixtures = $fixtures; }
然后,在您想要加载夹具的所有测试中,添加对该方法的调用(使用可选数组)。没有该调用的测试应该以 运行 结束,而不会加载固定装置,尽管固定装置可能仍然存在于之前测试的数据库中。
你可以这样试试:
protected $fixtures = array();
/**
* @return array
*/
public function fixturesProvider()
{
return array(
array(
array(
'id' => 1,
)
),
);
}
/**
*@dataProvider fixturesProvider
*/
public function testMethodName($fixtures)
{
$x = $this->service->method($fixtures['id]);
$this->assertInternalType('type',$x);
}
你在那里模拟你的固定装置,我喜欢这个,我有几个不同的数据库,我使用 setUp() 函数通过路由获取服务,并使用其中的方法来获取带有自定义变量的对象。 但不知道它在这个框架中是如何工作的