|

Profilez vos tests PHPUnit avec OpenTelemetry

Un projet de développement informatique qui grossit, c’est une base de code qui grossit par la même occasion et la batterie de tests qui évolue en conséquence. On ajoute des tests semaine après semaine, les temps d’exécution s’allongent. Et puis, à un moment, la CI s’arrête net: Allowed memory size exhausted. Le premier réflexe est alors d’augmenter la mémoire allouée à PHP. Et ce cycle peut continuer un certain temps, jusqu’au moment où l’on atteint des seuils critiques.

Je l’ai rencontré dans plusieurs expériences professionnelles. Corriger des problèmes de mémoire est compliqué et l’outillage restreint. On est donc aveugle, on ne sait pas quels tests consomment de la mémoire, lesquels prennent du temps à s’exécuter. Monitorer une application en production est une bonne pratique, pourquoi n’en serait-il pas de même pour nos tests ?

Pour l’observabilité de nos applications de production, un standard est en train de s’imposer: OpenTelemetry. Pourquoi, alors, ne pas utiliser ce dernier pour également suivre ce qu’il se passe sur nos tests: produire des traces et des métriques que nous pourrions analyser ?

Il existe d’ailleurs une bibliothèque pour intégrer de l’observabilité dans nos tests PHPUnit avec OpenTelemetry: flow-php/phpunit-telemetry-bridge. Il s’agit d’une extension PHPUnit qui collecte la télémétrie de votre suite de tests et l’exporte vers n’importe quel backend compatible OTLP.

Pour l’installer, rien de plus simple:

composer require --dev flow-php/phpunit-telemetry-bridge

Il restera ensuite à ajouter la configuration nécessaire dans PHPUnit:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit>
    <!-- ... -->
    <extensions>
        <bootstrap class="Flow\Bridge\PHPUnit\Telemetry\TelemetryExtension">
            <parameter name="service_name" value="phpunit-opentelemetry"/>
            <parameter name="transport" value="curl"/>
            <parameter name="endpoint" value="http://localhost:4318"/>
            <parameter name="emit_traces" value="true"/>
            <parameter name="emit_metrics" value="true"/>
            <parameter name="emit_test_spans" value="true"/>
            <parameter name="emit_test_case_spans" value="true"/>
            <parameter name="curl_connect_timeout_ms" value="1000"/>
            <parameter name="curl_timeout_ms" value="2000"/>
        </bootstrap>
    </extensions>
</phpunit>

Une fois configuré, il ne reste plus qu’à lancer vos tests, les données de télémétrie seront automatiquement envoyées, vous permettant ensuite de les visualiser dans des tableaux de bord.

Vue d'ensemble de la télémétrie d'une suite de tests PHPUnit dans un tableau de bord

On y retrouvera chaque suite de tests avec le détail de chaque test: sa durée, son empreinte mémoire, son statut.

Consommation mémoire des tests PHPUnit visualisée via OpenTelemetry

Quelques points d’attention néanmoins. Instrumenter chaque test a un coût. Cela ne sera pas forcément intéressant sur une petite suite de test. C’est surtout lorsque le projet commence à grossir que ce type de donnée a de la valeur et que vous souhaitez arrêter de naviguer à l’aveugle.

Et si vous désirez en savoir plus, n’hésitez pas à consulter la documentation de l’outil.

Jérémy DECOOL

Jérémy DECOOL

Développeur depuis plus d'une décennie, je partage mes réflexions sur les bonnes pratiques de développement, d'architecture logicielle et d'organisation d'équipe.