Categories

  • Test

Tags

  • Github action
  • Laravel

Pourquoi une CI “complète” ?

Sur un projet personnel, j’utilise Livewire et lors de la création d’un composant, l’outil permet de créer un simple test qui va juste vérifier que le composant peut se créer et s’afficher.
Dans mon cas, c’est un code très simple :

<?php

use App\Livewire\Charts;
use Livewire\Livewire;

it('renders successfully', function () {
    Livewire::test(Charts::class)
        ->assertStatus(200);
});

Je teste en local, tout fonctionne.
J’ajoute du code dans mon composant, je teste, ça fonctionne.
Je pousse sur github, où une action va lancer mes tests, et là… erreur !

Après une rapide recherche, je trouve le coupable, la configuration de la CI

C’est quoi une CI ?

Une CI (Continuous Integration, intégration continue en bon français) représente tout le processus d’automatisation des tests, de la mise en forme, des vérifications du code qu’un développeur va produire.

Une bonne CI a différents buts :

  • homogénéiser le code, via des formateurs tels que Pint (pour php) ou Prettier (pour plein de langages)
  • améliorer la qualité du code via des linters tels que PhpStan (pour php) ou EsLint (Ts/Js)
  • valider des tests unitaires / tests d’intégration via des testeurs tels que Pest

Pourquoi les tests n’ont pas fonctionné ?

Le composant, dans son initialisation, éxecute une requête SQL.
Et c’était la première requête exécutée dans mes tests (c’est le début du projet…)
Erreur donc, car la requête plantait.

Et elle plantait car il n’y avait pas de service pour exécuter la requête !

Une autre erreur aussi, c’est que pour un tel test, une séparation composant / requête devrait être faite, je reviendrai dessus un autre jour

Solution

J’ai donc configuré un service dans les actions github pour que les tests puissent s’exécuter.
La configuration de mon action ressemble donc à ceci :

name: Test

on:
  pull_request:
    branches: [ "main" ]

jobs:
  laravel-tests:
    runs-on: ubuntu-latest
    env:
      MYSQL_ROOT_PASSWORD: root_testing
      MYSQL_DB: testing
      MYSQL_USER: testing
      MYSQL_PASSWORD: testing
    services:
      mysql:
        image: mysql:latest
        env:
          MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }}
          MYSQL_DATABASE: ${{ env.MYSQL_DB }}
          MYSQL_USER: ${{ env.MYSQL_USER }}
          MYSQL_PASSWORD: ${{ env.MYSQL_PASSWORD }}
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3

Avec ceci, une base de données MySql est lancée sur le port 3306, avec une base nommée testing, pour un utilisateur testing et un mot de passe testing (il y a comme un truc redondant, peut-être même sporadique…)

Dans mon action, je n’ai plus qu’à lancer les tests :

  - name: Execute tests (Unit and Feature tests) via Artisan command
      env:
        DB_DATABASE: ${{ env.MYSQL_DB }}
        DB_USERNAME: ${{ env.MYSQL_USER }}
        DB_PASSWORD: ${{ env.MYSQL_PASSWORD }}
      run: php artisan test

Et maintenant, tout fonctionne proprement.
Est-ce que tout est parfait ?

Si seulement…

La suite dans un prochain post !