đź’Ż

Tests

📌
Pour aller plus loin : https://symfony.com/doc/current/testing.html

Tests unitaires


Un test unitaire vérifie que le comportement attendu est le bon, ce qui permet de gagner énormément de temps.

Ex : un getter doit retourner la bonne valeur 100 fois.

On ne fait pas de test unitaire sur des valeurs aléatoires, mais sur des choses qui se répètent et donnent toujours le même résultat.

ℹ️
Dans le monde professionnel, on ne peut pas commit ni push si on a pas 80-90% de couverture de tests.

Créer un test unitaire :

ℹ️
On peut choisir parmi 5 tests différents : 1. TestCase = tests basiques de PHPUnit (est-ce que la classe PHP fonctionne ?) 2. KernelTestCase = tests basiques qui ont accès aux services Symfony (ex : la classe testée peut être un contrôleur qui retourne un Twig) 3. WebTestCase = simule le comportement d’un navigateur web (sans exécuter de code JavaScript), avec des requêtes HTTP, des déplacements dans application, l’utilisation des boutons, formulaires… 4. ApiTestCase = simule le comportement avec une API 5. PantherTestCase = magie, simule le comportement “E2E” (end to end) où il ouvre un vrai navigateur et déplace même la souris —> Nous, les tests 1 et 2 pour l’instant.

Lancer les tests unitaires (tous ceux qu’on a écrits) : php bin/phpunit

(on obtient le pourcentage de tests lancés qui ont réussi.)

Les tests auto-générés ne sont pas à utiliser tels quels (on vérifie si vrai est vrai). On les modifie à façon.

Exemple de test utile : si la date de sortie est inférieure à la date du jour, alors elle ne doit pas être modifiée.

namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class MovieControllerTest extends WebTestCase
{
    public function testSomething(): void
    {
        $client = static::createClient();
        $client->request('GET', '/');

        $this->assertResponseIsSuccessful();
    }
}

⚠️
Un test doit ĂŞtre suffisamment simple pour ne pas avoir besoin de le tester.

De nombreuses méthodes sont disponibles :

$this->assertTrue();
$this->assertEquals();
$this->assertNull();
...
$client->request(method, url);
$client->back();
$client->forward();
$client->reload();

// clears all cookies and the history
$client->restart();

$client->followRedirects();

ℹ️
Le principe d’exécuter les tests unitaires à chaque push, c’est ce qu’on appelle l’intégration continue.

Base de données de tests


Un .env.test a été créé : généralement on ne fait pas les tests sur la base de données de production mais sur une autre, on indique la DATABASE_URL correspondante.

Elle est créée en spécifiant l’environnement de travail concerné : symfony console doctrine:database:create --env=TEST.

BP : La base de données de tests est généralement un autre type de base de données (SQLite, par exemple).

Fixtures

Les fixtures permettent de remplir la base de données de tests avec de fausses données (aléatoires ou choisies).

class AppFixtures extends Fixture
{
    public function load(ObjectManager $manager)
    {
        // on met un film
				$movie = new Movie();
						//ici on remplit les attributs
				// on persist en base
				$manager->persist($serie);
        $manager->flush();
    }
}
ℹ️
Au choix, on crée un fichier de fixtures par entité ou un seul fichier qui contient tout.

L’insertion de fausses données aléatoires est possible.

$faker = Faker\Factory::create('fr_FR');
for($i=0; $i < 1000; $i++) {
	$movie = new Movie();
	// on choist des attributs et faker-> a plein de méthodes de génération
	$movie->setDateCreated($faker->dateTime);
	$manager->persist($serie):
}

Une fois les scripts de données de tests prêts,

📌
Pour aller plus loin : https://symfony.com/bundles/DoctrineFixturesBundle/current/index.html https://github.com/fzaninotto/Faker ≠ Les bouchons (mocks) permettent de tester une partie du code indépendamment de ses dépendances. Il est conseillé de les utiliser, mais dans des cas bien précis (par exemple, pour tester un contrôleur avec un dépôt en injection de dépendance).

⚠️
Ne pas oublier les risques de sécurité lorsque l’on télécharge des paquets.