Accélérer les tests de Symfony en stockant le cache et les logs en mémoire et en utilisant SQLite

Lors du développement et du lancement des tests de Symfony, l'écriture et la lecture du cache peuvent prendre un temps important à cause des nombreux accès disques. Voici comment stocker ces fichiers dans la mémoire, bien plus rapide qu'un disque (y compris SSD) et comment utiliser une base de données SQLite lors des tests.

Stocker les fichiers dans la mémoire

Sous Linux, le dossier /run/shm est un système de fichier temporaire, créé dans la mémoire (RAM).

Créer les répertoires dans la mémoire :

mkdir -p /run/shm/projet/cache /run/shm/projet/logs

Se déplacer dans le répertoire du projet, puis dans app/ avec Symfony 2 ou var/ avec Symfony 3 :

cd projet/app/

Supprimer les dossiers app et cache :

rm -rf app/ cache/

Créer les liens symboliques afin que les répertoires app et cache pointent vers les dossiers créés au début :

ln -s /run/shm/projet/cache cache
ln -s /run/shm/projet/logs logs

Ajouter cette ligne dans le crontab afin de créer ces dossiers au démarrage de la machine :

@reboot mkdir -p /run/shm/projet/cache /run/shm/projet/logs && chmod 777 -R /run/shm/projet/

Utiliser une base de données SQLite

Comme cela est décrit dans la documentation deLiipFunctionalTestBundle, il est possible d'utiliser une base SQLite lors des tests :

# app/config/config_test.yml
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_sqlite
                path:     %kernel.cache_dir%/test.db

Comparaison

Afin de comparer l'impact de ces modifications sur les performances, j'ai lancé un scénario d'un test Behat avec les différents configurations.

Le cache a été pré-chauffé avant chaque test : app/console cache:warmup --env=test

Résultats

+--------+---------------------+----------------------+
|   X    | cache sur le disque | cache dans /run/shm/ |
+--------+---------------------+----------------------+
| MySQL  | 23,36 s             | 22,22 s              |
| SQLite | 10,90 s             | 8,82 s               |
+--------+---------------------+----------------------+

Conclusion

Comme le montrent les résultats ci-dessus, l'utilisation de la RAM et d'une base de données SQLite peuvent diviser par 3 le temps d'un test.