【问题标题】:Is there a way to only load specific fixtures for a given PHPUnit test?有没有办法只为给定的 PHPUnit 测试加载特定的夹具?
【发布时间】:2015-10-02 05:59:01
【问题描述】:

我们使用的是 Yii 1.1,但我怀疑这个问题适用于任何使用 PHPUnit 的人。

我们的一些单元测试依赖于数据库中的特定数据,因此我们使用了夹具。不幸的是,您define fixtures 是基于每个测试类,而不是基于每个测试功能。

例子:

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)...
}

我们的 Account 模型的一些测试需要更新几个不同的表以匹配定义的固定装置,但同一类的其他测试根本不依赖任何固定装置。不幸的是,我们 AccountTest.php 文件中的所有测试(其中包含对我们的 Account 模型的测试)都增加了重新加载数据库中这五个表的固定装置的延迟。

作为一个具体的例子,Account->isValid() 函数现在有七个单元测试来确认关于它做什么或不认为有效的各种事情。我对使用和不使用固定装置(这些测试不需要)运行testIsValid 单元测试进行了测试:使用固定装置需要 2.95 秒,没有需要 0.068 秒。

我们已经尝试(试图解决不同的问题)创建两个不同的 AccountTest.php 文件(在不同的文件夹中)以将我们的单元测试分成不同的组,但这导致的问题多于解决的问题。

我的最终目标是能够为特定测试定义它是否需要加载任何数据库夹具(如果需要,哪些),以便不依赖夹具的测试可以运行速度更快,无需等待(不必要地)更新数据库。

所以我的问题是:有没有办法只为给定的 PHPUnit 测试加载特定的夹具?

【问题讨论】:

    标签: php unit-testing yii phpunit fixtures


    【解决方案1】:

    这个怎么样?假设您的测试类扩展了 \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;
      }
      

    然后,在您希望加载(这些)固定装置的所有测试中,添加对该方法的调用(使用可选数组)。没有该调用的测试最终应该在没有加载固定装置的情况下运行,尽管固定装置可能仍然在先前测试的数据库中。

    【讨论】:

    • 这成功了。我最终创建了一个 \OptionalFixturesDbTestCase 类来保存新的 loadFixtures 函数(我扩展了一些函数并将在多个测试类中重用)并将我的测试类设置为子类而不是子类 \CDbTestCase。
    【解决方案2】:

    你可以这样试试:

     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() 函数通过路由获取服务,并使用其中的方法获取带有自定义变量的对象。 但不知道它在这个框架中是如何工作的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      相关资源
      最近更新 更多