{"meta":{"title":"CI 테스트 실패 진단","intro":"CI 로그를 끌어오고, 오류를 로컬 코드와 상호 연결하고, 터미널을 떠나지 않고 문제를 해결하는 데 사용합니다 Copilot CLI .","product":"GitHub Copilot","breadcrumbs":[{"href":"/ko/copilot","title":"GitHub Copilot"},{"href":"/ko/copilot/tutorials","title":"자습서"},{"href":"/ko/copilot/tutorials/copilot-cookbook","title":"GitHub Copilot 활용 안내서"},{"href":"/ko/copilot/tutorials/copilot-cookbook/debug-errors","title":"오류 디버깅"},{"href":"/ko/copilot/tutorials/copilot-cookbook/debug-errors/diagnose-ci-test-failures","title":"CI 테스트 실패 진단"}],"documentType":"article"},"body":"# CI 테스트 실패 진단\n\nCI 로그를 끌어오고, 오류를 로컬 코드와 상호 연결하고, 터미널을 떠나지 않고 문제를 해결하는 데 사용합니다 Copilot CLI .\n\nCopilot CLI GitHub MCP 서버와 함께 제공되므로 GitHub Actions 워크플로 실행, 작업 로그 및 상태 확인에 직접 액세스할 수 있습니다. 로컬 파일에 대한 액세스와 결합하면 CI 오류 세부 정보를 가져오고 코드와 상관 관계를 지정하며 터미널에서 수정 사항을 제안할 수 있습니다.\n\n## 예제 시나리오 1: 테스트가 로컬로 통과하지만 CI에서 실패\n\n로컬 머신을 통과하지만 CI에서 실패하는 테스트가 있습니다. 이 테스트 실패를 직접 조사하도록 요청할 Copilot CLI 수 있습니다.\n\n이 예제에서 테스트 중인 코드는 단순 주문 서비스(`order.py`)를 정의하며, 현재(`test_order_service.py`)에 주문이 만들어졌는지 확인하는 해당 테스트가 있습니다.\n\n### 예제 프롬프트\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### 응답 예제\n\n> \\[!NOTE] 다음 응답이 예제입니다. Copilot Chat 응답은 비결정적이므로 여기에 표시된 응답과 다른 응답을 얻을 수 있습니다.\n\nCopilot CLI GitHub MCP 서버를 사용하여 현재 분기에서 최신 워크플로 실행을 가져오고, 실패한 작업을 식별하고, 로그를 검색합니다. 다음과 같은 오류가 발생합니다.\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\n두 로컬 파일을 Copilot CLI 모두 읽은 후 날짜가 정확히 하루 떨어져 있음을 확인하고 이를 **표준 시간대 경계 문제로** 식별합니다. CI 실행기는 UTC를 사용하는 반면 로컬 머신은 다른 표준 시간대를 사용합니다. 테스트가 자정 `date.today()` 에 가까워지면 각 환경에서 서로 다른 날짜를 반환합니다.\n\nCopilot CLI 는 클록 종속성을 주입하거나 표준 시간대를 고정하여 계산 방법을 `today` 표준화할 것을 제안합니다.\n\n```python\nfrom datetime import timezone, datetime\n\ndef get_today():\n    return datetime.now(timezone.utc).date()\n```\n\n수정 사항을 `order.py`와 `test_order_service.py` 모두에 적용하고, 모든 참조가 새 `get_today()` 도우미를 사용하도록 업데이트합니다.\n\n수정 후 변경 내용을 확인하고 로컬로 테스트를 실행할 수 있습니다.\n\n1. `/diff`을 실행하여 Copilot CLI에서 정확히 무엇이 변경되었는지 검토합니다.\n2. 테스트를 로컬로 통과하는지 확인하려면 실행 `!pytest test_order_service.py` 합니다.\n3. 수정 사항을 푸시하고 CI를 다시 실행하도록 허용합니다.\n\n## 예제 시나리오 2: 경합 조건으로 인한 간헐적인 테스트 실패\n\n테스트는 때때로 통과하고 때로는 동일한 컴퓨터에서 실패합니다.\nCopilot CLI 실행 통과 및 실패에서 로그를 비교하여 원인을 파악하려고 합니다.\n\n이 예제에서 테스트 중인 코드는 백그라운드 작업을 `order_service.py` 사용하여 주문의 상태를 비동기적으로 업데이트하고, `test_order_service.py` 테스트에서 최종 상태가 `\"processed\"` 인지 확인합니다.\n\n### 경합 조건에 대한 프롬프트 예제\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### 경합 조건에 대한 응답 예제\n\n> \\[!NOTE] 다음 응답이 예제입니다. Copilot Chat 응답은 비결정적이므로 여기에 표시된 응답과 다른 응답을 얻을 수 있습니다.\n\nCopilot CLI GitHub MCP 서버를 사용하여 현재 분기의 최근 워크플로 실행을 나열하고, 한 번의 통과 및 실패 실행을 식별하고, 두 가지 모두에 대한 로그를 검색합니다. 다음을 비교합니다.\n\n**통과한 실행:**\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**실행 실패:**\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 는 전달 실행에서 백그라운드 작업이 상태 확인 전에 완료된 것을 표시하고, 실패한 실행에서는 작업이 실행되는 동안 상태를 확인했습니다. 테스트가 백그라운드 작업이 완료되기를 기다리지 않기 때문에 이를 **경합 상태로** 식별합니다.\n\nCopilot CLI는 검증하기 전에 명시적 대기 메커니즘을 추가할 것을 제안하고, 폴링 도우미를 사용한 수정 방안을 제시합니다.\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## 추가 읽기\n\n* *\n\n[GitHub Copilot CLI](/ko/copilot/how-tos/copilot-cli)"}