Привет, Хабр! Сегодня публикуем не совсем обычный для нас текст: решили сделать полезный гайд для новичков в код-ревью. Разобрались, кому нужна и не нужна эта практика, а еще — каких ошибок лучше избежать на старте.

Текст пригодится разработчикам и лидам, которые еще близко не знакомы с код-ревью или хотят упорядочить свои знания, узнать лайфхаки из практики. Если вы тоже захотите внести свою лепту, что-то посоветовать или рассказать историю из опыта — пишите в комментариях.

Что такое код-ревью и зачем его проводят?

Код-ревью — это процесс проверки кода, который позволяет:

  • выявить → ошибки, пропуски, уязвимости и стилистические недочеты (с точки зрения проекта или принятых в команде правил).

Пример диалога между автором и ревьюером.
Пример диалога между автором и ревьюером.
  • улучшить →

→ читаемость и понятность кода для других разработчиков.

→ архитектурные решения. Например, разбиение на модули, code style решения, неверно подобранный паттерн проектирования.

→ работу в команде. Способствует диалогу между автором кода и ревьюером, дает возможность прокачать навыки и узнать что-то новое.

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

Когда нужно и не нужно проводить код-ревью?

Системная практика оценки кода внутри команды — не всегда полезное с точки зрения затраты ресурсов решение. Оно отнимает время и у автора, и у проверяющего, а еще требует глубокого погружения в процессы и сил на коммуникацию.

Причины, чтобы отказаться от код-ревью в конкретном случае:

  • нет человека, который обладает экспертизой в области специфики задачи;

  • изменения слишком незначительны и не требуют проверки.

Причины, чтобы отказаться от постоянной практики код-ревью:

  • у всех разработчиков одинаковый уровень знаний, навыков и уровень погружения в контекст;

  • приняты другие практики проверки кода — например, парное программирование;

  • постоянные конфликты из-за код-ревью в команде;

  • практика уже показала свою неэффективность.

Как организовать процесс проверки кода?

Перед стартом

  • После выполнения задачи автор кода делает в отдельной ветке push в удаленный репозиторий и создает Merge Request (MR).

  • Назначается assignee (ответственный за MR) и reviewer (ответственный за проверку).

Ответственный за MR и ответственный за проверку.
Ответственный за MR и ответственный за проверку.
  • Затем начинается серия проверок, которая называется раундами. Цель каждой итерации — найти проблемы и недочеты, которые могут отразиться на работе проекта в будущем.

Раунды

Перед стартом ревьюер должен оценить объем MR и определить, сможет ли его проверить на «одном дыхании»‎ — не теряя концентрации. Если объем MR слишком большой, советуем разбить его на части поменьше. Чем объемнее решение, тем ниже эффективность проверки.

Заряд батарейки — количество энергии участников ревью от раунда к раунду.
Заряд батарейки — количество энергии участников ревью от раунда к раунду.

В первом раунде проверяющему важно оценить код на предмет высокоуровневых, глобальных проблем. Это, например, неверно выбранный подход к проектированию решения или разбиение на функции, отсутствие модульности.

Пример комментария.
Пример комментария.

Если таких проблем не нашлось, уровень проверки понижается до тех пор, пока не найдутся места для улучшений.

В первом раунде не стоит акцентировать внимание на мелких недочетах. Скорее всего, автор сам их обнаружит и поправит, и ревьюеру не придется тратить время на поиск незначительных проблем.

Антон Щербак, разработчик Selectel

После код возвращается автору: он вносит изменения и снова отправляет на проверку. Процесс продолжается до тех пор, пока решение не признают приемлемым — оно одобряется тем, кто проводил ревью, и после assignee выполняет merge.

«Решение не должно быть идеальным — оно должно соответствовать потребностям проекта и выполнять поставленную задачу»‎, — отмечает разработчик Антон Щербак.

Как понять, что решение готово?

→ Оно не имеет явных ошибок. 

