Reputation: 6383
I have the following structure within my project:
/
/app
/app/models/ --UserTable.php
/lib
/lib/framework
/lib/framework/Models
/lib/framework/Db
/tests -- phpunit.xml, bootstrap.php
/tests/app
/tests/app/models --UserTableTest.php
With the app and lib directories I have various classes that work together to run my app. To setup my tests I have create a /tests/phpunit.xml file and a /tests/bootstrap.php
phpunit.xml
<phpunit bootstrap="bootstrap.php">
</phpunit>
bootstrap.php
<?php
function class_auto_loader($className)
{
$parts = explode('\\', $className);
$path = '/var/www/phpdev/' . implode('/', $parts) . '.php';
require_once $path;
}
spl_autoload_register('class_auto_loader');
So I have the following test:
<?php
class UserTableTest extends PHPUnit_Framework_TestCase
{
protected $_userTable;
public function setup()
{
$this->_userTable = new app\models\UserTable;
}
public function testFindRowByPrimaryKey()
{
$user = $this->_userTable->find(1);
$this->assertEquals($user->id, 1);
}
}
But it can't find the class when I run the test - PHP Fatal error: Class 'app\models\UserTable' not found in /var/www/phpdev/tests/app/models/UserTableTest.php on line 13
What am I doing wrong? I'm trying to understand PHPUnit configuration better so I opted to write the configuration and bootstrap file myself.
Upvotes: 24
Views: 34732
Reputation: 1003
You probably should use composer to organize your code, for example, the composer.json in your project root directory should contains something like:
...
"autoload": {
"psr-0": {
"PRJ_NAME\\APP\\": "app/",
"PRJ_NAME\\LIB\\": "lib/"
}
},
...
Then after run composer update, the two namespaces defined above are put into the vendor/composer/autoload_namespaces.php. Next is simple, just run phpunit with the autoload option like this:
phpunit --bootstrap vendor/autoload.php tests/app/models/UserTableTest
Make sure change the usage of your namespace in both your source code and test code.
Upvotes: 5
Reputation: 2014
If you are using composer autoload
change
<phpunit colors="true" strict="true" bootstrap="vendor/autoload.php">
to
<phpunit colors="true" strict="true" bootstrap="tests/autoload.php">
and in tests
directory create new autoload.php
with following content
include_once __DIR__.'/../vendor/autoload.php';
$classLoader = new \Composer\Autoload\ClassLoader();
$classLoader->addPsr4("Your\\Test\\Namespace\\Here\\", __DIR__, true);
$classLoader->register();
Upvotes: 35
Reputation: 3454
In my loader (very close to yours) I check if the first exploded part of the class name is my vendor, if it isn't the loader just return doing nothing (else had issues with phpunit's loader, since I'm a newbie of phpunit and don't know if this is the expected behavior nor if phpunit suggest or provide a loader ready to use).
I keep phpunit.xml
in the same directory of tests/
(not within) and once configured <directory>tests</directory>
I just run phpunit
on command line without configuration or directory options.
Upvotes: 1
Reputation: 772
If you load you classess with the same bootstrap in app you should be able to load them in tests. If you are running test by cd into your test directory just add to your phpunit.xml:
<testsuite name="My Application Tests">
<directory>./</directory>
</testsuite>
Inside <phpunit></phpunit>
Upvotes: 1