How to use $_SERVER['DOCUMENT_ROOT'] with Phpunit - php

I am trying to set up Phpunit and across my whole project, $_SERVER['DOCUMENT_ROOT'] is used to link all files/functions/the connection etc. In my test class if I link the absolute path of my global_php_includes.php file (which is the parent file that contains more includes for everything else) then it gets an error every time $_SERVER['DOCUMENT_ROOT'] is called.
I'm very new to Phpunit, is there any way to solve this? I installed it using composer. Here is my xml file:
<?xml version="1.0" encoding="UTF-8" ?>
<phpunit bootstrap="vendor/autoload.php" colors="true" verbose="true" stopOnFailure="true">
<testsuites>
<testsuite name="unit">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>

Facing this issue, you can't do it (as far as I know).
If you launch phpunit through CLI, it's not use by the server directly, but with PHP, so you have to specify the absolute path (the same way that if you do a cron job).
I recommend you to use classes with you website to make it easier to use PHPUnit, but use absolute path for you project

Related

Unable to run PHPUnit Test with relative include path

I am doing an assignment and I was asked not to modify the Test File (CheckPayTest.php). I try to run test but phpunit cannot find the file and the file is correctly placed in the directory. Is it possible to make phpunit see this file when running the test
CheckPayTest.php
<?php declare(strict_types=1);
namespace cms\tests;
use PHPUnit\Framework\TestCase;
class CheckPayTest extends TestCase
{
public function test_File_Read()
{
$readFile = include './../Creative.php';
self::assertTrue($readFile);
}
}
File to include Creative.php
<?php declare(strict_types=1);
namespace cms;
return true;
phpunit.xml Config
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="My Test Suite">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
</phpunit>
Error
1) cms\tests\CheckPayTest::test_File_Read
include(./../Creative.php): failed to open stream: No such file or directory
Could this problem be solved without modifying CheckPayTest.php
Yes, you can make it run without modifying CheckPayTest.php.
Unfortunately someone who wrote this test was not aware of how php executable resolves relative directory paths - so the problem jumped out.
The solution is to change the directory from where php script starts to execute - php resolves relative paths from within any file during execution in reference to entry point of script start. The solution is to cd (change directory) to where this path './../Creative.php' becomes valid and run phpunit script from there.
Anyway, this solution is really poor - the correct way to fix it is to change first dot from the path to php magic constant __DIR__ which always provide absolute path to directory in which code was executed. I think you should change this file anyway - otherwise it will remain poorly written.
Try to change './../Creative.php' into __DIR__ . '/../Creative.php'

How to configure PHPUnit to test the whole vendor folder in a ZF2 application?

I'm developing a Zend Framework 2 application with a common folder structure, so that the folder /vendor contains all (project external) libraries. Setting up the unit testing environment I would like to be able to run all vendor tests. The folders structures are different depending on the library. Some packages have no tests at all.
A possible solution would be to create a test suite "vendor" and manually define there the paths to every single test folder, e.g.:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit ...>
<testsuites>
<testsuite name="vendor">
<directory>../vendor/lib-foo/path/to/tests</directory>
<directory>../vendor/package-bar/path/to/tests</directory>
...
</testsuite>
...
</testsuites>
...
</phpunit>
I don't like this solution. First of all because then I'd have to handle every package manually.
Another solution would be to define /vendor as test folder:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit ...>
<testsuites>
<testsuite name="vendor">
<directory>../vendor</directory>
...
</testsuite>
...
</testsuites>
...
</phpunit>
Well, but then PHPUnit has to scan a lot of folders, that it doesn't need, and the tests will need much more time.
Is there a better solution, that would make possible to automate the process and avoid much manual configuration?
It would probably be difficult to run all PHPUnit vendor test suites with a single test run. One issue is that each of the different test suites might ship its own configuration file or even require a custom bootstrap configuration file. You cannot cover that when running all test suites with a single command.
I'd probably use some shell magic for this. Note that this example relies on the presence of a phpunit.xml(.dist) file in each of your 3rd party packages (for most libraries that's a reasonable assumption). You could even integrate this into your continuous integration process to test this continuously:
for FILE in $(find . -name 'phpunit.xml*') ; do
sh -c 'cd '$(dirname $FILE)' && composer install'
vendor/bin/phpunit -c $FILE
done

How to test every module in my application phpunit - zend framework 2

