web-dev-qa-db-fra.com

PHPUnit - Chargement automatique des classes dans les tests

J'ai la structure suivante dans mon projet:

/
/app
/app/models/ --UserTable.php

/lib
/lib/framework
/lib/framework/Models
/lib/framework/Db

/tests -- phpunit.xml, bootstrap.php
/tests/app
/tests/app/models --UserTableTest.php

Avec les répertoires app et lib, j'ai plusieurs classes qui fonctionnent ensemble pour exécuter mon application. Pour configurer mes tests, j'ai créé un fichier /tests/phpunit.xml et un /tests/bootstrap.php

phpunit.xml

<phpunit bootstrap="bootstrap.php">
</phpunit>

bootstrap.php

<?php

function class_auto_loader($className)
{
  $parts = explode('\\', $className);
  $path = '/var/www/phpdev/' . implode('/', $parts) . '.php';

  require_once $path;
}

spl_autoload_register('class_auto_loader');

J'ai donc le test suivant:

<?php

class UserTableTest extends PHPUnit_Framework_TestCase
{
  protected $_userTable;

  public function setup()
  {
    $this->_userTable = new app\models\UserTable;
  }

  public function testFindRowByPrimaryKey()
  {
    $user = $this->_userTable->find(1);

    $this->assertEquals($user->id, 1);
  }
}

Mais il ne peut pas trouver la classe lorsque je lance le test - PHP Fatal error: Class 'app\models\UserTable' not found in /var/www/phpdev/tests/app/models/UserTableTest.php on line 13

Qu'est-ce que je fais mal? J'essaie de mieux comprendre la configuration de PHPUnit, j'ai donc choisi d'écrire moi-même le fichier de configuration et d'amorçage.

17
Martyn

Si vous utilisez le chargement automatique de compositeur

changement 

<phpunit colors="true" strict="true" bootstrap="vendor/autoload.php">

à 

<phpunit colors="true" strict="true" bootstrap="tests/autoload.php">

et dans le répertoire tests, créez un nouveau autoload.php avec le contenu suivant

include_once __DIR__.'/../vendor/autoload.php';

$classLoader = new \Composer\Autoload\ClassLoader();
$classLoader->addPsr4("Your\\Test\\Namespace\\Here\\", __DIR__, true);
$classLoader->register();
25
Raaghu

Vous devriez probablement utiliser composer pour organiser votre code, par exemple, le fichier composer.json dans le répertoire racine de votre projet devrait contenir quelque chose comme:

  ...
  "autoload": {
    "psr-0": {
      "PRJ_NAME\\APP\\": "app/",
      "PRJ_NAME\\LIB\\": "lib/"
    }
  },
  ...

Ensuite, après avoir exécuté la mise à jour du compositeur, les deux espaces de noms définis ci-dessus sont placés dans le fichier vendor/composer/autoload_namespaces.php. Suivant est simple, il suffit d’exécuter phpunit avec l’option autoload comme ceci:

phpunit --bootstrap vendor/autoload.php tests/app/models/UserTableTest

Assurez-vous de changer l'utilisation de votre espace de noms dans votre code source et votre code de test.

4
ImLeo

Si vous chargez votre classe avec le même bootstrap dans l'application, vous devriez pouvoir les charger dans des tests. Si vous exécutez test par cd dans votre répertoire de test, ajoutez simplement à votre phpunit.xml:

<testsuite name="My Application Tests">
    <directory>./</directory>
</testsuite>

<phpunit></phpunit> intérieur

1
Amorphous

Dans mon loader (très proche du vôtre), je vérifie si la première partie éclatée du nom de la classe est mon vendor , si ce n’est pas le loader ne retourne rien sans rien (sinon problèmes avec phpunit 's loader , puisque je suis un débutant de phpunit et je ne sais pas s’il s’agit du comportement attendu ni si phpunit suggère ou fournit un chargeur prêt à utiliser).

Je garde phpunit.xml dans le même répertoire que tests/ (pas à l'intérieur) et une fois configuré <directory>tests</directory>, je lance simplement phpunit en ligne de commande sans configuration ni options de répertoire. 

1
Alex