jock.perkins
jock.perkins

Reputation: 469

PHPUnit Class unable to find itself

New to PHPUnit and testing and have been following Teamtree House's Guide on it. But I'm stuck at this point and wonder if anyone can help. Here are the details from my files:

phpunit.xml --- in root

<phpunit backupGlobals="true" bootstrap="tests/bootstrap.php">
  <!-- Blacklist the vendor folder -->
  <filter>
    <blacklist>
      <directory>vendor</directory>
    </blacklist>
  </filter>
  <!-- Add the main testsuite -->
  <testsuite>
    <directory>tests</directory>
  </testsuite>
</phpunit>

bootstrap.php --- in ./tests/bootstrap.php

<?php
// Get autoloader
require './vendor/autoload.php';

// Get tests
require './tests/PigLatinTest.php';

// Initialise twig
$loader = new Twig_Loader_Filesystem('./src');
$twig = new Twig_Environment($loader);

PigLatinTest.php --- in ./tests/PigLatinTest.php

<?php
require 'vendor/autoload.php';
require 'src/PigLatin.php';

class PigLatinTest extends PHPUnit\Framework\TestCase
{
  /**
   * @test PigLatin
   */
  public function englishToPigLatinWorksCorrectly()
  {
    /**
     * Given I have an english word
     * If I pass that word to my PigLatin converter
     * I get back the correctly transformed version
     */
     $word = 'test';
     $expectedResult = 'esttay';

     $pigLatin = new PigLatin();
     $result = $pigLatin->convert($word);

     $this->assertEquals(
        $expectedResult,
        $result,
        "PigLatin conversion did not work correctly"
     );
  }
}

PigLatin.php --- in ./src/PigLatin.php

<?php

class PigLatin
{
  public function convert($word)
  {
    // Remove first letter of the word
    $first_letter = substr($word, 0, 1);
    $new_word = substr($word, 1, strlen($word) - 1);
    $new_word .= $first_letter . 'ay';

    return $new_word;
  }
}

When I run the command phpunit in my terminal I get the following output:

PHPUnit 6.2.3 by Sebastian Bergmann and contributors.

Time: 68 ms, Memory: 10.00MB

No tests executed!

But when I run phpunit PigLatinTest.php I get the following error:

PHP Fatal error:  Uncaught PHPUnit\Runner\Exception: Class 'PigLatinTest' could not be found in 'PigLatinTest.php'. in phar:///usr/local/bin/phpunit/phpunit/Runner/StandardTestSuiteLoader.php:101

This is really confusing me, and I can't find a solution on SO at all. If anyone has some insight that would be appreciated!

Upvotes: 2

Views: 2252

Answers (1)

M. Eriksson
M. Eriksson

Reputation: 13645

Your issue is with all the includes. They are trying to include the wrong files.

tests/bootstrap.php

<?php
// Let's use absolute paths instead with the help of __DIR__ which
// will give us the path to the current folder.
require __DIR__ . '/../vendor/autoload.php'; // Up one folder where the vendor is

// Removed the include for PigLatinTest since PHPUnit will handle that.

// Again, let's use __DIR__ to solve the path issues.
$loader = new Twig_Loader_Filesystem(__DIR__ . '/../src');

$twig = new Twig_Environment($loader);

// If your PigLatin-class isn't loaded with autoloading (in your composer.json),
// let's include it in here. Again, with the help of __DIR__
require __DIR__ . '/../src/PigLatin.php';

tests/PigLatinTest.php
In your test class, we can remove all include's. The bootstrap have already taken care of that.

Conclusion
It's important to remember that if you include/require a file that includes/requires other files, all relative paths will be relative from the file that does the including, not the file itself. The best way is to do: require __DIR__ . '/relative/from/this/file.php. The magic constant __DIR__ gives you the absolute path from the file it's written in.

Once you have included a file into your project once, all classes and functions in it it will be accessible in the rest of the request. No need to include it more than once.

Upvotes: 3

Related Questions