Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autoloading classes in PHPUnit using Composer and autoload.php

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.

like image 619
Jasdeep Khalsa Avatar asked Mar 29 '13 19:03

Jasdeep Khalsa


People also ask

How autoload PHP class the composer way?

After you create the composer. json file in your project root with the above contents, you just need to run the composer dump-autoload command to create the necessary autoloader files. These will be created under the vendor directory. Finally, you need to include the require 'vendor/autoload.

What is autoloading classes in PHP?

The spl_autoload_register() function registers any number of autoloaders, enabling for classes and interfaces to be automatically loaded if they are currently not defined. By registering autoloaders, PHP is given a last chance to load the class or interface before it fails with an error.

What does composer dump-autoload do?

Composer dump-autoload: The composer dump-autoload will not download any new thing, all it does is looking for all the classes and files it needs to include again.

What is autoloading classes in laravel?

Auto-Loading allows you to load class files when they are needed without explicitly loading or including them. This gives you ease in running your application by loading those files automatically which are needed every time. Laravel is built to work with Composer.

How do I autoload a PHP file in composer?

Run the composer dump-autoload command to generate the necessary files that Composer will use for autoloading. Include the require 'vendor/autoload.php' statement at the top of the file where you want to use autoloading. Autoloading: The files Directive

Does PHPUnit require composer's autoloader class?

Note that even though vendor\bin\phpunit already require composer's autoloader class, it doesn't stop you require it again and get a $loader object to add new classes. There is a really simple way to set up phpunit with autoloading and bootstap.

How to autoload a class in PHP?

However, PHP's autoloading feature doesn't need such explicit inclusion. Instead, when a class is used (for declaring its object etc.) PHP parser loads it automatically, if it is registered with spl_autoload_register () function. Any number of classes can thus be registered.

Which file is used for autoloading libraries for PHP project?

This file is used for autoloading libraries for the PHP project. Go back to the composer.json file, the following code will show up in the file: phpro/grumphp is the library used for the PHP project.


1 Answers

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.

like image 123
Wouter J Avatar answered Sep 20 '22 05:09

Wouter J