Search code examples
phpphpunitautoload

PHPUnit can't find test class if it is auto/manually loaded in bootstrap


I've come across an unusual class loading problem in PHPUnit, initially experienced with 4.3.5 and now latest 4.4.2 as well (latest stable).

I have a bootstrap file which is loaded via a phpunit.xml automatically, which includes Composer's default autoloader and also my own autoloader. This works fine as it is. However, I discover that if I load a test class in the bootstrap, then PHPUnit isn't able to resolve the class name correctly, and it thus does not load.

I get this error:

Class 'test/unit/tests/UpdateAllTest' could not be found in '/full/project/path/webapp/test/unit/tests/UpdateAllTest.php'.

(My purpose in wanting to refer to a test class in the bootstrap is to add a database build method in each one, keeping it with the test file it pertains to. I plan to do this in the bootstrap rather than a setUp() method, as I want it to run once across all tests, not once per test method).

I've done a bit of light debugging inside PHPUnit itself (in particular PHPUnit_Runner_StandardTestSuiteLoader::load) and found the class name is incorrectly supplied as a path and not as a namespaced class name. Here is the relevant clause:

    if (class_exists($suiteClassName, false)) {
        $class = new ReflectionClass($suiteClassName);

        if ($class->getFileName() == realpath($suiteClassFile)) {
            return $class;
        }
    }

The value of $suiteClassName is test/unit/tests/UpdateAllTest, which is plainly not a namespaced anything - it should be Awooga\Testing\Unit\UpdateAllTest, something that is normally handled by a custom mapping in my autoloader.

I don't think I am doing anything particularly unusual with PHPUnit, and so find it unlikely that this is a bug that no-one else has thus far experienced. In these circumstances, do I maybe need to declare the class namespaces in the phpunit.xml or something unusual like that? Grasping at straws here!

What might be the cause of this seemingly trivial problem? In the meantime I will just move these set-up methods to a different file/class - not ideal but not the end of the world either. I'm on PHP 5.5.x and Ubuntu 12.04.


Solution

  • I haven't fixed this, but my build methods are now so long that it makes sense for them to appear in different classes anyway. I have a naming convention so that a test of *Test.php has a corresponding build class of *Build.php.

    I use PHPUnit's bootstrap system to scan for build classes and to call a static build() within automatically.