2011-12-24

PHPUnit Taking Forever to Run

I was tasked to create some PHPUnit tests for a project at work, but I was having an issue running the tests because they were taking forever to load, even if it was just a single small little test that just asserted a true statement. So, I went googling for some kind of result and found this mail archive discussed in the ZendFramework mail archive.


Basically, you just want to check your phpunit.xml file and ensure you only whitelist the files and directories you want to be tested. Don't include excludes unless they are included in your whitelist.


To put example to words, let's assume you have a phpunit.xml similar to this:


<phpunit bootstrap="./tests/bootstrap.php"
         backupGlobals="false"
         backupStaticAttributes="false"
         syntaxCheck="false"
         colors="false">

    <testsuites>
        <testsuite name="MyTest-Application">
            <directory suffix=".php">tests/application/</directory>
        </testsuite>
    </testsuites>

    <filter>
        <blacklist>
            <directory suffix=".php">tests/</directory>
            <directory suffix=".php">build/</directory>
            <directory suffix=".php">htdocs/</directory>
            <directory suffix=".php">library/Doctrine</directory>
            <directory suffix=".php">library/Zend</directory>
            <directory suffix=".php">logs/</directory>
            <directory suffix=".php">scripts/</directory>
            <file suffix=".php">application/controllers/ExampleController.php</file>
        </blacklist>
        <whitelist>
            <directory suffix=".php">application/</directory>
            <exclude>
                <directory suffix=".php">application/models/</directory>
                <directory>application/configs/</directory>
                <file suffix=".php">application/setup.php</file>
                <file suffix=".php">application/Bootstrap.php</file>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

Note that this would be in the root of your project, right? You are referring to the tests/ directory as that contains the bulk of your tests, right? However, you are also telling phpunit to parse and search your entire application for any tests. This is a bad practice IMO, because 1) the parser now must parse ALL of your code instead of just the necessary pieces for things containing tests, 2) it can consume a lot of resources in this parsing process, and 3) It's very rare that you will find real PHPUnit tests within the main part of the application. PHPUnit tests are commonly found outside of the application and in their own directory.


The above phpunit.xml file should be corrected to reflect something like the following:


<phpunit bootstrap="./tests/bootstrap.php"
         backupGlobals="false"
         backupStaticAttributes="false"
         syntaxCheck="false"
         colors="false">

    <testsuites>
        <testsuite name="My-Application">
            <directory suffix=".php">tests/application/</directory>
        </testsuite>
    </testsuites>

    <filter>
     <whitelist>
      <directory suffix=".php">./tests/</directory>
      <exclude>
       <file>./tests/bootstrap.php</file>
      </exclude>
     </whitelist>
    </filter>
</phpunit>

Note how the whitelist directory has been changed to just point to the tests directory and only search for files with the suffix .php.


If your project is currently under subversion control, then it is likely the first configuration for phpunit.xml would cause PHPUnit to search for ALL files in ALL directories, and that includes the .svn directories in every single subdirectory of your project. This means, the first configuration would not only cause PHPUnit to search your entire project for PHPUnit test files, but also every .svn directory beneath it, thus increasing the amount of time required to parse and execute the test. So, if run time for your PHPUnit tests are taking 50+seconds to run one measly test, try taking a look at your phpunit.xml file and make sure you are whitelisting only the files you need to include in the test. Do not blacklist directories or files unless they are already apart of your whitelist and you need them excluded. This should increase the run-time of your PHPUnit scripts by a tremendous amount!


 


Enjoy,
-Kizano

No comments:

Post a Comment