I already made test for my application module and other module. They are working fine but i want to run all the test (application module and other module) toguether to generate clover report for jenkins. What should i do?? create another config file to invoke other config files??
---edit---
I have the same code for each module bootstrap.php and i want to use the same for each module to avoid code duplication. Rigth now i have two modules Application and Problem when i run phpunit it throws me this error:
**.PHP Fatal error: Class 'ProblemTest\Bootstrap' not found ....**
The test for the Application module works fine but the test for Problem module doesn't work for the namespace declaration in the phpunit_bootstrap.php file.
My Application test uses this declaration:
<?php
namespace ApplicationTest\Controller;
use ApplicationTest\Bootstrap; ....
My Problem tes uses this declaration:
<?php
namespace ProblemTest\Controller;
use ProblemTest\Bootstrap;
This is my phpunit.xml
<phpunit bootstrap="phpunit_bootstrap.php">
<testsuites>
<testsuite name="ALL">
<directory>module/Application/test</directory>
<directory>module/Problem/test</directory>
</testsuite>
</testsuites>
this is my phpunit_bootstrap.php
<?php
namespace ApplicationTest;
The problem that i have rigth now to run all the test toguether is how to include the same bootstrap for every test to avoid that exception.
You can make a testsuite to run a bunch of individual groups of tests all at once. In your phpunit.xml.dist file:
<phpunit bootstrap="phpunit_bootstrap.php">
<testsuites>
<testsuite name="all">
<directory>./</directory>
</testsuite>
<testsuite name="ALL">
<directory>/path/to/module1tests</directory>
<directory>/path/to/module2tests</directory>
<directory>/path/to/module3tests</directory>
<exclude>/path/to/module4tests</exclude>
</testsuite>
<testsuite name="module1only">
<directory>./module1tests</directory>
</testsuite>
</testsuites>
And then you can run it with: /path/to/phpunit --testsuite="ALL"
I can't comment yet so another solution to this issue can be found at zend framework 2 + phpunit + multiple modules + continuous integration If you don't want to go through naming each module independently.

Entity Class not found PHPUnit Test

Below are the paths where files are located,
src\TW\Talk\Entity\Talk.php
src\Tests\Talk\Entity\TalkTest.php
src\phpunit.xml.dist
In TalkTest.php, I have included PHPUnit and the entity Talk.
require_once 'TW/Talk/Entity/Talk.php';
require('PHPUnit/Autoload.php');
Class TalkTest extends PHPUnit_Framework_TestCase
{
...
}
In phpunit.xml.dist file, I have,
<phpunit>
<testsuites>
<testsuite name="TW">
<file>Tests/Talk/Entity/TalkTest.php</file>
</testsuite>
</testsuites>
</phpunit>
I am running phpunit command from src directory, I am getting error that Fatel Error: Class 'Tests\TW\Talk\Enity\Talk' not found.
For reference, I am referring to php-object-freezer-master which has similar structure.
Any idea why the TalkTest is not able to find Talk class ?
phpunit command is trying to find Talk entity in Tests folder.
Changing phpunit.xml.dist to
<phpunit bootstrap="loader.php">
<testsuites>
<testsuite name="TW_Talk">
<directory>Tests</directory>
</testsuite>
</testsuites>
</phpunit>
and loader file as,
<?php
function tw_test_autoloader($class) {
if(file_exists(__DIR__."\\" . $class . ".php"))
require_once(__DIR__."\\" . $class . ".php");
}
spl_autoload_register('tw_test_autoloader');
Worked for me.
But still if I replace directory tag to file
<file>Tests\TW\Talk\Entity\TalkTest.php</file>
It does not work.
Check your include_path:
echo get_include_path();
It should contain the directory to which your TW/Talk/Entity/Talk.php is relative. If it is not there, then you must add it either to php.ini or to PHPUnit's bootstrap.
You can easily test if PHP can find your file using your include path with this:
var_dump( stream_resolve_include_path('TW/Talk/Entity/Talk.php') );

How to run full directories in phpunit?

I have somewhat complex dir structure for my tests.
En example:
unitests
unitests/moduleA
unitests/moduleA/t1.php
unitests/moduleA/t2.php
unitests/moduleA/t3.php
unitests/moduleB
unitests/moduleB/t1.php
unitests/moduleB/t2.php
unitests/moduleB/t3.php
I might have deeper directory structure.
How would I run ALL the tests in one command?
(I tried phpunit unitests/*/* which ran only the first file found unitests/moduleA/t1.php)
You should use a configuration file, it will make things easier to run the tests in the future.
If you create a phpunit.xml file containing :
<phpunit>
<testsuites>
<testsuite name="Unit">
<directory>unitests/*</directory>
</testsuite>
</testsuites>
</phpunit>
and run phpunit, all tests should run.
You should also suffix all your classes with Test.
Also it's not a bad idea to create a test suite per sub-folder.

Categories