Class autoload in PHPUnit using Composer and autoload.php

I just installed PHPUnit version 3.7.19 from Sebastian Bergman through Composer and wrote a class that I would like to unit test.

I would like all my classes to be automatically loaded into each unit test without , to use include or require at the top of my test, but it is complicated!

This is what my directory structure looks like (trailing / slash indicates a directory, not a file):

  • composer.json
  • composer.lock
  • composer.phar
  • Library /
    • returning.php
  • Tests /
    • returningTest.php
  • seller /
    • bin /
      • Phpunit
    • composer /
    • PHPUnit /
    • Symfony /
    • autoload.php

My composer.json file contains the following:

 "require": { "phpunit/phpunit": "3.7.*", "phpunit/phpunit-selenium": ">=1.2" } 

The return.php class file contains the following:

 <?php class Returning { public $var; function __construct(){ $this->var = 1; } } ?> 

My test file returnTest.php 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: Return class not found in /files/code/php/db/tests/returningTest.php on line 8

I noticed that composer created the autoload.php file in vendor/autoload.php , but I'm not sure if this is relevant for my problem.

Also, in some other answers on Qaru, people mentioned something about using PSR-0 in composer and the namespace command in PHP, but I have not had success in using one of them.

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: August 14, 2013

Now I have created an open source project called PHPUnit Skeleton to help you quickly and easily test PHPUnit for your project.

+59
php namespaces phpunit composer-php autoload
Mar 29 '13 at 19:46
source share
5 answers

Ok, first. You must tell the autoloader where to find the php file for the class. This is done following the PSR-0 standard.

The best way is to use namespaces. The autoloader searches for the Acme/Tests/ReturningTest.php file when the Acme\Tests\ReturningTest class is requested. There are some great namespace tutorials out there, just searching and reading. Please note that the namespace is not included in PHP for startup, this is what you can use for startup.

The composer comes with a standard PSR-0 autoloader (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/" } } } 

Additional information in the documentation .

Now the autoloader can find the classes you need so that PHPunit knows that before running the tests there should be a file: bootstrap file. You can use the --bootstrap option to indicate where the bootstrap file is located:

 $ ./vendor/bin/phpunit tests --bootstrap vendor/autoload.php 

However, it is better to use the PHPunit configuration file :

 <!-- /phpunit.xml.dist --> <?xml version="1.0" encoding="utf-8" ?> <phpunit bootstrap="./vendor/autoload.php"> <testsuites> <testsuite name="The project 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 in a different directory, you need to specify the path to this directory in the command with the -c option.

+71
Mar 29 '13 at 20:58
source share

[ Update2 ] Another simpler alternative approach is to use the autoload-dev directive in composer.json ( link ). The advantage is that you do not need to support two bootstrap.php (one for prod, one for dev) just to autoload different classes.

 { "autoload": { "psr-4": { "MyLibrary\\": "src/" } }, "autoload-dev": { "psr-4": { "MyLibrary\\Tests\\": "tests/" } } } 

[ Refresh ] Wouter J's answer is more complete. But mine can help people who want to configure PSR-0 startup in the tests/ folder.
Phpunit scans all files with this *Test.php template. Therefore, we do not need to download them ourselves. But we still want to autoload other helper classes in tests/ , such as fixture / stub or some parent classes.

An easy way is to see how the Composer project itself sets up the phpunit test. It is actually very simple. Pay attention to the line with "bootstrap".

link: https://github.com/composer/composer/blob/master/phpunit.xml.dist

 <?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" syntaxCheck="false" bootstrap="tests/bootstrap.php" > <testsuites> <testsuite name="Composer Test Suite"> <directory>./tests/Composer/</directory> </testsuite> </testsuites> <groups> <exclude> <group>slow</group> </exclude> </groups> <filter> <whitelist> <directory>./src/Composer/</directory> <exclude> <file>./src/Composer/Autoload/ClassLoader.php</file> </exclude> </whitelist> </filter> </phpunit> 

link: https://github.com/composer/composer/blob/master/tests/bootstrap.php

 <?php /* * This file is part of Composer. * * (c) Nils Adermann <naderman@naderman.de> * Jordi Boggiano <j.boggiano@seld.be> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ error_reporting(E_ALL); $loader = require __DIR__.'/../src/bootstrap.php'; $loader->add('Composer\Test', __DIR__); 

The last line above is the autoload of phpunit test classes in the Composer \ Test namespace.

+40
Mar 30 '13 at 7:28
source share

None of these answers were what I was looking for. Yes PHPUnit downloads test files, but not stubs / devices. Chaun Ma's answer doesn't shorten it, because running vendor/bin/phpunit already includes autoload, so there is no way to get an autoloader instance to direct more stacks to it.

I eventually found this in the docs:

If you need to find the same prefix in several directories, you can specify them as an array as such:

 { "autoload": { "psr-0": { "Monolog\\": ["src/", "lib/"] } } } 
+6
Sep 29 '13 at 15:42
source share

If you use PHPUnit 7, you can make your classes from src/ folder for automatic loading in tests as follows:

  1. Make sure your composer.json file looks something like this:

     { "autoload": { "classmap": [ "src/" ] }, "require-dev": { "phpunit/phpunit": "^7" } } 
  2. To apply the changes to the composer.json run command:

     composer install 
  3. Finally, you can run the tests in the tests/ folder:

     ./vendor/bin/phpunit tests/ 
0
Dec 04 '18 at 8:02
source share

There is a really easy way to configure phpunit with autoload and boot. Use the phpunit --generate-configuration parameter to create the --generate-configuration in a few seconds :

 vendor/bin/phpunit --generate-configuration 

(Or just phpunit --generate-configuration if phpunit is installed in your PATH). This option has been available since phpunit5.

This option will ask you for a bootstrap file ( vendor / autoload.php ), tests, and source directories. If your project is configured with the default composer settings (see the directory structure below), the default options will be available to you by default. Just press RETURN three times!

 project-dir -- src -- tests -- vendor 

You get phpunit.xml by default, which is good. Of course, you can edit to include any specializations (eg colors="true" ) that you require-:

 <?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.1/phpunit.xsd" bootstrap="vendor/autoload.php" executionOrder="depends,defects" forceCoversAnnotation="true" beStrictAboutCoversAnnotation="true" beStrictAboutOutputDuringTests="true" beStrictAboutTodoAnnotatedTests="true" verbose="true"> <testsuites> <testsuite name="default"> <directory suffix="Test.php">tests</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">src</directory> </whitelist> </filter> </phpunit> 
0
Apr 26 '19 at 13:46
source share



All Articles