Ревью может выявить недочеты, которые видны без запуска проекта. Обычно это:

  • опечатки;

  • ошибки, возникшие из-за недостаточного погружения в контекст проекта;

  • необновленный конфигурационный файл.

Пример комментария.
Пример комментария.

→ Соответствует стайл-гайдам, принятым в команде.

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

Если автор решения выходит за рамки принятых стайл гайдов или отклоняется от них, стоит указать ему на это.

→ Не затрагивает код, выходящий за рамки задачи. 

Решение должно быть выполнено в рамках скоупа задачи. Если разработчик заметил, что можно выполнить рефакторинг другого класса, это лучше сделать в отдельном MR. При таком подходе ревьюеру будет проще проверять выполнение исходной задачи.

→ Пропущено через линтеры, используемые в проекте.

Большинство команд в Selectel использует pre-commit — так при каждом коммите код прогоняется через линтеры. Для Python используется black, isort, flake8, pyupgrade и autoflake.

→ Обладает хорошей читаемостью и пояснением неочевидных мест.

Лучшая практика в разработке — написание самодокументируемого кода. Если по каким-то причинам ей воспользоваться не получается, советуем оставить поясняющий комментарий: он расскажет ревьюеру, что происходит в этом месте проекта. 

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

→ Если на проекте пишутся автотесты, решение должно ими покрываться.

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

→ Нет оверинжениринга (кода «на будущее»‎).

Часто код, который решает еще не возникшие проблемы, не пригождается и становится лишним.

Еще Дональд Кнут говорил: преждевременная оптимизация — корень всех проблем в программировании.

Советы по процессу

  • Договоритесь о сроках и организации процесса. Например, не отдавайте правки по одной — это отвлекает. Еще не затягивайте процесс на весь день и по возможности не переключайтесь между задачами — это время- и энергозатратно.

Хорошая практика — восприятие код-ревью как отдельной задачи без переключения на другие. Правда при условии, что у остальных дел невысокий приоритет.

  • Используйте префикс NIT (сокращение от nitpick) для комментариев, которые даны в качестве рекомендаций. Помните: они не обязательны к исполнению, автор волен сам решать, следовать им или нет.

Пример комментария.
Пример комментария.

Разработчики часто спорят о названиях переменных. Бывает, что эти нововведения никак не влияют на итоговое решение. Поэтому делать пометку в начале — нормальная практика: она говорит разработчику, что решение о внесении в код изменений остается за ним. Эти изменения не обязательны — решение и так хорошее.

Антон Щербак, разработчик Selectel

  • Помните о том, что обратная связь должна быть балансной. Ее цель — не обидеть человека, а аргументировано (например, с помощью примеров кода и ссылок на паттерны) подсветить зоны для улучшений.

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

Так не стоит комментировать → «Ты тут ошибся, поправь по моему примеру. Вот ссылка».

Так лучше → «Мы уже сталкивались с аналогичной ситуацией. Вот как эта проблема решилась тут → ссылка. Можем ли реализовать нечто подобное?»

  • Количество раундов в код-ревью не ограничено, но лучше стремиться к сокращению их количества. Каждая новая серия правок отнимает силы участников ревью и тормозит релиз.

Удобные инструменты для код-ревью

  • GitLab — используем в Selectel.

По ссылке конкретные гайдлайны, которыми пользуются в GitLab. В них описано, как построена практика код-ревью в компании.

  • GitHub. Подробнее об инструменте — по ссылке.

Больше текстов про развитие карьеры читайте в блоге Selectel. А еще подписывайтесь на наш Телеграмм-канал с вакансиями и полезными карточками про soft и hard skills.

Комментарии (15)


  1. dmitryvolochaev
    14.04.2022 17:23
    +10

    У меня вызывают сомнение некоторые из перечисленных причин отказа от ревью.

    Если ревьювер по опыту не превосходит автора, свежий взгляд все же чего-то стоит, вы не согласны? Бывают ошибки типа копипасты. Такой код компилируется. От этого только ревью спасает.

    А если отказаться от ревью из-за возможных конфликтов, то конфликт может быть после коммита.


    1. gdt
      14.04.2022 19:14
      +3

      Согласен, в целом если отсутствует ревью — говнокод это вопрос времени.


      1. Sly_tom_cat
        14.04.2022 23:12
        +2

        К сожалению, даже ревью от говнокода не спасает порой.

        Оно ведь как бывает: давай, давай быстрее, фичу клиенты толпами уже под окнами офиса ждут. И соответствующее ревью "по-диагонали"... а потом берешь этот код в работу и в офисе начинают слышаться маты.....


    1. Cerberuser
      14.04.2022 20:29
      +5

      Более того, где-то даже попадалась рекомендация периодически приглашать младших участников команды поревьювить код старших - и "свежий глаз" (у самого разработчика он всё-таки замыливается), и возможность чему-то дополнительно научиться на конкретном примере.


    1. gardiys
      15.04.2022 15:11

      Думаю, что стоит отказываться от код ревью, когда его эффективность начинает стремиться к 0. Я согласен, что возможно ревьюер, который по опыту не превосходит автора решения может найти какую то опечатку, но возможно стоит задуматься о том, что времязатраты на это не очень оправданы.

      То же самое касается и конфликтов, если они очень сильно тормозят feature delivery, тогда, кажется, стоит пересмотреть процессы в команде.


  1. Nialpe
    15.04.2022 09:37
    +1

    У нас была практика назначения нескольких ревьюверов в том числе и ниже по условному уровню - чтобы учились + свежий взгляд + нельзя сбрасывать со счетом менее опытных, иногда их идеи и видение превосходит имеющиеся решения.


    1. gardiys
      15.04.2022 15:05

      Поддерживаю такой подход, он в целом не идет в разрез с тем, что написано в статье, а даже расширяет эффективность код ревью.


  1. metalidea
    15.04.2022 10:00

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


    1. gardiys
      15.04.2022 15:04

      Если это какой то очень чувствительный функционал, из за которого будет "оппечатка на проде", то конечно его стоит просмотреть дополнительно.

      Я больше имел в виду ситуацию когда у вам нужно например добавить новое поле на выдачу для фронта из БД. На такие вещи не стоит тратить время ревьюера.


  1. mirudom
    15.04.2022 10:00

    matasha_d,
    интересно, но используете ли вы формальные метрики, которые можно получить автоматически при использовании соответствующих инструментов для оценки качества разрабатываемого ПО?


    1. gardiys
      15.04.2022 13:48

      Привет! Общепринятой практики использования автоматических средств аудита на уровне компании у нас нет, но некоторые команды используют к примеру pylama для проектов на Python, для того, чтобы получать определенные метрики, говорящие о качестве разрабатываемого ПО.


  1. Dolios
    15.04.2022 13:20
    +3

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

    Менее опытному нужно давать ревьювить более опытного. Во-первых, так менее опытный учится, имекя перед глазами примеры того, как конкретную задачу решают более опытные коллеги. Во-вторых, более опытные часто забывают комментировать совсем не очевидные вещи, которые очевидны для них или вообще могут нафигачить криптокода, который никто кроме них прочитать не сможет. И это, как раз, хорошая возможность поправить такой код. Если менее опытный коллега ничего не понял, это повод задуматься и сделать более понятно.


    1. lebedec
      15.04.2022 14:31
      +1

      Поддерживаю и добавлю еще что решает экспертность в предметной области и личная мотивация ревьюера вносить качественные изменения в рассматриваемый код. Должность тут никак не влияет.

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


    1. gardiys
      15.04.2022 15:02

      Хорошее замечание, и в целом справедливое. Но есть большой минус такой проверки, это ее бесполезность для предлагаемого решения. При таком подходе мы уже преследуем другую цель - обучение младших сотрудников, потому что скорее всего единственный конструктив, который сможет привнести младший разработчик - это сказать о том, что ему что то не понятно.

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


  1. cruzo
    15.04.2022 14:31

    Gerrit, кстати, тоже неплохо подходит для организации ревью