Как делают софт и карьера Разработка: ветки, код-ревью, стандарты и Definition of Done
0%

Разработка: ветки, код-ревью, стандарты и Definition of Done

Разработка: ветки, код-ревью, стандарты и Definition of Done

На собеседовании вас спросят про алгоритмы. На работе 80% времени вы будете заниматься другим: читать чужой код, выяснять, что имелось в виду в задаче, ждать CI, объяснять в комментариях к PR, почему вы сделали именно так, и переделывать после ревью.

Исследования подтверждают ощущение: разработчики тратят на понимание существующего кода примерно 58% рабочего времени — это данные Xin Xia и соавторов, «Measuring Program Comprehension: A Large-Scale Field Study with Professionals» (IEEE TSE, 2018, препринт). Написание нового кода — далеко не самая объёмная часть работы.

Поэтому этап «разработка» в SDLC — это не «сесть и накодить». Это конвейер с чёткими правилами: как задача попадает к вам, где вы её делаете, кто и как проверяет результат, что автоматически проверяет робот и в какой момент можно честно сказать «готово». Разберём весь конвейер.

Если вы ещё не читали, откуда берутся задачи, — начните с Требования и аналитика и Проектирование. Здесь мы стартуем с момента, когда задача уже лежит в трекере и на ней ваше имя.

Единица работы — не строка кода, а изменение, доехавшее до пользователя

Первое, что ломает мышление вчерашнего студента: код, который «работает у меня локально», не имеет ценности. Ноль. Ценность появляется, когда изменение прошло ревью, слилось в основную ветку, проехало через тесты, попало в релиз и не сломало продакшн.

Из этого следует практическое правило, которое отличает джуна от мидла: джун оптимизирует скорость написания кода, мидл оптимизирует скорость прохождения кода через весь конвейер. Написать за час фичу, которая потом три дня висит на ревью из-за размера, — это медленнее, чем писать её полтора дня и вливать по кусочкам.

Метрика, которую отслеживают зрелые команды, называется lead time for changes — время от первого коммита до работающего в проде изменения. Она входит в четвёрку DORA-метрик (dora.dev/guides/dora-metrics-four-keys), и почти всё, о чём эта статья, влияет именно на неё.

Жизненный цикл задачи: что означают колонки в трекере

Статусы в Jira/YouTrack/Linear выглядят как бюрократия, пока не поймёшь, что это протокол синхронизации. Колонка отвечает на вопрос «кто сейчас должен что-то сделать и чего ждёт задача».

Что здесь важно понять честно:

  • Точный набор колонок у каждой команды свой. В стартапе бывает три статуса, в банке — двенадцать, включая «На согласовании ИБ» и «Ожидает окна релиза». Ни то ни другое не «правильно»: количество статусов отражает количество реальных передач ответственности между людьми.
  • Возвраты назад — норма, а не позор. Стрелки Review → In Progress и Testing → In Progress срабатывают постоянно. Плохо не то, что задача вернулась, а то, что она возвращается по одной и той же причине пятый раз подряд.
  • Blocked — самый недооценённый статус. Джуны боятся его ставить, потому что кажется, будто это признание в беспомощности. На самом деле незаявленный блокер — это дни простоя, о которых никто не знает. Правило: если вы застряли дольше, чем на 60–90 минут, и не сдвинулись, вы обязаны об этом сказать.
  • Восемь задач в «In Progress» у одного человека — это ноль сделанных задач. Про WIP-лимиты и почему поток важнее загрузки подробно в треке project-management; здесь достаточно запомнить, что переключение контекста стоит дороже, чем кажется.

Что сделать до того, как открыть редактор

Пять минут здесь экономят два дня потом:

  1. Прочитать задачу целиком, включая комментарии — там часто спрятано «мы передумали».
  2. Найти критерии приёмки. Если их нет — сходить к автору задачи и получить их текстом в тикете. Не в личке, не голосом: текстом в тикете, потому что через месяц спор о том, что имелось в виду, разрешать будет нечем.
  3. Посмотреть, кто последний трогал этот код (git log -p --follow <файл>, git blame) — это ваш будущий ревьюер и источник контекста.
  4. Прикинуть размер. Если задача разваливается на 800 строк изменений — резать на части до начала работы, а не после.
  5. Уточнить нефункциональные ожидания: нагрузка, обратная совместимость API, миграция данных. Это то, что джуны забывают, а на ревью потом всплывает как «а ты подумал про старых клиентов?».

