С технической точки зрения возможно добавить несколько до / после push-хуков, которые будут запускать модульные тесты, прежде чем разрешить объединение некоторого конкретного коммита с удаленной веткой по умолчанию.
Мой вопрос - лучше ли держать модульные тесты в конвейере сборки (таким образом, вводить битые коммиты в репо) или лучше просто не допускать «плохих» коммитов.
Я понимаю, что я не ограничен этими двумя вариантами. Например, я могу разрешить все коммиты разветвленным и тестировать, прежде чем нажать Merge commit для репо. Но если вам придется выбирать между именно этими двумя решениями, какое из них вы выберете и по каким именно причинам?
Ответы:
Нет, по двум причинам:
скорость
Коммиты должны быть быстрыми. Например, коммит, который занимает 500 мс, слишком медленный и побудит разработчиков делать коммиты более экономно. Учитывая, что в любом проекте, превышающем Hello World, у вас будут десятки или сотни тестов, их запуск во время предварительной фиксации займет слишком много времени.
Конечно, дела обстоят хуже для крупных проектов с тысячами тестов, которые выполняются в течение нескольких минут на распределенной архитектуре, или недели или месяцы на одной машине.
Хуже всего то, что вы ничего не можете сделать, чтобы сделать это быстрее. Небольшие проекты Python, которые имеют, скажем, сотню модульных тестов, для запуска на среднем сервере занимают по меньшей мере секунду, но часто гораздо дольше. Для приложения C # это будет в среднем четыре-пять секунд из-за времени компиляции.
С этого момента вы можете либо заплатить дополнительные 10 000 долларов за лучший сервер, который сократит время, но не намного, либо запустить тесты на нескольких серверах, что только замедлит работу.
Оба хорошо платят, когда у вас есть тысячи тестов (а также функциональных, системных и интеграционных тестов), что позволяет выполнять их в считанные минуты, а не недели, но это не поможет вам в небольших проектах.
Вместо этого вы можете:
Поощряйте разработчиков запускать тесты, тесно связанные с кодом, который они модифицировали локально, перед выполнением фиксации. Возможно, они не могут запустить тысячи модульных тестов, но могут выполнить пять-десять из них.
Убедитесь, что найти соответствующие тесты и запустить их на самом деле легко (и быстро). Например, Visual Studio может определить, на какие тесты могут повлиять изменения, выполненные с момента последнего запуска. Другие IDE / платформы / языки / рамки могут иметь аналогичную функциональность.
Держите коммит как можно быстрее. Применение правил стиля - это нормально, потому что зачастую это единственное место, где можно это сделать, и потому что такие проверки часто бывают удивительно быстрыми. Выполнение статического анализа - это нормально, как только оно остается быстрым, что редко бывает. Запуск юнит-тестов не в порядке.
Запустите модульные тесты на сервере Continuous Integration.
Убедитесь, что разработчики получают автоматическую информацию, когда они прерывают сборку (или когда не удается выполнить модульные тесты, что практически одно и то же, если вы рассматриваете компилятор как инструмент, который проверяет некоторые из возможных ошибок, которые вы можете внести в ваш код).
Например, переход на веб-страницу для проверки последних сборок не является решением. Они должны быть проинформированы автоматически . Отображение всплывающего окна или отправка SMS - два примера того, как они могут быть проинформированы.
Убедитесь, что разработчики понимают, что ломать сборку (или проваливать регрессионные тесты) нехорошо, и что, как только это происходит, их первоочередной задачей является исправление. Неважно, работают ли они над высокоприоритетной функцией, которую их босс попросил отправить на завтра: они провалили сборку, они должны это исправить.
Безопасность
Сервер, на котором размещено хранилище, не должен запускать пользовательский код, такой как модульные тесты, особенно по соображениям безопасности. Эти причины уже были объяснены в CI Runner на том же сервере GitLab?
Если, с другой стороны, ваша идея состоит в том, чтобы запустить процесс на сервере сборки из ловушки перед фиксацией, то это замедлит еще больше фиксаций.
источник
Позвольте мне быть тем, кто не согласен с моими коллегами-ответчиками.
Это известно как Gated Check-in в мире TFS, и я ожидаю в другом месте. Когда вы пытаетесь выполнить возврат в филиал с помощью gated-регистрации, набор полок отправляется на сервер, который обеспечивает сборку ваших изменений и выполнение указанных (прочитанных: всех) модульных тестов. Если они этого не делают, он уведомляет вас, что вы плохая обезьяна, которая сломала сборку. Если они это сделают, изменения перейдут в систему контроля версий (ууу!).
По моему опыту, закрытые проверки являются одним из наиболее важных процессов для успешного модульного тестирования и, как следствие, качества программного обеспечения.
Зачем?
И, конечно, вы извлекли выгоду изначально - когда у вас есть закрытые регистрации и солидный набор тестов, каждый набор изменений «стабилен». Вы сохраняете все эти накладные расходы (и потенциальную возможность ошибки) на «когда была последняя хорошая сборка?» - все сборки достаточно хороши, чтобы развиваться против.
Да, для сборки и запуска тестов требуется время. По моему опыту 5-10 минут для хорошего приложения C # и ~ 5k юнит-тестов. И мне все равно. Да, люди должны часто регистрироваться. Но они также должны часто обновлять свои задачи, или проверять свою электронную почту, или получать кофе или десятки других «не работающих над кодом» вещей, которые составляют работу разработчика программного обеспечения, чтобы занять это время. Проверка плохого кода обходится намного дороже, чем 5-10 минут.
источник
Коммиты должны бежать быстро. Когда я фиксирую некоторый код, я хочу, чтобы он был передан на сервер. Я не хочу ждать несколько минут, пока он запускает ряд тестов. Я отвечаю за то, что отправляю на сервер, и мне не нужно, чтобы кто-нибудь присматривал за мной с помощью коммитов.
Тем не менее, как только он попадет на сервер, он должен быть проанализирован, протестирован модулем и построен немедленно (или в течение короткого периода времени). Это предупредило бы меня о том, что модульные тесты не работают, или они не компилируются, или я сделал беспорядок, показанный доступными инструментами статического анализа. Чем быстрее это будет сделано (сборка и анализ), тем быстрее будет моя обратная связь и тем быстрее я смогу это исправить (мысли не полностью исчезли из моего мозга).
Так что нет, не ставьте тесты и тому подобное в хуки коммитов на клиенте. Если необходимо, поместите их на сервер в пост-фиксации (потому что у вас нет сервера CI) или на сервер сборки CI и предупредите меня соответствующим образом о проблемах с кодом. Но не блокируйте коммит, чтобы он произошел в первую очередь.
Я также должен отметить, что в некоторых интерпретациях Test Driven Development следует проверять модульный тест, который сначала ломается . Это демонстрирует и документирует наличие ошибки. Тогда более поздняя регистрация будет кодом, который исправляет юнит-тест. Предотвращение любых проверок до прохождения модульных тестов уменьшит эффективное значение проверки в модульном тесте, который не документирует проблему.
Связанный: Должны ли я иметь модульные тесты для известных дефектов и какова ценность проверки при неудачных юнит-тестах?
источник
Commits should run fast.
Каковы преимущества этого? Мне любопытно, потому что мы в настоящее время используем закрытые проверки. Обычно мои проверки - это кумуляция часа или около того работы, так что 5-минутное ожидание не имеет большого значения. На самом деле я обнаружил , что его , как правило те времена , когда я нахожусь в спешке , что сборка проверка является наиболее полезным для ловли глупых ошибок (в результате стремительного движения)catching silly mistakes (as a result of rushing)
Точно так же. спешка вообще плохая практика в разработке программного обеспечения. Роберт К. Мартин рекомендует писать код, например, делать операцию youtube.com/watch?v=p0O1VVqRSK0В принципе, я думаю, что имеет смысл не позволять людям вносить изменения в основную линию, которые нарушают сборку. То есть процесс внесения изменений в основную ветку вашего репозитория должен требовать, чтобы все тесты все еще проходили. Нарушение сборки просто слишком дорого с точки зрения потери времени для всех инженеров в проекте, чтобы сделать что-нибудь еще.
Тем не менее, конкретное решение коммитов не является хорошим планом.
источник
Breaking the build is simply too costly in terms of lost time for all engineers on the project
Я бы предложил использовать какой-нибудь инструмент для уведомления о сборке, чтобы избежать потери всеми инженерами времени на каждую сломанную сборкуНет, вы не должны, как указывали другие ответы.
Если вы хотите иметь кодовую базу, которая гарантированно не будет иметь неудачных тестов, вы можете вместо этого разрабатывать функциональные ветви и выполнять запросы в master. Затем вы можете определить предварительные условия для принятия этих запросов. Преимущество в том, что вы можете нажимать очень быстро, и тесты запускаются в фоновом режиме.
источник
Ожидание успешной сборки и тестирования каждого коммита в основной ветке действительно ужасно, я думаю, что все с этим согласны.
Но есть и другие способы достижения последовательной основной ветки. Вот одно предложение, немного похожее в плане стробированных проверок в TFS, но которое можно обобщить для любой системы контроля версий с ветвями, хотя я в основном буду использовать термины git:
Создайте промежуточную ветку, в которую вы можете фиксировать только слияния между вашими ветками разработчика и основной веткой
Установите хук, который запускает или ставит в очередь сборку и тестирует коммиты, сделанные в промежуточной ветке, но это не заставляет коммиттера ждать
При успешной сборке и тестировании автоматически заставьте основную ветвь идти вперед, если она обновлена
Примечание: не выполняйте автоматическое слияние с основной ветвью, потому что проверенное слияние, если не прямое слияние с точки зрения основной ветки, может произойти сбой при слиянии с основной веткой с коммитами между ними.
Как следствие:
Запрещать человеческие коммиты в основную ветку, автоматически, если вы можете, но также и как часть официального процесса, если есть лазейка или если это технически невозможно реализовать
По крайней мере, вы можете быть уверены, что никто не будет делать это непреднамеренно или без злого умысла, если это основное правило. Вы не должны пытаться сделать это, никогда.
Вам придется выбирать между:
Одна промежуточная ветвь, которая в противном случае приведет к успешному слиянию, если произойдет сбой предыдущего, но не построенного и не протестированного слияния
По крайней мере, вы будете знать, какое слияние не удалось, и попросите кого-нибудь исправить его, но слияния между ними не могут быть легко отслежены (системой контроля версий) результатов дальнейших сборок и тестов.
Вы можете посмотреть на аннотацию файла (или обвинять), но иногда изменение в файле (например, конфигурация) приводит к ошибкам в неожиданных местах. Однако это довольно редкое событие.
Несколько промежуточных веток, которые позволят бесконфликтным успешным слияниям добраться до основной ветки
Даже в том случае, если какая-то другая промежуточная ветвь имеет несогласованные сбои с ошибками. Трассируемость немного лучше, хотя бы в том случае, если одно слияние не ожидало изменения, которое может повлиять на другое слияние. Но опять же, это достаточно редко, чтобы не волноваться каждый день или каждую неделю.
Чтобы в большинстве случаев происходили бесконфликтные слияния, важно разумно разделить промежуточные ветви, например, для каждой группы, для каждого слоя или для каждого компонента / проекта / системы / решения (как бы вы его ни называли).
Если основная ветвь была переадресована на другое слияние, вы должны слить снова. Надеемся, что это не проблема с бесконфликтными слияниями или с очень небольшим количеством конфликтов.
По сравнению с закрытыми регистрациями, преимущество в том, что у вас есть гарантия работающей основной ветви, поскольку основной ветви разрешено только двигаться вперед, а не автоматически объединять ваши изменения с тем, что было зафиксировано между ними. Итак, третий момент - существенная разница.
источник
Я предпочитаю, чтобы «пройденные модульные тесты» были воротами для отправки кода. Однако, чтобы это работало, вам понадобится несколько вещей.
Вам понадобится сборочный фреймворк, который кэширует артефакты.
Вам понадобится тестовая структура, которая кэширует статус теста из (успешных) тестовых прогонов с любым заданным артефактом (ами).
Таким образом, проверки с прохождением модульных тестов будут быстрыми (перекрестная проверка от источника к артефакту, который был создан, когда разработчик проверил тесты перед регистрацией), те, кто провалил модульные тесты, будут заблокированы, и разработчики, которые удобно не забывать проверять сборки перед фиксацией, рекомендуется помнить об этом в следующий раз, потому что цикл компиляции и тестирования длительный.
источник
Я бы сказал, что это зависит от проекта и объема автоматизированных тестов, которые выполняются на коммите.
Если тесты, которые вы хотели бы запустить в триггере регистрации, действительно быстрые, или если рабочий процесс разработчика заставит какую-либо административную работу после такой регистрации в любом случае, я думаю, что это не должно иметь большого значения и заставляет разработчиков только проверять в материале, который абсолютно запускает самые основные тесты. (Я предполагаю, что вы будете запускать только самые основные тесты для такого триггера.)
И я думаю, что если разрешить скорость / рабочий процесс, это хорошая вещь, чтобы не выдвигать изменения другим разработчикам, которые провалили тесты - и вы знаете только, если они не пройдут, если вы их запустите.
Вы пишете «commit ... to remote branch» в вопросе, что для меня означает, что (а) не то, что разработчик делает каждые несколько минут, поэтому небольшое ожидание может быть очень приемлемым, и (б) что после При такой фиксации изменения кода могут повлиять на других разработчиков, поэтому могут потребоваться дополнительные проверки.
Я могу согласиться с другими ответами о том, что «не заставляйте своих разработчиков вертеться во время ожидания» для такой операции.
источник
Разрешенные коммиты не должны допускаться на транке , потому что транк - то, что может войти в производство. Таким образом, вы должны убедиться, что есть шлюз, который они должны пройти, прежде чем находиться в транке . Тем не менее, нарушенные коммиты могут быть вполне хороши в репо, если они не на стволе.
С другой стороны, требование к разработчикам подождать / исправить проблемы перед отправкой изменений в репозиторий имеет ряд недостатков.
Некоторые примеры:
источник