{"meta":{"title":"Diagnostic des échecs des tests CI","intro":"Utilisez Copilot 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.","product":"GitHub Copilot","breadcrumbs":[{"href":"/fr/copilot","title":"GitHub Copilot"},{"href":"/fr/copilot/tutorials","title":"Tutoriels"},{"href":"/fr/copilot/tutorials/copilot-cookbook","title":"livre de recettes GitHub Copilot"},{"href":"/fr/copilot/tutorials/copilot-cookbook/debug-errors","title":"Erreurs de débogage"},{"href":"/fr/copilot/tutorials/copilot-cookbook/debug-errors/diagnose-ci-test-failures","title":"Diagnostiquer les échecs des tests CI"}],"documentType":"article"},"body":"# Diagnostic des échecs des tests CI\n\nUtilisez Copilot 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.\n\nCopilot 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.\n\n## Exemple de scénario 1 : Les tests réussissent localement, mais échouent en intégration continue\n\nVous avez un test qui réussit sur votre machine locale, mais échoue en intégration continue. Vous pouvez demander Copilot CLI d’examiner directement cet échec de test.\n\nDans 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`).\n\n### Exemple d’invite\n\n```copilot copy\nMy CI is failing on this branch. Can you pull the latest workflow run \nlogs, figure out what is failing, and help me fix it? The relevant files \nare @order.py and @test_order_service.py\n```\n\n### Exemple de réponse\n\n> \\[!NOTE] La réponse suivante est un exemple. Les réponses Copilot Chat ne sont pas déterministes, vous pouvez donc obtenir une réponse différente de celle affichée ici.\n\nCopilot 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 :\n\n```text\n___ TestOrderService.test_order_created_today ___\n>       assert order[\"created_date\"] == date.today()\nE       AssertionError: assert datetime.date(2024, 1, 15) == datetime.date(2024, 1, 16)\n\ntest_order_service.py:45: AssertionError\n```\n\nAprès avoir lu les deux fichiers locaux, Copilot 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.\n\nCopilot 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 :\n\n```python\nfrom datetime import timezone, datetime\n\ndef get_today():\n    return datetime.now(timezone.utc).date()\n```\n\nIl 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()`.\n\nAprès le correctif, vous pouvez vérifier les modifications et exécuter les tests localement :\n\n1. Exécutez `/diff` pour vérifier exactement ce qui Copilot CLI a changé.\n2. Exécutez `!pytest test_order_service.py` pour confirmer que les tests réussissent localement.\n3. Poussez le correctif et laissez la CI se relancer.\n\n## Exemple de scénario 2 : échecs de test intermittents dus à des situations de concurrence\n\nUn test réussit parfois et échoue parfois sur la même machine. Vous souhaitez Copilot CLI comparer les journaux des exécutions réussies et de celles ayant échoué afin d’identifier la cause.\n\nDans 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\"`.\n\n### Exemple d’invite pour les conditions de concurrence\n\n```copilot copy\nThis test passes sometimes and fails sometimes. Can you pull the logs \nfrom the last passing and failing CI runs for test_order_processed \non this branch, compare them, and figure out what is going wrong? \nRelevant files: @order_service.py @test_order_service.py\n```\n\n### Exemple de réponse pour les situations de concurrence\n\n> \\[!NOTE] La réponse suivante est un exemple. Les réponses Copilot Chat ne sont pas déterministes, vous pouvez donc obtenir une réponse différente de celle affichée ici.\n\nCopilot 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 :\n\n**Exécution réussie :**\n\n```text\n[DEBUG] Created order #1234\n[DEBUG] Background job started for order #1234\n[DEBUG] Background job completed (52ms)\n[DEBUG] Checking order status\n[DEBUG] Order #1234 status: processed\n```\n\n**Échec de l’exécution :**\n\n```text\n[DEBUG] Created order #1234\n[DEBUG] Background job started for order #1234\n[DEBUG] Checking order status\n[DEBUG] Order #1234 status: pending\n```\n\nCopilot 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.\n\nCopilot 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 :\n\n```python\nimport time\n\ndef wait_for_status(order_id, expected, timeout=5):\n    start = time.time()\n    while time.time() - start < timeout:\n        order = get_order(order_id)\n        if order.status == expected:\n            return order\n        time.sleep(0.1)\n    raise TimeoutError(\n        f\"Order {order_id} did not reach '{expected}' within {timeout}s\"\n    )\n```\n\n## Lectures complémentaires\n\n* *\n\n[GitHub Copilot CLI](/fr/copilot/how-tos/copilot-cli)"}