Ветки: как несколько человек пишут в один репозиторий

Ветка в Git — это не «копия проекта», а всего лишь подвижный указатель на коммит. Именно поэтому создать ветку стоит наносекунды, а слить две сильно разошедшиеся ветки — иногда день.

Две базовых философии

Trunk-based development. Одна главная ветка, ветки живут часы или максимум пару дней, всё сливается в trunk постоянно, незаконченные фичи прячутся за feature flags. Каноническое описание — trunkbaseddevelopment.com. Это подход команд, которые деплоят несколько раз в день.

GitFlow. Долгоживущие ветки develop, release/*, hotfix/*, feature/*, релиз собирается из отдельной release-ветки. Автор модели Vincent Driessen в 2010 году описал её в посте «A successful Git branching model», и десять лет спустя добавил туда честное примечание: если вы делаете веб-приложение с непрерывной поставкой, вам, скорее всего, нужен не GitFlow, а что-то попроще. Читать это примечание — обязательно, потому что половина команд тащит GitFlow по инерции.

GitHub Flow — компромисс: только main и короткие ветки под задачу, merge через pull request, деплой из main. Это то, что вы, вероятнее всего, встретите на первой работе.

Как выбирают на практике

Условие Скорее trunk-based / GitHub Flow Скорее GitFlow / release-ветки
Частота релизов несколько раз в день раз в 2 недели и реже
Кому поставляем своему SaaS коробка, мобильные сторы, on-premise у клиента
Нужно ли поддерживать старые версии нет да, 1.4 и 1.5 одновременно живут у разных клиентов
Есть ли регламент релизного окна нет да, релиз согласуют с ИБ, ЦОД, бизнесом
Зрелость автотестов высокая, CI ловит регресс ручной регресс на стенде занимает неделю

Мобильная разработка почти всегда ближе к release-веткам просто потому, что ревью в App Store занимает время и откатить релиз мгновенно нельзя. Банковский монолит с релизом раз в месяц — тоже. Это не отсталость, это следствие цены ошибки. Подробнее контраст разобран в Энтерпрайз изнутри и Стартап изнутри.

Почему долгие ветки — это дорого

Расхождение ветки с main: короткая против долгоживущей

Стоимость слияния растёт нелинейно от времени жизни ветки. За три недели в main успевает приехать рефакторинг, переименование модулей и обновление библиотеки — и ваш идеальный код конфликтует со всем сразу. Хуже конфликта только семантический конфликт: Git слил файлы без единого маркера <<<<<<<, всё собралось, а логика сломалась, потому что коллега поменял контракт функции, которую вы вызываете.

Практика, которая спасает: git fetch && git rebase origin/main (или merge из main) хотя бы раз в день. Разбирать конфликт из одного дня расхождения — 10 минут. Из трёх недель — рабочий день и высокая вероятность, что вы что-то потеряете при разрешении.

Feature flags: как вливать незаконченное

Классический ответ на «фича готова только наполовину, но я не хочу держать ветку»: влить код в main, но выключить его флагом.

// Флаг читается из конфигурации/сервиса фич-флагов на каждом запросе,
// а не один раз при старте — иначе выключить его в инциденте можно
// будет только перезапуском сервиса.
if flags.Enabled(ctx, "checkout.new_pricing", user) {
    return newPricing(ctx, cart)
}
return legacyPricing(ctx, cart)

Плюсы очевидны: маленькие PR, непрерывная интеграция, возможность включить фичу на 5% пользователей и мгновенно выключить при инциденте (это уже про релиз и эксплуатацию).

Честная цена: каждый флаг — это ветвление логики, то есть удвоение числа состояний системы и тестовых сценариев. Флаги обязаны иметь владельца и дату удаления, иначе через год у вас двести мёртвых флагов, и никто не знает, что будет, если тронуть любой из них. Хорошее описание техники и её издержек — у Мартина Фаулера, «Feature Toggles».

Гигиена коммитов и веток

  • Имя ветки содержит ключ задачи: feature/AB-142-checkout-discounts. Автоматика в трекере связывает ветку с тикетом, а через полгода в git log понятно, зачем это делалось.
  • Сообщение коммита объясняет «зачем», а не «что» — «что» видно в диффе. Плохо: fix. Хорошо: fix(checkout): не применять скидку дважды при повторной отправке формы. Формат из примера — Conventional Commits, на нём часто строится автогенерация changelog и версионирование. Классика жанра про сообщения — «How to Write a Git Commit Message».
  • Rebase против merge — тема священных войн. Практический минимум: не переписывайте историю ветки, которую кто-то уже забрал себе; git push --force-with-lease вместо --force; в общую ветку force-push не делают никогда. Часто команда просто включает squash merge — тогда вся ветка становится одним коммитом в main и спор исчезает.
  • Секреты в репозитории. Закоммиченный токен считается скомпрометированным навсегда, даже если вы удалили его следующим коммитом: он остался в истории и в чужих клонах. Правильная реакция — сразу отозвать ключ, а не пытаться «почистить». Для профилактики ставят gitleaks или аналог в CI.

Код-ревью: главный обучающий механизм в команде

Зачем это делают на самом деле

Ловля багов — не главная цель, хотя она и работает. Основное — это:

  • распространение знаний: после ревью код знают минимум два человека, bus factor растёт;
  • читаемость: код пишут один раз, читают сто, и ревью — единственный момент, когда «непонятно» можно сказать вовремя;
  • соответствие принятым решениям: архитектурным договорённостям, ADR, стандартам;
  • обучение: для джуна ревью — это персональный курс от команды, самый быстрый канал роста;
  • разделённая ответственность: после апрува это уже не «твой код», а код команды.

Самое полезное чтение по теме — работа Google «Modern Code Review: A Case Study at Google» (Sadowski et al., ICSE-SEIP 2018, research.google/pubs/pub47025): там честно показано, что основная польза ревью в масштабе — образовательная и нормативная, а не «поиск дефектов». Практическая часть, которую стоит прочитать целиком, — открытый Google Engineering Practices / Code Review.

Размер PR решает всё

Как размер pull request влияет на качество ревью

Внимание ревьюера — исчерпаемый ресурс. На 50 строках человек читает каждую. На 1500 строках он листает, ищет что-нибудь очевидное, не находит и ставит апрув — это называется rubber stamping, и это худший вид ревью: он создаёт иллюзию проверки. Практическая эвристика большинства инженерных руководств — держаться в районе двух-трёх сотен строк изменений на PR и разбивать большее на серию.

Как резать большую задачу:

  1. Сначала отдельным PR — рефакторинг без изменения поведения (его читать легко).
  2. Потом — миграция схемы БД, обратно совместимая, без использования новых полей.
  3. Потом — новая логика за выключенным флагом.
  4. Потом — включение флага и удаление старой ветки кода.

Да, это четыре PR вместо одного и четыре круга ревью. И это всё равно быстрее, чем один разговор на неделю вокруг простыни в 1200 строк.

Как автору не бесить ревьюера

  • Сделайте self-review. Откройте свой же дифф в интерфейсе PR и прочитайте как чужой. Половина замечаний ловится здесь: забытый console.log, закомментированный код, случайно переформатированный файл.
  • Напишите описание. Не «делает то, что в задаче». Что менялось, почему выбран этот подход, какие альтернативы отброшены, как это проверить руками, что осталось за скобками. Хорошее описание PR экономит ревьюеру полчаса разбирательств.
  • Не смешивайте. Функциональное изменение + переформатирование всего файла = дифф, в котором ничего не видно. Форматирование отдельным коммитом или отдельным PR.
  • Отвечайте на каждый комментарий. Либо правкой, либо аргументом, либо «согласен, вынес в отдельную задачу AB-157». Молча закрыть тред — верный способ поссориться.
  • Не воспринимайте замечания как оценку личности. Это единственный по-настоящему сложный навык из списка, и он тренируется только практикой.

Как ревьюеру не быть узким местом

Скорость важнее глубины. PR, лежащий сутки, — это сутки простоя автора и растущий дрейф ветки. Нормальная договорённость: первый ответ в течение нескольких часов рабочего дня, даже если это «посмотрю после обеда, вот беглые мысли». В Google-руководстве прямо написано: если вы не можете посмотреть внимательно сейчас — дайте хотя бы быстрый отклик.

Помечайте уровень замечания. Это одна из самых дешёвых и самых полезных практик:

  • blocking: — так мержить нельзя (утечка данных, гонка, сломанная обратная совместимость);
  • question: — я не понял, объясните, возможно, всё в порядке;
  • suggestion: — было бы лучше вот так, но решать вам;
  • nit: — придирка по вкусу, не блокирует.

Без такой маркировки автор не понимает, что обязательно, а что вкусовщина, и либо переделывает всё подряд, либо игнорирует важное.

Комментируйте код, а не человека. Разница не в вежливости ради вежливости, а в том, что формулировка определяет, будет ли обсуждение продуктивным.

Плохо Хорошо
«Ты опять не подумал про конкурентность» «Если два запроса придут одновременно, здесь возможна двойная запись — стоит взять блокировку или уникальный индекс»
«Перепиши это нормально» «Функция делает три вещи сразу; если вынести валидацию отдельно, её можно будет протестировать без БД»
«Так не пишут» «У нас в проекте принято возвращать ошибку, а не паниковать — см. internal/errors/README.md»
«Зачем ты это сделал?» «question: почему здесь мапа, а не слайс? Может, я упускаю сценарий»

Не превращайте ревью в дедовщину. Симптомы, при которых процесс сломан: ревьюер требует переписать по своему вкусу без аргумента; замечания приходят порциями по одному в день; джуну возвращают PR восемь раз подряд с новыми претензиями. Если спор зашёл в тупик — правило простое: обсуждение переезжает в голосовой звонок на 10 минут, а итог записывается в тред PR текстом. Тексты в комментариях плохо передают тон, и половина конфликтов на ревью — это конфликт интонации, а не техники.

Кто ревьюит. В зрелых репозиториях есть файл CODEOWNERS: он автоматически назначает владельцев конкретных каталогов. Обязательный апрув владельца критичного модуля — нормальная практика; требование двух апрувов на всё подряд обычно означает, что процесс не доверяет людям и просто удваивает задержку.

Когда ревью — не лучший инструмент

Ревью асинхронно, а значит, у него есть задержка. Иногда дешевле:

  • парное программирование для сложной или незнакомой области — ревью происходит в реальном времени, отдельный PR-ревью потом можно сделать формальным;
  • разговор до написания кода — обсудить подход на 15 минут, чтобы не выяснять на ревью, что вся структура выбрана неверно (это, по сути, продолжение проектирования);
  • прототип на выброс, который никто не ревьюит, потому что он будет удалён.

Стандарты кода: спор, который нужно автоматизировать

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

Слои автоматических проверок

Ключевая мысль диаграммы: человек включается последним и смотрит только то, что машина проверить не может — правильность решения, читаемость замысла, соответствие требованиям.

Из чего это состоит на практике

  • Форматтер — не обсуждается и не настраивается: gofmt, prettier, black/ruff format, dotnet format, mix format. Go в этом смысле выиграл спор радикально: формат один на всю экосистему.
  • Линтер и статический анализgolangci-lint, eslint, ruff, аналайзеры Roslyn, credo. Ловят реальные классы ошибок: неиспользуемое, затенённые переменные, потерянные ошибки, подозрительные приведения типов.
  • Типы — строгий режим TypeScript, mypy/pyright, nullable reference types в C#. Самый дешёвый способ убрать целый класс замечаний с ревью.
  • Тесты и покрытие — подробно в следующей статье трека.
  • Проверка зависимостейnpm audit, govulncheck, Dependabot/Renovate.
  • Соглашения о коммитах и PR — commitlint, шаблон описания PR в .github/pull_request_template.md.

Минимальный, но честный пример пайплайна:

# .github/workflows/ci.yml — то, что должно быть в любом репозитории с первого дня
name: CI
on:
  pull_request:
  push:
    branches: [main]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: "1.23"

      # Форматирование: не «замечание на ревью», а падение сборки
      - name: Проверка форматирования
        run: test -z "$(gofmt -l .)"

      - name: Линтеры
        uses: golangci/golangci-lint-action@v6

      # -race ловит гонки, которые на ревью глазами не находят почти никогда
      - name: Тесты
        run: go test -race -coverprofile=coverage.out ./...

      - name: Известные уязвимости в зависимостях
        run: go run golang.org/x/vuln/cmd/govulncheck@latest ./...

Про pre-commit хуки честно. Они удобны, но на них нельзя строить гарантии: хук живёт на машине разработчика, его можно не установить и обойти через --no-verify. Хук — это про быстрый отклик, CI — про гарантию. Нужны оба, но источник истины один: CI.

Как жить со стандартами в легаси

Включить строгий линтер на проекте с историей в семь лет — значит получить 40 000 замечаний и заблокировать команду. Работающий подход:

  1. Зафиксировать baseline: текущие нарушения записываются в файл исключений и не считаются ошибкой (golangci-lint с new-from-rev, eslint с --cache, ruff с # noqa по списку).
  2. Новые и изменённые файлы проверяются строго. Правило «boy scout rule»: тронул файл — оставил чуть чище.
  3. Постепенно выпиливать исключения отдельными задачами в рамках работы с техническим долгом.

Хорошие открытые ориентиры по стилю, если своего гайда нет: Google Style Guides, Go Code Review Comments, Effective Go.

Definition of Done: договор о слове «готово»

Классический диалог на дейли:

— Задача готова? — Да, код написан. — А тесты? — Ну, тестов нет. — А на стенде проверял? — Нет, локально работает.

Definition of Done — это письменное соглашение команды, которое делает такой диалог невозможным. Термин пришёл из Scrum (см. Scrum Guide и трек scrum-master), но полезен в любом процессе, включая канбан и «у нас нет процесса».

Не путайте три разные вещи:

Что Про что Кто владеет Пример
Definition of Ready когда задачу можно брать в работу команда + аналитик/PO есть критерии приёмки, оценка, нет неизвестных блокеров
Acceptance criteria что именно должна делать эта задача автор задачи «при повторной отправке формы скидка не применяется дважды»
Definition of Done качественная планка для любой задачи команда тесты, ревью, документация, мониторинг

Критерии приёмки уникальны для задачи, DoD одинаков для всех задач. Их регулярно путают, и тогда в DoD пытаются писать функциональные требования.

Как выглядит рабочий DoD

Реальный пример DoD небольшой продуктовой команды — восемь пунктов, которые помещаются в закреплённое сообщение в чате:

Задача считается Done, если:
1. Код слит в main, ветка удалена.
2. CI зелёный: сборка, линтеры, юнит- и интеграционные тесты.
3. PR апрувнут минимум одним человеком, не автором; для платежей — владельцем модуля.
4. Новая логика покрыта тестами; на исправленный баг есть тест, падавший до фикса.
5. Проверено на staging по критериям приёмки из задачи.
6. Обновлены: миграции, конфиги, README/ADR, если менялись контракты.
7. Добавлены метрика и лог, по которым можно понять, что фича работает в проде.
8. Тикет переведён в нужный статус, в комментарии — что и как проверять.

Антипаттерны DoD

  • DoD как декларация. Написали на воркшопе, повесили в Confluence, никогда не открывали. DoD живёт только если он встроен в чеклист PR и/или в правила CI.
  • DoD из тридцати пунктов. Никто не читает. Лучше семь выполняемых, чем тридцать игнорируемых.
  • DoD, спущенный сверху. Планку качества, в которую команда не верит, команда обойдёт. Это соглашение, а не приказ; менеджер может настаивать на наличии DoD, но не диктовать его.
  • «Done-done». Если в команде появились градации «сделано» и «сделано по-настоящему», — значит, DoD не работает и его надо переписать под реальность.
  • DoD, игнорирующий эксплуатацию. Самый частый пропуск у команд без дежурств: нет пунктов про логи, метрики и алерты — а потом в проде фича молча не работает три недели.

DoD должен эволюционировать. Появились дежурства — добавили пункт про алерты. Появился внешний API — добавили пункт про версионирование контракта. Ревизия на ретроспективе раз в квартал — хороший ритм.

Кто с кем взаимодействует на этапе разработки

Честная поправка: этой схемы целиком у вас может не быть. В маленькой команде нет отдельного тестировщика — тогда его роль исполняют автотесты плюс перекрёстная проверка коллегой, и пункт «проверил на стенде» в DoD становится критичным. В большом энтерпрайзе, наоборот, между разработчиком и продом появятся ещё согласование ИБ, ревью архитектурного комитета и релизное окно. Кто за что отвечает в разных конфигурациях — в статье Кто есть кто в команде.

Жизненный цикл бага: почему он отличается от задачи

Три вещи, которые отличают работу с багом от работы с фичей:

  1. Сначала воспроизведение, потом код. «Кажется, я понял, в чём дело» без воспроизведения — это лотерея. Не воспроизвели — не сможете доказать, что починили.
  2. Тест, падающий до фикса. Это единственная гарантия, что вы починили именно то и что оно не вернётся. Если тест зелёный и до вашей правки — вы чинили не то.
  3. Severity ≠ priority. Severity — насколько страшно техническое последствие. Priority — насколько срочно бизнесу. Опечатка на главной странице лендинга имеет низкий severity и высокий priority. Падение фоновой джобы, о которой никто не знает, — наоборот.

Энтерпрайз и стартап: одна и та же работа, разные настройки

Аспект Крупная компания Стартап / небольшая команда
Ветвление release-ветки, окна релизов, иногда монорепо со сложными правилами trunk-based, деплой из main по мержу
Ревью обязательно, часто 2+ апрува, CODEOWNERS, регламент SLA обязательно, но 1 апрув; иногда «после факта» на мелочах
Стандарты общекорпоративный гайд, платформенная команда, готовые шаблоны CI что успели настроить; часто линтера нет, и это ваша возможность его принести
DoD формализован, привязан к аудиту, есть обязательные согласования договорённость в чате, меняется на ходу
Скорость изменение до прода — недели часы
Что вы получаете масштаб, сложные системы, культура процесса, наставники широта задач, влияние на продукт, скорость обратной связи
Чего лишаетесь скорости и ощущения влияния страховки: некому подсказать, легко закрепить плохие привычки

Ни одна колонка не «правильнее». Для первой работы важнее не тип компании, а наличие людей, которые будут читать ваш код и объяснять замечания. Один вдумчивый ревьюер даёт больше роста за полгода, чем два года самостоятельного написания кода без обратной связи. Как это влияет на грейд — в статье Грейды.

Типичные ошибки на этапе разработки

Список составлен из того, что реально всплывает на ревью у начинающих:

  1. Начать кодить, не поняв задачу. Два дня работы в мусор, потому что имелось в виду другое.
  2. Молча застрять. Полтора дня на проблеме, которую коллега решил бы за пять минут. Правильная форма вопроса: что делаю, что пробовал, что ожидал, что получил.
  3. Огромный PR. «Заодно отрефакторил» — самая дорогая фраза в код-ревью.
  4. Отсутствие тестов «потому что некогда». Работает ровно до первого регресса, после которого выясняется, что времени ушло больше.
  5. Спор о вкусовщине на ревью. Стиль автоматизируют, а не обсуждают.
  6. Игнор комментариев ревьюера. Молча закрытый тред читается как неуважение.
  7. Коммит секретов, .env и артефактов сборки. Проверьте .gitignore до первого коммита.
  8. Локальная правка прямо в main. Даже если «на минутку».
  9. Правка бага без воспроизведения. Вы не знаете, починили ли вы что-нибудь.
  10. «Готово» без проверки на стенде. Локальное окружение отличается от тестового всегда.
  11. Забытые логи и метрики. В проде фича молча не работает, и узнаете вы об этом от клиента.
  12. Долгоживущая ветка «пока не доделаю». Возвращаемся к картинке с дрейфом.

Мини-итог

  • Работа на этапе разработки — это конвейер от тикета до прода, и оптимизировать надо скорость всего конвейера, а не скорость набора кода.
  • Ветки должны быть короткими; долгая ветка платит нелинейно растущим налогом на слияние. Незаконченное вливают за feature flag, а флаги обязаны иметь владельца и срок жизни.
  • Стратегия ветвления вытекает из частоты релизов и цены ошибки, а не из моды.
  • Код-ревью — прежде всего механизм распространения знаний. Держите PR маленькими, помечайте уровень замечаний, комментируйте код, а не человека, и отвечайте быстро.
  • Всё, что может проверить машина, должна проверять машина: форматтер, линтер, типы, тесты, аудит зависимостей — в CI, а не в комментариях к PR.
  • Definition of Done — командное соглашение из 5–8 выполнимых пунктов, включающее эксплуатацию (логи, метрики), а не только «код написан».
  • Баг требует воспроизведения и падающего теста; severity и priority — разные вещи.

Что почитать

Что дальше

Мы довели изменение до слияния в main и договорились, что считать сделанным. Теперь разберёмся, как это изменение проверяют: какие бывают уровни тестов, что из этого пишет сам разработчик, как выглядит приёмка и что делать, когда тестировщика в команде нет.

Тестирование и приёмка глазами разработчика

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов