Asked  7 Months ago    Answers:  5   Viewed   34 times

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.

 Answers

17

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 AcmeTestsReturningTest 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.

Wednesday, March 31, 2021
 
codingb
answered 7 Months ago
99

You can just require the composer autoloader. The only feature it lacks is the ApcClassLoader which speeds things up with APC but introduces some complexity (you have to clear the cache when deploying). Using composer's -o flag (when installing or running dump-autoload) will give you a classmap one which is more or less equivalent to APC in terms of speed but without the complexity.

Wednesday, March 31, 2021
 
Teno
answered 7 Months ago
51

Classes/Contact/Contact.php and the composer rule "Classes\": "includes/libraries/Classes/" imply ClassesContactContact class, not ClassesContact.

So if you actually want ClassesContact class, move the Classes/Contact/Contact.php file up to the parent directory: Classes/Contact.php.

If, however, the desired namespace path to the class is ClassesContactContact, then change the use:

use ClassesContactContact;

And the namespace:

namespace ClassesContact;

class Contact {}

Example

??? composer.json
??? includes
?   ??? libraries
?       ??? Classes
?           ??? Contact
?               ??? Contact.php
??? test.php
??? vendor
    ??? autoload.php
    ??? composer
        ??? autoload_classmap.php
        ??? autoload_namespaces.php
        ??? autoload_psr4.php
        ??? autoload_real.php
        ??? autoload_static.php
        ??? ClassLoader.php
        ??? installed.json
        ??? LICENSE

The files under vendor/ are generated by composer.

composer.json

{
    "name": "testpsr4",
    "autoload": {
        "psr-4": {
            "Classes\": "includes/libraries/Classes"
        }
    }
}

test.php

<?php
require_once __DIR__ . '/vendor/autoload.php';

use ClassesContactContact;

$c = new Contact;
$c->test();

includes/libraries/Classes/Contact/Contact.php

<?php
namespace ClassesContact;

class Contact {
    public function test () {
        echo __METHOD__, PHP_EOL;
    }
}

Testing

composer update
php test.php

Output

ClassesContactContact::test
Saturday, May 29, 2021
 
lena
answered 5 Months ago
71

You can configure composer to use key files to access private repository.

More info: https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md#security

Saturday, July 31, 2021
 
irom
answered 3 Months ago
40

I see two possible mistakes you may have done that would cause this:

  • You forgot to update your satis repo so the autoload config for lxp/init is not up to date in there
  • You are running composer install from a lock file, and that means composer just reads the info from the composer.lock file and does not update package metadata to the latest version available in satis. To solve this you should run composer update instead.
Friday, August 13, 2021
 
Freddie
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :