web-dev-qa-db-fra.com

Comment spécifier un fichier .env différent pour phpunit dans Laravel 5?

J'ai un .env fichier contenant les détails de ma connexion à la base de données, comme c'est normal pour Laravel 5. Je veux les remplacer pour les tests, ce que je peux faire dans phpunit.xml. Cependant, cela semble aller à l'encontre de la philosophie de .env qui ne consiste pas à valider des configurations environnementales, notamment des mots de passe.

Est-il possible d'avoir quelque chose comme .env.testing et de dire phpunit.xml pour lire?

21
Gnuffo1

Copiez votre .env Dans .env.testing, Puis modifiez le fichier .env.testing Et modifiez le paramètre APP_ENV Pour le rendre ainsi APP_ENV=testing De cette façon vous pourra spécifier vos paramètres dans ce nouveau fichier

Dans le cas où vous ne voulez pas créer un nouveau fichier .env.testing, Vous devez spécifier vos variables dans le phpunit.xml Dans la section php avec les valeurs dont vous avez besoin, quelque chose comme ceci

<php>
    <env name="APP_ENV" value="testing"/>
    <env name="CACHE_DRIVER" value="array"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="QUEUE_DRIVER" value="sync"/>
    <env name="DB_CONNECTION" value="sqlite"/>
    <env name="DB_DATABASE" value="testing"/>
</php>

Utilisez simplement les valeurs de clé dans la section nom et la valeur de cette clé dans la section valeur.

Pour cet exemple, je spécifie phpunit pour utiliser une base de données sqlite avec le nom de testing.

Par ailleurs, dans config/database.php, j'ai ajouté cette 'default' => env('DB_CONNECTION', 'mysql'), pour utiliser mysql par défaut, sauf si je spécifie quelque chose de différent, comme dans ce cas.

11
Dimitri Acosta

Vous pouvez remplacer le .env fichier utilisé dans votre fichier TestCase, où le framework est démarré pour les tests.

Plus spécifique:

tests/TestCase.php

/**
 * Creates the application.
 *
 * @return \Illuminate\Foundation\Application
 */
public function createApplication()
{
    /* @var \Illuminate\Foundation\Application $app */
    $app = require __DIR__ . '/../bootstrap/app.php';

    $app->loadEnvironmentFrom('.env.testing'); // specify the file to use for environment, must be run before boostrap

    $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();

    return $app;
}

Tous les tests étendant TestCase utiliseront ce fichier de configuration.

Veuillez noter que tout paramètre défini dans phpunit.xml remplacera cette configuration.

Mise à jour

À partir de Laravel5.4, la fonction createApplication ne se trouve plus dans tests\TestCase . Il a été déplacé dans tests\CreatesApplication trait.

9
Bogdan

Nous sommes en 2019.

J'ai eu ces problèmes pendant si longtemps jusqu'à ce que je puisse le comprendre.

Et voici mon hypothèse:

Si vous avez également du mal à faire parler PHPUnit.xml avec votre fichier .env.testing, alors vous utilisez probablement PHPStorm!

Si c'est vrai, continuez à lire.

Sinon, non ... cela n'aidera pas.

D'accord...

Voici:

  1. Accédez aux paramètres de votre PHPStorm ou appuyez simplement sur Ctrl + Alt + S.
  2. Allez dans Langues et Frameworks >> PHP >> Test Frameworks
  3. Sous l'onglet Test Runner, cliquez sur Fichier de configuration par défaut et sélectionnez (en cliquant sur l'icône du dossier) le chemin du fichier PHPUnit.xml de votre projet.

Ce que cela fait, c'est que toutes vos modifications dans le fichier xml prennent effet. Alors, allez-y, créez le fichier .env.testing, créez vos variables de configuration de base de données préférées pour le test ... et essayez de relancer vos tests!

4
Wale

Créez une base de données locale sur votre machine de développement, par ex. 'local_test_db'

Créez un nouveau fichier .env.testing.

DB_DATABASE=local_test_db
DB_USERNAME=root

Assurez-vous que votre fichier phpunit.xml a au moins celui-ci env var:

<php>
    <env name="APP_ENV" value="testing"/>
</php>

Enfin, votre testcase de base (TestCase.php) doit exécuter une migration pour remplir la base de données avec des tables:

public function createApplication()
{

    $app = require __DIR__.'/../bootstrap/app.php';

    $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

    return $app;
}


public function setUp()
{
    parent::setUp();
    Artisan::call('migrate');
}

public function tearDown()
{
    Artisan::call('migrate:reset');
    parent::tearDown();
}
3
S..

De cela lien

Méthode 1

Étape 1: Créez une nouvelle connexion de base de données de test sur Database/Config.php comme ci-dessous:

