PHPUnit in a legacy environment - php

I'm starting to setup PHPUnit (v4.8) to be used in my 'legacy' code (it's not so legacy, but it have bad programming practices).
The structure of my folders is as follows
/home
-phpunit.xml
/folder1
/folder2
/folder3
/vendor
/tests
-Test1.php
/includes
-functions.php
/libs
-User.php
-TableClass.php
....
functions.php
<?php
//require_once $_SERVER['DOCUMENT_ROOT'] . "/home/vendor/autoload.php" ;
require_once $_SERVER['DOCUMENT_ROOT'] . "/home/includes/libs/table_classes/User.php" ;
?>
I have commented that line, because I think composer automatically loads it. Question 1, Am I Rigth? (because phpunit get automatically recognized inside my Test class...)
Test1.php
<?php
class Test1 extends PHPUnit_Framework_TestCase
{
public function testSomething()
{
// $something = getColNameByStatusId(1);
$this->assertEquals(1,2);
}
}
?>
phpunit.xml
<phpunit bootstrap="includes/functions.php" colors="true">
<testsuite name="Test1" >
<directory>./tests</directory>
</testsuite>
</phpunit>
Then I Execute phpunit in command line
My functions.php works fine in my code, of course with no composer integration, but when It's loaded with phpunit it 'breaks', I get the following error:
Warning: require_once(/home/includes/libs/table_classes/User.php): failed to open stream: No such file or directory in C:\wamp\www\home\includes\functions.php on line 18
I think I'm missing the 'loading' stuff for phpunit. My code doesn't use namespaces and PSR-0 neither PSR-4.
Question 2- How to properly load files in this case?
My goal is to load functions.php then it will load all other 'table' classes for doing my tests

Replace $_SERVER['DOCUMENT_ROOT'] with __DIR__ and adjusted the paths accordingly, and everything worked fine.
PHPUnit does not set $_SERVER['DOCUMENT_ROOT'] so It was not finding my files. Apache's do that. So the CLI of PHPUnit couldn't find it.
Hope it helps someone else.

I think it is better to start using PHPUnit by running
phpunit --generate-configuration
and follow some simple questions.
To autoload 'functions.php' and other table 'classes', you may try via composer.json autoload.
"autoload": {
"psr-4": {
"Model\\": "libs/"
}
}
Here is the link with autoload for your reference.

Related

Composer not auto-loading required classes

