Skip to main content

Diagnostic des échecs des tests CI

Utilisez Copilot pour CLI pour récupérer les journaux CI, faire le lien entre les échecs et le code local, et résoudre les problèmes sans quitter le terminal.

Copilot pour CLI est fourni avec le serveur MCP GitHub, ce qui lui donne un accès direct à vos exécutions de flux de travail GitHub Actions, aux journaux des travaux et à la vérification des états. Combiné à l’accès à vos fichiers locaux, il peut récupérer les détails des défaillances CI, les mettre en corrélation avec votre code et proposer des correctifs à partir de votre terminal.

Exemple de scénario 1 : Les tests réussissent localement, mais échouent en intégration continue

Vous avez un test qui réussit sur votre machine locale, mais échoue en intégration continue. Vous pouvez demander Copilot pour CLI d’examiner directement cet échec de test.

Dans cet exemple, le code testé définit un service d’ordre simple (order.py), et il existe un test correspondant qui vérifie si une commande a été créée aujourd’hui (test_order_service.py).

Exemple d’invite

Copilot prompt
My CI is failing on this branch. Can you pull the latest workflow run 
logs, figure out what is failing, and help me fix it? The relevant files 
are @order.py and @test_order_service.py

Exemple de réponse

Remarque

La réponse suivante est un exemple. Les réponses Discussion avec Copilot ne sont pas déterministes, vous pouvez donc obtenir une réponse différente de celle affichée ici.

Copilot pour CLI utilise le serveur GitHub MCP pour récupérer vos dernières exécutions de flux de travail sur la branche actuelle, identifie le travail ayant échoué et récupère ses journaux. Il détecte l’échec suivant :

___ TestOrderService.test_order_created_today ___
>       assert order["created_date"] == date.today()
E       AssertionError: assert datetime.date(2024, 1, 15) == datetime.date(2024, 1, 16)

test_order_service.py:45: AssertionError

Après avoir lu les deux fichiers locaux, Copilot pour CLI constate que les dates ont exactement un jour d’écart et identifie cela comme un problème à la frontière entre deux fuseaux horaires. L’exécuteur CI utilise UTC tandis que votre ordinateur local utilise un fuseau horaire différent. Lorsque le test s’exécute près de minuit, date.today() retourne des dates différentes dans chaque environnement.

Copilot pour CLI suggère de standardiser la manière dont today est calculé en injectant une dépendance d’horloge ou en fixant le fuseau horaire :

from datetime import timezone, datetime

def get_today():
    return datetime.now(timezone.utc).date()

Il applique le correctif à order.py et à test_order_service.py, en mettant à jour toutes les références pour utiliser le nouvel utilitaire get_today().

Après le correctif, vous pouvez vérifier les modifications et exécuter les tests localement :

  1. Exécutez /diff pour vérifier exactement ce qui Copilot pour CLI a changé.
  2. Exécutez !pytest test_order_service.py pour confirmer que les tests réussissent localement.
  3. Poussez le correctif et laissez la CI se relancer.

Exemple de scénario 2 : échecs de test intermittents dus à des situations de concurrence

Un test réussit parfois et échoue parfois sur la même machine. Vous souhaitez Copilot pour CLI comparer les journaux des exécutions réussies et de celles ayant échoué afin d’identifier la cause.

Dans cet exemple, le code testé utilise un travail en arrière-plan dans order_service.py pour mettre à jour l'état d'une commande de manière asynchrone, et un test dans test_order_service.py vérifie que l'état final est "processed".

Exemple d’invite pour les conditions de concurrence

Copilot prompt
This test passes sometimes and fails sometimes. Can you pull the logs 
from the last passing and failing CI runs for test_order_processed 
on this branch, compare them, and figure out what is going wrong? 
Relevant files: @order_service.py @test_order_service.py

Exemple de réponse pour les situations de concurrence

Remarque

La réponse suivante est un exemple. Les réponses Discussion avec Copilot ne sont pas déterministes, vous pouvez donc obtenir une réponse différente de celle affichée ici.

Copilot pour CLI utilise le serveur GitHub MCP pour répertorier les exécutions récentes du flux de travail sur la branche actuelle, identifie un passage et un échec d’exécution, puis récupère les journaux pour les deux. Il les compare :

Exécution réussie :

[DEBUG] Created order #1234
[DEBUG] Background job started for order #1234
[DEBUG] Background job completed (52ms)
[DEBUG] Checking order status
[DEBUG] Order #1234 status: processed

Échec de l’exécution :

[DEBUG] Created order #1234
[DEBUG] Background job started for order #1234
[DEBUG] Checking order status
[DEBUG] Order #1234 status: pending

Copilot pour CLI montre que, lors de l’exécution réussie, la tâche en arrière-plan s’est terminée avant la vérification de l’état, tandis que lors de l’exécution ayant échoué, l’état a été vérifié alors que la tâche était toujours en cours d’exécution. Il identifie cela comme une condition de concurrence , car le test n’attend pas que le travail en arrière-plan se termine.

Copilot pour CLI suggère d’ajouter un mécanisme d’attente explicite avant de faire l’assertion et propose une correction à l’aide d’un utilitaire de scrutation :

import time

def wait_for_status(order_id, expected, timeout=5):
    start = time.time()
    while time.time() - start < timeout:
        order = get_order(order_id)
        if order.status == expected:
            return order
        time.sleep(0.1)
    raise TimeoutError(
        f"Order {order_id} did not reach '{expected}' within {timeout}s"
    )

Lectures complémentaires

CLI GitHub Copilot