-1

I have chosen to use a Phar of PHPUnit (phpunit-4.8.26.phar) to unit test my custom built PHP Framework and Application. The reason I am using the old stable release is because I need compatibility with PHP 5.4.29.

The reason I have chosen not to use Composer to get PHPUnit is because it's tends to pollute my vendors folder with dependencies. I like to keep it as lean as possible.

I am using Windows 7 Pro SP1, WampDeveloper v5.4.0.1, ProPhpStorm 2016.1.2, Phing and a whole bunch of other cool stuff to do my thing.


The Problem

  • I CAN run a passing unit test successfully from within PhpStorm.
  • I CAN run a group of passing unit tests successfully from within PhpStorm.
  • I CAN NOT run a FAILING unit test successfully from within PhpStorm.
  • I CAN run a passing unit test successfully from the command line.
  • I CAN run a group of passing unit test successfully from the command.
  • I CAN NOT run a FAILING unit test successfully from the command line.

Instead of PHPUnit display a typical test failure message it exits with the below errors:

Warning: require(Composer\Autoload\ClassLoader.php): failed to open stream: No such file or directory in D:\WampDeveloper\Websites\qclean.development\bootstrap\Autoloader.php on line 23

Fatal error: require(): Failed opening required 'Composer\Autoload\ClassLoader.php' (include_path='.;D:\WampDeveloper\Tools\PEAR\pear;D:\WampDeveloper\Tools\PEAR;D:\WampDeveloper\Components\Php\PEAR;D:\WampDeveloper\Tools\PHPMailer;') in D:\WampDeveloper\Websites\qclean.development\bootstrap\Autoloader.php on line 23

And a screen shot to expand on the above:

enter image description here


Supporting Info

My directory structure:

enter image description here


My unit test script ConfigurationTest.php

<?php
/**
 * Created by PhpStorm
 * User:
 * Date: 04/06/16
 * Time: 12:04 PM
 */

namespace nova\tests\configuration;

use PHPUnit_Framework_TestCase as TestCase;

/**
 * Class ConfigurationTest
 * 
 * @package nova\tests\configuration
 */
class ConfigurationTest extends TestCase
{
    protected function setUp()
    {
        parent::setUp();
    }
    
    public function test()
    {
        $result = false;
        
        $this->assertTrue($result);
    }
    
    protected function tearDown()
    {
        parent::tearDown();
    }
    
}

My PHPUnit XML configuration file TestAll.xml

<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="../../../bootstrap/Start.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnError="false"
         stopOnFailure="false"
         stopOnIncomplete="false"
         stopOnSkipped="false"
         stopOnRisky="false"
         syntaxCheck="false"
         timeoutForSmallTests="1"
         timeoutForMediumTests="10"
         timeoutForLargeTests="60"
         verbose="false">

    <testsuites>

        <testsuite name="Nova Framework Test Suite">

            <!-- <directory>.</directory> -->

            <directory>./configuration</directory>

            <exclude>./input</exclude>
            <exclude>./request</exclude>
            <exclude>./security</exclude>
            <exclude>./validation</exclude>
        </testsuite>

    </testsuites>

</phpunit>

And lastly my Autoloader Autoloader.php

<?php

// Ref: https://github.com/philsturgeon/fig-standards

/**
 * Define the application autoloader function.
 */
function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName = '';
    $namespace = '';
    
    if ($lastNsPos = strrpos($className, '\\'))
    {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $namespace) . '.php';
    
    require $fileName;
}

/**
 * Register the autoloader functions.
 */
spl_autoload_register('autoload');

The error and warning indicate the inability to load the Composer\Autoload\ClassLoader.php file. What I don't understand is why it is asking for this file when I am using a Phar? Reading snippets off the internet indicate the Phar should have an internal autoloader though I am unable to see one.

I do not want to have to install Composer just to get it's autoloader. That would defeat the purpose of trying to solely use the Phar.

I added the PHPUnit Phar path to my Windows %path% but this did not make any difference. I understand that this should be done if PHPUnit was installed using PEAR.

Any help on this 'hair pulling out matter' would be greatly appreciated...

midnight-coding
  • 2,857
  • 2
  • 17
  • 27
  • Always post the code, not images of it – Christian Giupponi Jun 07 '16 at 08:28
  • "The reason I have chosen not to use Composer to get PHPUnit is because it's tends to pollute my vendors folder with dependencies. I like to keep it as lean as possible". That's why composer allows to require certain dependencies as `dev`. When deploying in production, you execute `composer install --no-dev` so only dependencies required for the production code are installed. – gontrollez Jun 07 '16 at 08:47
  • @Christian Giupponi. Yes, you are correct. My foobar. – midnight-coding Jun 08 '16 at 06:22

2 Answers2

3

If you look at the stack trace, you'll see that the error is triggered on class_exists. This function calls __autoload by default. This means that the autoloader you registered will be called. In this case it will be called for a class that exists outside of your project.

So you should add an extra file_exists check to your autoloader before requiring the file. You're requiring a file that doesn't exist.

if (file_exists($fileName)) {
    require $fileName;
}

Or just suppress the error (require doesn't throw an exception, so use @):

@require $fileName;
aross
  • 3,325
  • 3
  • 34
  • 42
  • Unfortunately such a modification causes an error in my framework. – midnight-coding Jun 08 '16 at 10:48
  • So then your files don't exist in the specified location and you rely on `include_path`? I'd say this is bad practice. Anyway, you could also just attempt to include the file and suppress errors if they occur. – aross Jun 08 '16 at 11:22
1

All what you need to do it to go to Settings > Language & Frameworks > PHP > PHPUnit and Choose PHPUnit library - and set path to phpunit.phar, that's all.

enter image description here

Christian Giupponi
  • 7,408
  • 11
  • 68
  • 113
Zdenek Machek
  • 1,758
  • 1
  • 20
  • 30
  • That's effectively what I had to do to get it working. In PHPStorm Settings > Languages & Framesworks > PHP >PHPUnit > Test Runner I removed any reference to a default configuration and bootstrap file. That got it working when the individual test file was run directly from PHPStorm. Following this I added some real tests. Doing so required me to have an 'include' path at the top of the test file so my code under test would be present. This is something I was hoping to avoid by using my own autoloader. I guess more experimenting is needed. – midnight-coding Jun 08 '16 at 11:12
  • Well you basically just removed your autoloader (where the actual problem is). So this is just a workaround. – aross Jun 08 '16 at 11:25