{"meta":{"title":"Diagnose von CI-Testfehlern","intro":"Wird Copilot CLI verwendet, um CI-Protokolle abzurufen, Fehler mit lokalem Code zu korrelieren und Probleme zu beheben, ohne das Terminal zu verlassen.","product":"GitHub Copilot","breadcrumbs":[{"href":"/de/copilot","title":"GitHub Copilot"},{"href":"/de/copilot/tutorials","title":"Anleitungen"},{"href":"/de/copilot/tutorials/copilot-cookbook","title":"GitHub Copilot Kochbuch"},{"href":"/de/copilot/tutorials/copilot-cookbook/debug-errors","title":"Debuggen von Fehlern"},{"href":"/de/copilot/tutorials/copilot-cookbook/debug-errors/diagnose-ci-test-failures","title":"CI-Testfehler diagnostizieren"}],"documentType":"article"},"body":"# Diagnose von CI-Testfehlern\n\nWird Copilot CLI verwendet, um CI-Protokolle abzurufen, Fehler mit lokalem Code zu korrelieren und Probleme zu beheben, ohne das Terminal zu verlassen.\n\nCopilot CLI wird mit dem GitHub MCP-Server ausgeliefert. Dadurch erhalten Sie direkten Zugriff auf Ihre GitHub Actions Workflowausführungen, Auftragsprotokolle und Überprüfungsstatus. In Kombination mit dem Zugriff auf Ihre lokalen Dateien können CI-Fehlerdetails abgerufen, mit Ihrem Code korreliert und Korrekturen vom Terminal vorgeschlagen werden.\n\n## Beispielszenario 1: Tests laufen lokal erfolgreich durch, schlagen jedoch in CI fehl\n\nSie haben einen Test, der auf Ihrem lokalen Rechner erfolgreich läuft, aber in CI fehlschlägt. Sie können Copilot CLI bitten, diesen Testfehler direkt zu untersuchen.\n\nIn diesem Beispiel definiert der getestete Code einen einfachen Bestelldienst (`order.py`), und es gibt einen entsprechenden Test, der überprüft, ob heute eine Bestellung erstellt wurde (`test_order_service.py`).\n\n### Beispielaufforderung\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### Beispielantwort\n\n> \\[!NOTE] Die folgende Antwort ist ein Beispiel. Da die Copilot Chat-Antworten nicht deterministisch sind, erhältst du möglicherweise eine andere Antwort als die hier beschriebene.\n\nCopilot CLI verwendet den GitHub MCP-Server, um Ihre neuesten Workflow-Ausführungen im aktuellen Branch abzurufen, den fehlgeschlagenen Job zu identifizieren und dessen Protokolle abzurufen. Es erkennt den folgenden Fehler:\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\nNachdem Copilot CLI beide lokalen Dateien gelesen hat, stellt es fest, dass die Daten genau einen Tag auseinanderliegen, und identifiziert dies als **Problem mit der Zeitzonengrenze**. Der CI-Läufer verwendet UTC, während ihr lokaler Computer eine andere Zeitzone verwendet. Wenn der Test nahe Mitternacht ausgeführt wird, `date.today()` werden in jeder Umgebung unterschiedliche Datumsangaben zurückgegeben.\n\nCopilot CLI schlägt vor, zu standardisieren, wie `today` berechnet wird, indem eine Clock-Abhängigkeit injiziert oder die Zeitzone festgelegt wird:\n\n```python\nfrom datetime import timezone, datetime\n\ndef get_today():\n    return datetime.now(timezone.utc).date()\n```\n\nEs wendet den Fix auf beide `order.py` und `test_order_service.py` an und aktualisiert alle Verweise, sodass sie die neue `get_today()`-Hilfsfunktion verwenden.\n\nNach dem Fix können Sie die Änderungen überprüfen und die Tests lokal ausführen:\n\n1. Führen Sie den Befehl aus `/diff` , um genau zu überprüfen, was Copilot CLI sich geändert hat.\n2. Führen Sie `!pytest test_order_service.py` aus, um zu bestätigen, dass die Tests lokal erfolgreich durchlaufen.\n3. Pushen Sie den Fix, und lassen Sie CI erneut ausführen.\n\n## Beispielszenario 2: Zeitweilige Testfehler mit Rennbedingungen\n\nEin Test besteht manchmal und schlägt manchmal auf demselben Computer fehl. Sie möchten Copilot CLI Protokolle erfolgreicher und fehlerhafter Ausführungen vergleichen, um die Ursache zu ermitteln.\n\nIn diesem Beispiel verwendet der zu testende Code einen Hintergrundauftrag in `order_service.py`, um den Status einer Bestellung asynchron zu aktualisieren, und eine Überprüfung in `test_order_service.py` bestätigt, dass der endgültige Status `\"processed\"` ist.\n\n### Beispielaufforderung für Rennbedingungen\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### Beispielantwort für Rennbedingungen\n\n> \\[!NOTE] Die folgende Antwort ist ein Beispiel. Da die Copilot Chat-Antworten nicht deterministisch sind, erhältst du möglicherweise eine andere Antwort als die hier beschriebene.\n\nCopilot CLI verwendet den GitHub-MCP-Server, um die neuesten Workflow-Ausführungen auf dem aktuellen Branch aufzulisten, identifiziert eine erfolgreiche und eine fehlgeschlagene Ausführung und ruft die Protokolle für beide ab. Es vergleicht sie:\n\n**Erfolgreicher Durchlauf:**\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**Fehler beim Ausführen:**\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 stellt fest, dass im erfolgreichen Durchlauf der Hintergrundauftrag vor der Statusüberprüfung beendet wurde, während im fehlgeschlagenen Durchlauf der Status überprüft wurde, als der Auftrag noch lief. Dies wird als **Rennbedingung** identifiziert, da der Test nicht auf den Abschluss des Hintergrundauftrags wartet.\n\nCopilot CLI empfiehlt, vor der Prüfung einen expliziten Wartemechanismus hinzuzufügen, und schlägt eine Lösung mithilfe eines Polling-Helfers vor:\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## Weiterführende Lektüre\n\n* *\n\n[GitHub Copilot CLI](/de/copilot/how-tos/copilot-cli)"}