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.
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.
[Update2] Another simpler alternative approach is to use the autoload-dev directive in composer.json (reference). The benefit is that you don't need to maintain two bootstrap.php (one for prod, one for dev) just in order to autoload different classes.
{
"autoload": {
"psr-4": { "MyLibrary\\": "src/" }
},
"autoload-dev": {
"psr-4": { "MyLibrary\\Tests\\": "tests/" }
}
}
[Update] Wouter J's answer is more complete. But mine can help people who want to set up PSR-0 autoloading in tests/ folder.
Phpunit scans all files with this pattern *Test.php. So we don't need to autoload them ourselves. But we still want to autoload other supporting classes under tests/ such as fixture/stub or some parent classes.
An easy way is to look at how Composer project itself is setting up the phpunit test. It's actually very simple. Note the line with "bootstrap".
reference: 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>
reference: 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 autoloading phpunit test classes under the namespace Composer\Test.
None of these answers were what I was looking for. Yes PHPUnit loads test files, but not stubs/fixtures. Chaun Ma's answer doesn't cut it because running vendor/bin/phpunit already includes the autoload, so there's no way to get an instance of the autoloader to push more paths to it's stack at that point.
I eventually found this in the docs:
If you need to search for a same prefix in multiple directories, you
can specify them as an array as such:
{
"autoload": {
"psr-0": { "Monolog\\": ["src/", "lib/"] }
}
}
There is a really simple way to set up phpunit with autoloading and bootstap. Use phpunit's --generate-configuration option to create your phpunit.xml configuration in a few seconds-:
vendor/bin/phpunit --generate-configuration
(Or just phpunit --generate-configuration if phpunit is set in your PATH). This option has been available from version phpunit5 and upwards.
This option will prompt you for your bootstrap file (vendor/autoload.php), tests and source directories. If your project is setup with composer defaults (see below directory structure) the default options will be all you need. Just hit RETURN three times!
project-dir
-- src
-- tests
-- vendor
You get a default phpunit.xml which is good to go. You can of course edit to include any specialisms (e.g. colors="true") 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>
If you are using PHPUnit 7 you can make your classes from src/ folder to autoload in tests like this:
Ensure that your composer.json file looks similar to this:
{
"autoload": {
"classmap": [
"src/"
]
},
"require-dev": {
"phpunit/phpunit": "^7"
}
}
To apply changes in composer.json run command:
composer install
Finally you can run tests in tests/ folder:
./vendor/bin/phpunit tests/
I created fresh Symfony 4.1.x project, but when I'm trying to create and execute functional test I am getting error:
PHP Fatal error: Class
'Symfony\Bundle\FrameworkBundle\Test\WebTestCase' not found in
/home/tomasz/my_project/tests/ExampleControllerTest.php on line 7
Steps to reproduce:
Create project
composer create-project symfony/skeleton my_project
Install phpunit, functional tests components and maker for generating skeleton of functional test
composer req --dev symfony/phpunit-bridge symfony/css-selector symfony/browser-kit symfony/maker-bundle
Create example functional test
bin/console make:functional-test ExampleControllerTest
Content of created file:
<?php
namespace App\Tests;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class ExampleControllerTest extends WebTestCase
{
public function testSomething()
{
$client = static::createClient();
$crawler = $client->request('GET', '/');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$this->assertContains('Hello World', $crawler->filter('h1')->text());
}
}
Run tests
bin/phpunit
Output (after installing phpunit dependencies):
PHP Fatal error: Class
'Symfony\Bundle\FrameworkBundle\Test\WebTestCase' not found in
/home/tomasz/my_project/tests/ExampleControllerTest.php on line 7
I checked and class Symfony\Bundle\FrameworkBundle\Test\WebTestCase does exist in vendor/. Any clues?
phpunit.xml.dist
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.5/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
>
<php>
<ini name="error_reporting" value="-1" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
</whitelist>
</filter>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
</phpunit>
I am trying to execute some test in PHPUnits but it's not getting executed.
<?php
use \PHPUnit\Framework\TestCase;
class UserControllerTest extends TestCase {
public function testThatCanGetNumber() {
$mock = $this->getMockBuilder('UserModel')
->setMethods(array('getNumber'))
->getMock();
$mock->expects($this->once())
->method('getNumber')
->with($this->equalTo(5));
}
}
However, if I extend the class with \PHPUnit_Framework_TestCase it gets executed. Why is that?
This is my phpunit.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
stopOnFailure="false">
<testsuites>
<testsuite name="Test suite">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
You expect that the method is getting called but you are not executing anything in the test. You should call the method where the mocked method is called.
I have set up the PHPunit Framework for testing and upon running a simple test I am getting a TypeError below:
SampleTest::testTrueAssertsToTrue
TypeError: Argument 3 passed to
SebastianBergmann\GlobalState\Snapshot::__construct() must be of the type boolean, null given, called in /usr/share/php/PHPUnit/Framework/TestCase.php on line 2412
My test case is below:
class SampleTest extends \PHPUnit_Framework_TestCase
{
public function testTrueAssertsToTrue()
{
$this->assertTrue(true);
}
}
The PHPunit version is ^6.2 and below is the configuration XML file:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
stopOnFailure="false">
<testsuites>
<testsuite name ="Test suite">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
Please help I have searched online whole day and I cant find a solution.
Because you're using phpunit 6.2, \PHPUnit_Framework_TestCase has been removed and you should be instead extending the namespaced PHPUnit\Framework\TestCase
<?php
use PHPUnit\Framework\TestCase;
class SampleTest extends TestCase
{
public function testTrueAssertsToTrue()
{
$this->assertTrue(true);
}
}
You can verify the successful build here on travis-ci:
https://travis-ci.org/scratchers/phpunit6truetest/builds/242989226
My phpunit xml:
<phpunit bootstrap="bootstrap.php">
<testsuites>
<testsuite name="Phase Unit Tests">
<directory>./Phase</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">Api/app/library</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="build/report" charset="UTF-8"
highlight="false" lowUpperBound="35" highLowerBound="70"/>
<log type="testdox-html" target="build/testdox.html"/>
</logging>
</phpunit>
My test run successfully and I am not getting errors. I have checked for any DIE() and EXIT calls and did not find any in my code. When I look at my report it is just the empty folders with no files being scanned.
I am using PHP_CodeCoverage 1.2.7 using PHP 5.4.3 and PHPUnit 3.7.13 on Windows 8 with Wamp server 2.2
Ok so I wrote a small thing to test PHPUnit coverage reporting... Below is my classes:
/**
* test
*/
class Application
{
public $testprop;
function __construct()
{
$this->testprop = "Stuff";
}
}
/**
* Tests for the application class
*/
class ApplicationTest extends PHPUnit_Framework_TestCase
{
public function testRunTheThing()
{
$app = new Application();
$this->assertEquals($app->testprop, 'Stuff');
}
}
I run the following in my command prompt:
phpunit --coverage-html report ApplicationTest.php
The test passes but the code coverage report generated is of the composer ClassLoader file.
It seems to have been an issue with the versions of phpunit and its dependencies. I ran an update on phpunit and now it is generating the coverage reports successfully. I am now using PHP_CodeCoverage 1.2.16, PHP 5.4.3 and PHPUnit 3.7.32.