Unable to run PHPUnit Test with relative include path - php

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'

Related

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

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

How to compare 2 URL adres with PHPUnit?

I am working on a task that is expose a xml file with given url. I want to test my code and I do this with PHPUnit. I used composer to install PHPUnit.
The example test that I want to run is this :
<?php
use PHPUnit\Framework\TestCase;
class IndexTest extends TestCase{
public function testGetXmlWithUrl(){
require 'index.php';
$XmlClass = new XmlReaderClass("localhost", "8000", "status.xml", "");
$url= $XmlClass->$url;
$myUrl = "http://localhost:8000/status.xml?password=";
$this->assertEquals($myUrl, $url);
}} ?>
TestCase class cannot be added. I mean even PhpUnit name is not colored in blue in the code. So I guess I could not include it in my project actually. Error is like:
Fatal error: Uncaught Error: Class 'PHPUnit\Framework\TestCase' not found in /Users/demetsen/Desktop/tests/IndexTest.php:4
My second problem is when I try to run testGetXmlWithUrl() method the result is :
Failed asserting that SimpleXMLElement Object (...) matches expected '\n ....
Why am I getting this result and how can I solve it?
A default phpunit.xml (or better, use phpunit.xml.dist, so you can copy/edit it locally if needed), can be created with phpunit --generate-configuration will include a line for bootstrap:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
bootstrap="path/to/bootstrap.php"
<!-- more lines -->
</phpunit>
Here, the bootstrap="...." line can, at its simplest, point to the composer autoloader. PHPunit can also create a suitable file for you.
$ php ./phpunit-9.2.phar --generate-configuration # or vendor/bin/phpunit, via composer
PHPUnit 9.2.6 by Sebastian Bergmann and contributors.
Generating phpunit.xml in /home/username/code/test
Bootstrap script (relative to path shown above; default: vendor/autoload.php):
Tests directory (relative to path shown above; default: tests):
Source directory (relative to path shown above; default: src):
Generated phpunit.xml in /home/username/code/test
# optional, but useful:
# mv phpunit.xml phpunit.xml.dist # .dist will be read if .xml does not exist
The output file:
$ cat phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.2/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 had something you needed to add to the bootstrap process, create a file with your needs, and you'd probably also add something like require __DIR__.'/vendor/autoload.php'; to setup the autoloading.

PHPUnit inheritance tests

I have a parent and a child classes - loaded with spl_register_autoload()) and I'm trying to write PHPUnit tests; I have a problem with the inheritance : when I run tests, this warning message appears:
Warning: include(classes/PHPUnit\Composer\Autoload\ClassLoader.class.php): failed to open stream: No such file or directory in C:\wamp64\www\test\test\unit_tests\test\Employe9Test.php on line 36.
Any idea?
The relative path to ClassLoader.class.php is not found when the file is called from Employe9Test.php
If you need an autoloader for your tests, may I suggest you to use the bootstrap property in the phpunit config file?
<phpunit bootstrap="src/autoload.php">
<testsuites>
<testsuite name="money">
<file>tests/IntlFormatterTest.php</file>
<file>tests/MoneyTest.php</file>
<file>tests/CurrencyTest.php</file>
</testsuite>
</testsuites>
</phpunit>
Source
That way you won't have to adjust/edit the autoload file path in each of your test file if the autoload file path changes.

PHPUnit test error, cannot find class

I'm new in PHPUnit and unit-testing, so I was install PHPUnit and phar via composer and everything had been going fine until I was try to start my simple test. I'm using PhpStorm where I can see all classes were autoload, but when I trying to start my test I got an error:
Fatal error: Class 'PharIo\Manifest\Simple' not found in C:\xampp\htdocs\mydocs\
I don't understand why he is looking for It in folder upper than PHPUnit is exists ?
I was trying to configure autoload section in composer.json and checking settings in phpunit.xml but nothing works.
Add:
I have to reinstall PHPUnit without PharIO, so now I have a little bit of progress, now I have a situation where I can test my class if I make require_once line with a name of the tested class. It looks like:
require_once '../src/Simple.php';
class SimpleTest extends PHPUnit_Framework_TestCase
{
public function testAdd() {
$sum = new Simple();
$this->assertEquals(5, $sum->add(2, 3));
}
}
So my simple class is:
class Simple {
public function add($a, $b) {
return (int) $a + (int) $b;
}
}
But, of course, I want to use namespaces. I try to make some changes based on this question: Autoloading classes in PHPUnit using Composer and autoload.php (I was try even use that repo for test, but an error is still exists) but nothing works for me. I was try to edit my autoload section in the composer.json like this
"autoload": {
"psr-4": {
"app\\": "src/"
}
},
But an error is still exists, another words autoload cannot see It. I was create phpunit.xml and phpunit.dist.xml with a same settings
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xsd"
backupGlobals="true"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./tests/bootstrap.php">
<testsuites>
<testsuite name="The project's test suite">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
and I made tests/bootstrap.php too with
require_once '../vendor/autoload.php';
I know this is an old question, but maybe you need to do
composer dump-autoload for composer to generate the map of classes.
I wasted 30mins trying to understand why PHPUnit was giving me:
Cannot stub or mock class or interface XXX because it doesn't exists
You should specify the script with autoloading classes.
You can either specify the file with autoloading in XML-file, as suggested in the other answer, or just by specifying --bootstrap option in your command to run tests:
phpunit --bootstrap vendor/autoload.php tests
Composer's autoload relies on configuration located in the vendor/autoload.php file which needs to be loaded at some point in your execution thread. You application already includes this and that's why it works, but the tests use a different entry point so you need to configure it with a file called phpunit.xml.dist.
Assuming your file structure is something like:
app/
src/
tests/
bootstrap.php <- create it in your test folder
vendor/
...
composer.json
composer.lock
phpunit.xml.dist <- create it if does not exist
You can see the various options here, but for a basic config, you can use this.
File phpunit.xml.dist:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/3.7/phpunit.xsd"
backupGlobals="true"
backupStaticAttributes="false"
bootstrap="tests/bootstrap.php">
</phpunit>
File tests/bootstrap.php:
require_once '../vendor/autoload.php';
You should run phpunit from the root.

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') );

Categories