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?
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.
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.
À partir de Laravel5.4, la fonction createApplication
ne se trouve plus dans tests\TestCase
. Il a été déplacé dans tests\CreatesApplication
trait.
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:
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!
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();
}
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();
}
}
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
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).
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
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.