Dans le cadre des tests fonctionnels on va souvent être amené à travailler avec une base de données. Afin de maîtriser les données qui sont présentes au moment de note test on va pouvoir utiliser un système de fixtures. Ce système va permettre de déclarer un ensemble de données à rentrer dans la base avant d'exécuter chaque test.
Par défaut doctrine dispose d'un tel système mais il n'est pas forcément facile de l'utiliser en dehors de l'invite de commande. De la même manière, on va vouloir initialiser différent set de données en fonction des choses que l'on souhaite tester. Il existe cependant un bundle qui va permettre de charger les données dont on a besoin directement depuis nos tests : LiipTestFixturesBundle.
LiipTestFixturesBundle
Pour l'utiliser il suffit de l'installer :
composer require --dev orm-fixtures liip/test-fixtures-bundle:^1.0.0
Une recette flex est disponible pour ce bundle et Symfony devrait automatiquement l'ajouter à votre fichier bundles.php
.
Maintenant si vous souhaitez charger des fixtures il vous suffit de charger le trait FixturesTrait
pour ensuite avoir accès aux deux méthodes loadFixtures()
et loadFixtureFiles()
.
<?php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Liip\TestFixturesBundle\Test\FixturesTrait;
class ExampleFunctionalTest extends WebTestCase
{
use FixturesTrait;
public function testUserFooIndex(): void
{
// On charge les fixtures dans une classe Spécifique
$this->loadFixtures([App\Fixtures\AppFixtures::class]);
// Ou depuis un fichier PHP renvoyant un tableau
$this->loadFixtureFiles([__DIR__ . '/users.php']);
$client = $this->createClient();
$crawler = $client->request('GET', '/users/foo');
// …
}
}
Alice
Afin de déclarer plus facilement les données à générer vous avez la possibilité d'utiliser des fixtures en YAML. Dans ce cas là il faudra aller charger la librairie Alice.
Cette librairie se repose sur Faker afin de générer des données aléatoirement. Vous avez tout un ensemble de fonctionnalités que vous pouvez utiliser pour renseigner des données et il ne faudra pas hésiter à se rendre sur la documentation pour plus d'informations.
App\Entity\User:
user{1..10}:
email: user<current()>\@domain.fr
password: \$2y\$12\$pkZP7fkgwxr6XtIozrvT0uUUiDCsYW8rAnZa7gckm3A4fd9jMhke
App\Entity\InvitationCode:
code:
code: "54321"
description: Code de test
expire_at: <dateTime("+1 year")>
Sqlite pour plus de rapidité
Comme vous pouvez l'imaginer, vider et remplir la base de données entre chaque test est une tâche qui peut prendre plus ou moins de temps suivant la taille de votre base. Afin d'accélérer ce processus et de ne pas forcément ralentir trop vos tests vous avez la possibilité d'utiliser une base de données SQLite.
# dans le .env.test
DATABASE_URL=sqlite:///%kernel.cache_dir%/test.db
Vous pourrez ensuite indiquer au système de chargement de fixtures qu'il doit mettre en cache les données afin de pouvoir réutiliser une précédente base.
# config/packages/test/framework.yaml
liip_test_fixtures:
cache_db:
sqlite: liip_test_fixtures.services_database_backup.sqlite