I'm new to Composer and I'm really struggling to auto-load my classes with composer. What am I missing in the following process?
I installed the package in my PHP includes folder (which is outside the document root - I'm not sure if that matters) like this:
composer require monolog\monolog
It stated it completed successfully and I confirmed the project was added to my vendor folder.
My entire composer.json file looks like this:
{
"require": {
"monolog/monolog": "^1.22"
}
}
My entire test file looks like this:
<?php
require_once "vendor/autoload.php";
use Monolog\Logger;
$log = new Logger("name");
?>
And I get this error when I load the page:
Fatal error: Uncaught Error: Class 'Monolog\Logger' not found in C:\Dropbox\Projects\Web\Websites\Instamation\wwwroot\qbtest.php:6 Stack trace: #0 {main} thrown in C:\Dropbox\Projects\Web\Websites\Instamation\wwwroot\qbtest.php on line 6
It includes the vendor/autoload.php file without any error.
I've tried to run these commands in composer without any change:
composer update
composer dump-autoload -0
I've also tried it with different packages and I get the same error, so I'm pretty sure it has nothing to do with the monolog package.
Is there a step here I'm missing? I don't need to manually define which classes to autoload in a json file if I require them in composer, do I?
Edit 1:
As requested, here's the paths to my different files.
Path to the test page:
C:\Dropbox\Projects\Web\Websites\Instamation\wwwroot\qbtest.php
Path to the composer.json file (outside the document root but in my includes path):
C:\Dropbox\Projects\Web\Websites\Instamation\wwwincludes\composer.json
My vendor folder is here:
C:\Dropbox\Projects\Web\Websites\Instamation\wwwincludes\vendor\
And inside my vendor folder I have these folders and file:
bin/
composer/
monolog/
psr/
autoload.php
You need to include autoload in your qbtest.php as following:
require_once "../wwwincludes/vendor/autoload.php";
use Monolog\Logger;
$log = new Logger("name");

Class is not found phpunit

I have written phpunit test. I ran it by using following commands:
C:\Program Files (x86)\Ampps\www\phpunit.dev\vendor\bin>phpunit -c ../../phpunit.xml
But end up having this error:
PHP Fatal error: Class 'Acme\SumFinder' not found in C:\Program Files (x86)\Ampps\www\phpunit.dev\tests\AcmeTests\SumFinderTest.php on line 15
I have tried several solutions from these questions:
Class 'sample\question2\Hello' not found with composer and phpunit
Autoloading classes in PHPUnit using Composer and autoload.php
but nothing works. What could be the problem and how am I going to solve it? Thanks!
My directory structures:
phpunit.dev/src/Acme/SumFinder.php
phpunit.dev/tests/AcmeTests/SumFinderTest.php
phpunit.dev/composer.json
phpunit.dev/phpunit.xml
My composer.json written like this:
{
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-4": {
"Acme\\": "./src/"
}
},
"autoload-dev": {
"psr-4": {
"AcmeTests\\": "./tests/"
}
}
}
My Acme\SumFinder.php written like this:
<?php
namespace Acme;
class SumFinder {
private $inputArray;
function __construct($inputArray = null) { ... }
function findSum() { ... }
function compareArrays() { ... }
}
?>
My AcmeTests\SumFinderTest.php:
<?php
namespace AcmeTests;
use Acme\SumFinder;
class SumFinderTest extends \PHPUnit_Framework_TestCase
function testFindSum() { ... }
function testCompareArrays() { ... }
?>
My phpunit.xml config file:
<?xml version="1.0" encoding="utf-8" ?>
<phpunit colors="true" bootstrap="./vendor/autoload.php">
<testsuites>
<testsuite name="First Test">
<directory>./tests</directory>
</testsuite>
</testsuites>
I am using windows 10 and AMPPS stack if it could help solve my problem.
As a general answer: If dumping the optimized autoloader solves your problem, and not optimizing it still shows it, you have a typo somewhere in your directories or file names.
Dumping the optimized autoloader will scan all files it finds in the directory mentioned for PSR-4 or PSR-0 autoloading, and write an array with all class names found, and their corresponding file names. If you made a typo in your path, dumping this array will connect the class name to the correct file path, regardless of any typos.
Note that some file systems (mostly Linux) are case sensitive, others not (Windows), and that cases are relevant for PSR-4 and PSR-0, which would result in the autoloading to work on case-insensitive file systems, but not on case-sensitive ones.
The problem with your question is that none of the information you gave contains an OBVIOUS hint that you were doing something wrong. However, you might have re-typed your code and NOT made the error, while your original code still has the typo in the file path. Double check that.

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.

Composer Autoload Issue

I've added composer to an existing project that uses the PHP autoload function. Now that composer autoload.php is being used I've removed my old autoload function and I'm trying to load my existing source directory via composer autoload but it isn't picking up any of my existing source classes.
Everything installed by composer loads fine and can be accessed via namespaces etc. so it's just the existing sources in the source directory not being picked up. Any suggestions?
I've looked at a few other of the composer questions on stackoverflow but nothing I've read has solved my problem.
File structure:
index.php
root/
sources/
vendor/
composer.json
media/
Composer autoload:
"autoload": {
"psr-0": {
"" : "sources/"
}
}
There were two things causing issues for me, one was the class file names and the second was a composer command that needed to be run.
My class file names were in the format {classname}.class.php when they need to be in the format that PSR-0 expects which is Classname.php (uppercase first letter) and in turn the classname in the class file follows the file name.
class Classname
{
...
The second issue was that I needed to run the below command.
composer dump-autoload
From composer.org:
If you need to update the autoloader because of new classes in a classmap package for example, you can use "dump-autoload" to do that without having to go through an install or update.
If your code structure is too complex to convert to PSR-* structure, you can use your old autoloader and composer autoload together.
spl_autoload_register( function ( $class ) {
$file = "sources/" . $class . ".class.php";
if ( file_exists( $file ) ) {
require $file;
return;
}
} );
require "vendor/autoload.php";

Automatic load a Listener in PHPUnit

Is there a way to automatically load a Listener (or phpunit configuration file for that matter), without using no more than:
phpunit testdir
? Today I'm using:
phpunit -c phpunit.xml --bootstrap bootstrap.php testdir
and want to exclude all switches. I know that I could have a phpunit.xml file in every directory, but thats not an option..
Thanks in advance!
PHPUnit by itself should look in the current directory for a phpunit.xml file. So your first and second example should both find and include the same phpunit.xml.
Use a Makefile:
unittest:
phpunit -c phpunit.xml --bootstrap bootstrap.php testdir
And simply call it with make unittest
Now you can add more for different cases, in the same pattern.

Categories