← Вайбкодинг · Вайбкодинг с OpenCode EN FR Курс 30/70 →

Модуль 04 — Практика: TDD-цикл с агентом

Время: 210 минут · Артефакт: labs/04-oracles/


Задание 1. Одна команда проверки (30 мин)

Соберите scripts/check.sh (или make check):

#!/usr/bin/env bash
set -e
ruff check . --output-format=concise
mypy . --no-error-summary
pytest -q

Добавьте в AGENTS.md:

## Проверка
- всё: `./scripts/check.sh`
- если упало: исправляйте причину, не отключайте проверку

Приёмка: ./scripts/check.sh проходит на чистом проекте за < 60 сек.


Задание 2. Падающий тест → рабочий код (50 мин)

  1. Выберите функцию, которой ещё нет: normalize_phone(s: str) -> str.
  2. Сами напишите тесты (5 кейсов, включая граничные):
def test_normalize_phone():
    assert normalize_phone("+7 (912) 345-67-89") == "+79123456789"
    assert normalize_phone("89123456789") == "+79123456789"
    assert normalize_phone("") == ""
    assert normalize_phone("abc") == ""
    assert normalize_phone("+1 222 333") == "+1222333"
  1. Убедитесь, что тесты падают (ImportError — тоже падение).
  2. Дайте агенту:
Тесты в tests/test_phone.py падают. Реализуй normalize_phone в src/utils/phone.py.
Минимальный код, проходящий все тесты. Не меняй тесты.

Приёмка: тесты зелёные, тесты не изменены (git diff tests/ пустой).


Задание 3. Агент пишет тесты по вашему списку (40 мин)

Возьмите существующую функцию без покрытия. Составьте список кейсов сами:

- вход None
- пустой список
- отрицательные числа
- дубликаты
- очень большое число

Затем:

Напиши тесты для src/x.py::func по списку кейсов ниже. Тесты должны падать,
если поведение изменится. Не используй моки без необходимости.

Приёмка: тесты действительно ловят мутацию — измените одну строку кода, убедитесь, что тест падает, верните обратно.


Задание 4. Цикл «ошибка → фикс» (40 мин)

Сломайте код намеренно (например, поменяйте условие). Запустите проверку и передайте агенту полный вывод:

./scripts/check.sh падает. Вот вывод:

<вставить целиком>

Найди причину и исправь. Объясни в двух строках, что было не так.

Повторите 2 раза с разными поломками.

Приёмка: в отчёте — вывод ошибки, дифф фикса, объяснение. Отметьте: помогал ли полный вывод по сравнению с пересказом.


Задание 5. Golden-тест (50 мин)

Для функции, генерирующей текст/JSON/отчёт:

  1. Создайте эталон tests/golden/expected.json.
  2. Тест:
def test_report_golden():
    assert generate_report(SAMPLE_INPUT) == json.loads(
        open("tests/golden/expected.json").read()
    )
  1. Попросите агента изменить формат отчёта — golden упадёт — пусть обновит эталон осознанно.

Приёмка: в отчёте есть дифф эталона и объяснение, почему изменение корректно.


Критерии сдачи

  • check.sh работает одной командой, время < 60 сек.
  • Тесты из задания 2 не изменены, код — минимальный.
  • Есть доказательство, что тесты ловят мутацию.
  • Отчёт цикла «ошибка → фикс» с полным выводом.
  • Golden-тест + осознанное обновление эталона.