Autoloading classes in PHPUnit using Composer and autoload.php
autoload, composer-php, namespaces, php, phpunit
Solution
Well, at first. You need to tell the autoloader where to find the php file for a class. That's done by following the PSR-0 standard.
The best way is to use namespaces. The autoloader searches for a `Acme/Tests/ReturningTest.php` file when you requested a `Acme\Tests\ReturningTest` class. There are some great namespace tutorials out there, just search and read. Please note that namespacing is not something that came into PHP for autoloading, it's something that can be used for autoloading.
Composer comes with a standard PSR-0 autoloader (the one in `vendor/autoload.php`). In your case you want to tell the autoloader to search for files in the `lib` directory. Then when you use `ReturningTest` it will look for `/lib/ReturningTest.php`.
Add this to your `composer.json`:
{
...
"autoload": {
"psr-0": { "": "lib/" }
}
}
More information in the documentation.
Now the autoloader can find your classes you need to let PHPunit know there is a file to execute before running the tests: a bootstrap file. You can use the `--bootstrap` option to specify where the bootstrap file is located:
$ ./vendor/bin/phpunit tests --bootstrap vendor/autoload.php
However, it's nicer to use a PHPunit configuration file:
<!-- /phpunit.xml.dist -->
<?xml version="1.0" encoding="utf-8" ?>
<phpunit bootstrap="./vendor/autoload.php">
<testsuites>
<testsuite name="The project's test suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
Now, you can run the command and it will automatically detect the configuration file:
$ ./vendor/bin/phpunit
If you put the configuration file into another directory, you need to put the path to that directory in the command with the `-c` option.
Problem
I have just installed PHPUnit version 3.7.19 by Sebastian Bergmann via Composer and have written a class I would like to unit test. I would like to have all my classes autoloaded into each unit test without having to use `include` or `require` at the top of my test but this is proving to be difficult! This is what my directory structure looks like (a trailing / slash indicates a directory, not a file): ``` * composer.json * composer.lock * composer.phar * lib/ * returning.php * tests/ * returningTest.php * vendor/ * bin/ * phpunit * composer/ * phpunit/ * symfony/ * autoload.php ``` My composer.json file includes the following: ``` "require": { "phpunit/phpunit": "3.7.*", "phpunit/phpunit-selenium": ">=1.2" } ``` My returning.php class file includes the following: ``` <?php class Returning { public $var; function __construct(){ $this->var = 1; } } ?> ``` My returningTest.php test file includes the following: ``` <?php class ReturningTest extends PHPUnit_Framework_TestCase { protected $obj = null; protected function setUp() { $this->obj = new Returning; } public function testExample() { $this->assertEquals(1, $this->obj->var); } protected function tearDown() { } } ?> ``` However, when I run `./vendor/bin/phpunit tests` from the command-line, I get the following error: PHP Fatal error: Class 'Returning' not found in /files/code/php/db/tests/returningTest.php on line 8 I noticed that `composer` produced an `autoload.php` file in `vendor/autoload.php` but not sure if this is relevant for my problem. Also, in some other answers on Stack Overflow people have mentioned something about using PSR-0 in composer and the `namespace` command in PHP, but I have not been successful in using either one. Please help! I just want to autoload my classes in PHPUnit so I can just use them to create objects without worrying about `include` or `require`. Update: 14th of August 2013 I have now created an Open Source project called PHPUnit Skeleton to help you get up and running with PHPUnit testing easily for your project.