Skip to main content

Диагностика сбоев тестов CI

Используйте Второй пилот CLI для извлечения CI-логов, сопоставления сбоев с локальным кодом и устранения проблем без выхода из терминала.

Второй пилот CLI поставляется вместе с GitHub MCP сервером, который даёт ему прямой доступ к вашим GitHub Actions рабочим процессам, журналам заданий и статусам проверок. В сочетании с доступом к вашим локальным файлам он может получать детали отказа CI, сопоставлять их с вашим кодом и предлагать исправления с терминала.

Пример сценария 1: тесты проходят локально, но не проходят CI

У вас есть тест, который проходит на вашем локальном компьютере, но проваливается в CI. Вы можете попросить Второй пилот CLI расследовать этот провал теста напрямую.

В этом примере тестируемый код определяет простой сервис заказов (order.py), и есть соответствующий тест, который проверяет, был ли заказ создан сегодня (test_order_service.py).

Пример запроса

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

Пример ответа

Примечание.

Следующий ответ является примером. Ответы Копилот Чат являются недетерминированными, поэтому вы можете получить другой ответ, показанный здесь.

Второй пилот CLI использует GitHub MCP-сервер для загрузки последнего текущего рабочего процесса, выявления неудачного задания и получения её логов. В нём обнаружена следующая ошибка:

___ 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

После прочтения обоих локальных файлов он Второй пилот CLI замечает, что даты ровно в один день и определяет это как проблему с границей часового пояса. CI-runner использует UTC, а ваш локальный компьютер — другой часовой пояс. Когда тест проходит около полуночи, date.today() в каждой среде появляются разные даты.

Второй пилот CLI предлагает стандартизировать вычисления today путём внедрения зависимости от часового сигнала или закрепления часового пояса:

from datetime import timezone, datetime

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

Исправление применяется к обоим order.py и test_order_service.py, обновляя все ссылки для использования нового get_today() помощника.

После исправления вы можете проверить изменения и провести тесты локально:

  1. Беги /diff проверить, что Второй пилот CLI именно изменилось.
  2. Проведите !pytest test_order_service.py проверку, чтобы убедиться, что тесты проходят локально.
  3. Нажми на исправление и дай CI перезапуститься.

Пример сценария 2: Периодические неудачи испытаний в условиях гонки

Тест иногда проходит, а иногда проваливается на одной и той же машине. Вам нужно Второй пилот CLI сравнивать логи прохождения и неудачных забегов, чтобы определить причину.

В этом примере тестируемый код использует фоновую задачу в order_service.py для асинхронного обновления статуса заказа, а тест в test_order_service.py утверждает, что итоговый статус — "processed".

Пример запроса для условий гонки

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

Пример реакции для гоночных условий

Примечание.

Следующий ответ является примером. Ответы Копилот Чат являются недетерминированными, поэтому вы можете получить другой ответ, показанный здесь.

Второй пилот CLI использует GitHub MCP-сервер для перечисления недавних рабочих процессов на текущей ветке, определяет один проходящий и один неудачный запуск, а также получает логи для обоих. Они сравниваются:

Пасовый пробег:

[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

Неудачный забег:

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

Второй пилот CLI Обнаруживает, что при проходном запуске фоновая задача выполнена до проверки статуса, а в неудачном запуске статус был проверен, пока работа всё ещё работала. Он определяет это как гоночное условие , потому что тест не ждёт завершения фонового задания.

Второй пилот CLI предлагает добавить явный механизм ожидания перед утверждением и предлагает исправление с помощью помощника по опросу:

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"
    )

Дополнительные материалы

GitHub Copilot CLI