return [
    ... 

    'default' => env('DB_CONNECTION', 'db'),    

    'connections' => [
        'sqlite_testing_db' => [
            'driver' => 'sqlite',
            'database' => storage_path().'/testing_database.sqlite',           
            'prefix' => '',
        ],

        /**************** OR ******************/

        'testing_db' => [
            'driver' => 'mysql',
            'Host' => env('TEST_DB_Host', 'localhost'),
            'database' => env('TEST_DB_DATABASE', 'forge'),
            'username' => env('TEST_DB_USERNAME', 'forge'),
            'password' => env('TEST_DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
        ],

        /** Production or database DB **/
        'db' => [
            'driver' => 'mysql',
            'Host' => env('TEST_DB_Host', 'localhost'),
            'database' => env('TEST_DB_DATABASE', 'forge'),
            'username' => env('TEST_DB_USERNAME', 'forge'),
            'password' => env('TEST_DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
        ],
    ],
];

Étape 2: spécifiez les informations d'identification de la base de données sur le fichier .env

TEST_DB_Host=localhost
TEST_DB_DATABASE=laravel
TEST_DB_USERNAME=root
TEST_DB_PASSWORD=rootwdp

Étape 3: Spécifiez la connexion test db à utiliser sur phpunit.xml.

<env name="DB_CONNECTION" value="testing_db"/>
          OR Below If you prefer sqlite
<env name="DB_CONNECTION" value="sqlite_testing_db"/>                

Étape 4: Migrez la base de données vers cette nouvelle base de données de test - si vous choisissez d'utiliser l'insertion de la transaction de base de données vers la restauration sur la table.

php artisan migrate --database=testing_db

//If using sqlite
touch storage/testing_database.sqlite
php artisan migrate --database=sqlite_testing

Étape 5: Maintenant, le test unitaire avec la transaction de base de données ressemble à ci-dessous:

<?php

use App\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class UserTest extends TestCase
{
    use DatabaseTransactions;

    /** @test */
    function it_test_user_can_be_saved()
    {
        factory(User::class, 2)->create();

        $users = User::all();

        $this->assertEquals(2, $users->count());
    }
}

//Run Php Unit
-> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php

Remarque: Si vous préférez ne pas utiliser la transaction de base de données, vous pouvez utiliser la méthode de configuration et de démontage sur la classe TestCase.php pour migrer et restaurer la base de données comme ci-dessous:

<?php

use Illuminate\Support\Facades\Artisan;

class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    ...

    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
    }

    public function tearDown()
    {
        Artisan::call('migrate:reset');
        parent::tearDown();
    }
}
2
Sambhu Singh

J'ai fait toutes les étapes de la réponse @Sambhu Singh et j'ai suivi son lien. Mais ça n'a pas marché pour moi en L5.5

Lors de la migration, l'ajout/la définition de APP_ENV à "testing" devant la commande artisan a fonctionné pour moi:

APP_ENV=testing php artisan migrate --database=sqlite_testing
1
Nisal Gunawardana

Je ne vois pas d'autre moyen que de renommer temporairement .env.testing en .env avant le début des tests unitaires.

Vous pouvez mettre de la logique dans bootstrap/autoload.php car c'est ce que phpunit utilise car c'est un fichier bootstrap avant de charger l'application).

1
fire

Dans votre app.php changez la section Dotenv

$envFile = 'testing' === env('APP_ENV') ? '.env.testing' : null;
try {
    (new Dotenv\Dotenv(__DIR__ . '/../', $envFile))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    //
}

Cela fonctionnera donc PHPUnit modifie l'env avant de charger votre application .. donc si vous exécutez des tests, vous aurez déjà l'env à tester

1
Julius Koronci

Je lutte avec cela depuis quelques mois maintenant et je viens de découvrir ce problème Github aujourd'hui. Parmi les solutions proposées, voici ce que vous devez faire dans votre fichier CreatesApplication.php (pour supprimer la configuration mise en cache afin d'avoir Laravel charger l'environnement de test):

/**
 * Creates the application.
 *
 * @return \Illuminate\Foundation\Application
 */
public function createApplication()
{
    $app = require __DIR__.'/../bootstrap/app.php';

    $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

    $this->clearCache(); // NEW LINE -- Testing doesn't work properly with cached stuff.

    return $app;
}

/**
 * Clears Laravel Cache.
 */
protected function clearCache()
{
    $commands = ['clear-compiled', 'cache:clear', 'view:clear', 'config:clear', 'route:clear'];
    foreach ($commands as $command) {
        \Illuminate\Support\Facades\Artisan::call($command);
    }
}

Si vous rencontrez toujours ce problème après la modification ci-dessus, vous pouvez aller plus loin en reconstruisant l'intégralité de l'application comme suit:

public function createApplication()
{
    $createApp = function() {
        $app = require __DIR__.'/../bootstrap/app.php';
        $app->make(Kernel::class)->bootstrap();
        return $app;
    };

    $app = $createApp();
    if ($app->environment() !== 'testing') {
        $this->clearCache();
        $app = $createApp();
    }

    return $app;
}

Cela fonctionne très bien pour moi.

0
Leonel Elimpe