Is there a way to only load specific fixtures for a given PHPUnit test?

We are using Yii 1.1, but I suspect this problem applies to anyone using PHPUnit.

Some of our unit tests depend on specific data in the database, which is why we use instrumentation. Unfortunately, you are defining fixtures for each test class, not each test function.

Example:

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

      

Some tests for our account model require several different tables to update according to certain parameters, but other tests for this same class do not depend on any instruments. Unfortunately, all the tests in our AccountTest.php file (which contains the tests for our account model) have an additional fixture reload delay for these five tables in the database.

As a concrete example, the function Account->isValid()

now has seven unit tests to confirm various things about what it does or does not consider valid. I checked the tests with the module testIsValid

with and without fixtures (for which these tests are not needed): with fixtures it took 2.95 seconds, without 0.068 seconds.

We have already tried (in an attempt to solve a different problem) to create two different AccountTest.php files (in different folders) to separate our unit tests into different groups, but this caused more problems than was resolved.

My ultimate goal is to determine, for a particular test, whether any loadable databases (and if so, which ones) need to be loaded so that the instrument-agnostic tests can run much faster, without delaying waiting for a database update (unnecessarily).

So my question is: Is there a way to load only specific fixtures for a given PHPUnit test?

+3


source to share


2 answers


How about this? Assuming your test class extends \ CDbTestCase ...

  • change the name of your $ fixtures to $ optionalFixtures
  • add the following ...

    public function loadFixtures($fixtures=null)
    {
        if ($fixtures === null) {
            $fixtures = $this->optionalFixtures;
        }
    
        if(is_array($fixtures))
            $this->getFixtureManager()->load($fixtures);
        $this->fixtures = $fixtures;
    }
    
          



Then in the whole test where you want the loaded fixtures to be loaded, add a call to this method (with an additional array). Testing without this call should complete without loading the fixtures, although in previous tests it might still be in the database.

+2


source


u can try this:

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

      



You mock where I have several different databases. I am using setUp () function to get Service by routing and use methods in it to take an object with custom variables. but don't know how it works in this structure

0


source







All Articles