Альтернатива индикатору «Passing / Broken build»?

14

При непрерывной интеграции, выполняющей тесты при каждом коммите, общепринятой практикой является постоянное прохождение всех тестов (иначе говоря, «не нарушайте сборку»).

Я нахожу некоторые проблемы с этим:

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

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

То же самое и в компании. Если вы работаете с TDD, вы не можете писать тесты, фиксировать, а затем писать логический код, который выполняет тест. Это означает, что если я написал 4-5 тестов на своем ноутбуке, я не смогу выполнить их до отпуска. Никто не может забрать мою работу. Я даже не могу «поделиться» ими с коллегой, кроме как, например, отправив их по электронной почте. Это также не позволяет работать одному человеку, пишущему тесты, а другому - моделирующему.

Все это говорит, я неправильно использую / неправильно понимаю процесс сборки / непрерывную интеграцию? Мне кажется, что «прохождение» / «не прохождение» является слишком узким показателем.

Есть ли способ сделать непрерывную интеграцию и совместимую с TDD?

Может быть, существует стандартное решение / практика, позволяющая различать «новые тесты» (которые могут провалиться) и «регрессионные тесты» (которые не должны давать сбой, потому что они привыкли работать)?

Матье Наполи
источник
1
Имейте индикатор, который показывает, увеличилось ли количество неудачных тестов (красный) или вниз (зеленый) за последний час (или около того).
Иоахим Зауэр
2
Я не специалист по TDD / ALM (следовательно, комментарий, а не ответ), но я думаю, что ваша проблема может быть решена с помощью частных веток / функциональных веток. Вы работаете над функцией А? Разветвите его, работайте над веткой (с коллегами), а когда закончите, объедините ее в непрерывно интегрированную соединительную линию.
Авнер Шахар-Каштан
@JoachimSauer Да, но такой показатель стандартизирован / используется в каком-либо крупном проекте? Я пытаюсь понять, почему большинство проектов (и инструментов CI) работают именно так.
Матье Наполи
Я думаю, что правильный критерий для «тестов, которые могут провалиться» - это не «новые тесты», а скорее «тесты на известные открытые проблемы». Я могу понять, насколько полезны эти тесты - я также могу понять, что эти тесты НЕ полезны в сборке CI, потому что они загрязняют смысл прохождения или неудачи тестов (вам нужно только запускать тесты, на которые кто-то действительно потратил время). чтобы заставить их пройти).
Йорис Тиммерманс
@MadKeithV Точно
Матье Наполи

Ответы:

12

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

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

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

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

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

редактировать

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

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

Нил
источник
1
На самом деле вы делаете точку с ветками темы. Но я никогда не говорю о фиксации неработающего кода, просто провал тестов. Например, я мог бы помочь проекту с открытым исходным кодом, создав тесты для входящих заявок, даже если я не знаю, как их исправить. Это экономит некоторое время для сопровождающих.
Матье Наполи
Если я работаю над тем же проектом, что и вы, и вы загружаете неудачный тест, у меня теперь есть сборка, которая имеет неудачный тест. Я мог бы закончить тем, что удалил ваш тест, так как эта функциональность еще не реализована, или решил бы внедрить эту функцию и в конечном итоге потопил ваш код и потратил время. Если бы существовала такая культура, такого отклика можно было бы избежать, но тогда бы все это делали, и даже когда все ваши тесты пройдены, не все мои. В этом случае сборка всегда будет иметь неудачные тесты. Я не вижу преимущества.
Майкл Шоу
the build would always have failing testsточно! Но так ли это плохо? Наша единственная метрика - «сборка повреждена или нет», но ваш код может быть полон известных ошибок , так что это ничего не значит, кроме случаев, когда нет регрессии. В идеальном мире у каждой проблемы с трекером был бы тест (воспроизведение легче, чем исправление). Таким образом, можно было бы увидеть, что 35 тестов / 70% всех тестов пройдены, что Branch-A улучшает его до 40 тестов (80%) без регрессии, и что у Branch-B есть регрессии. Сегодня вы могли только сказать, что Мастер и Филиал-А в порядке, а Филиал-В неисправен.
Матье Наполи
@Matthieu Я вижу, к чему ты клонишь. Похоже, вам нужна особая категория или что-то, что говорит: «Эй, если этот тест не пройден, это нормально. Мы знаем об этом. Но мы все равно хотим, чтобы он прошел, и если он пройдет, это еще лучше, и мы должны удалить специальную категорию, потому что теперь нас волнует, сломается ли это »
Earlz
@Earlz Точно! Что мне интересно, так это «сделано ли это кем-то где-то? И есть ли инструменты, которые поддерживают это (CI и библиотеки модульного тестирования?»). Потому что, если я просто классифицирую эти тесты с помощью классических инструментов CI и модульных тестов, сборка будет всегда в любом случае потерпеть неудачу, и я не увижу разницу между неудачными тестами, и поэтому она не будет полезна: /
Матье Наполи
4

Учитывая основную ветку с ошибочными тестами, как вы можете быть уверены - не сравнивая этот список с предыдущими сборками - что вы не ввели ошибки?

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

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

Попросите рецензента филиала слить только вашу ветку, если она пройдет все тесты. (Более того: рецензент может объединить вашу ветвь только в том случае, если результат слияния ветки с master пройдет все тесты!)

Фрэнк Шиарар
источник
2
Simply tracking the number of failing tests is insufficientэто не единственная возможная метрика. Например: Branch-A improves it to 40 tests (80% passing) with no regression. Отсутствие регрессии означает, что ранее пройденные тесты всегда проходят. Короче говоря, тест будет разрешен на провал, если он никогда не проходил. Мне кажется, что нам не хватает хороших вещей, поскольку мы запрещаем проваливать тесты в основных ветках. (конечно, для этого потребуются инструменты, работающие по-разному: модульные тесты, CI, ...)
Матье Наполи,
Я все еще придерживаюсь своей точки зрения: хозяин всегда должен быть зеленым, потому что это ясно и однозначно. Безусловно, тесты маркеров не пройдены ... в ветви функций. CI может постоянно напоминать людям о выдающихся ошибках.
Фрэнк Шиарар
Я думаю, что Матье предлагает немного другое определение «зеленого», не отклоняясь от мастера, всегда являющегося зеленым. Для меня не очевидно, что это не имеет смысла - конечно, для отслеживания потребуются не совсем тривиальные инструменты. (Нужно откатить изменение, которое сделало этот тест успешным? Не повезло, если это означает, что состояние внезапно стало красным ...)
Кристофер Кройциг
NUnit имеет концепцию игнорируемого теста. Это может быть альтернативой: они не запускаются, поэтому они не терпят неудачу, но они все равно считаются проигнорированными.
Фрэнк Шиарар
2

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

Я начну с проблемы совершения «сломанного теста», который соответствует заявке. Одно из решений состоит в том, чтобы создать один или несколько тестов, раскрывающих проблему, затем устранить проблему , чтобы их можно было объединить вместе с основной строкой кода. Второе решение состоит в том, чтобы иметь неработающие тесты, но использовать некоторый тип флага игнорирования, чтобы они фактически не запускались и не ломали сборку. Возможно добавьте комментарий или специальную аннотацию, которая сделает очень очевидным, что это не пройденный тест Ticket#N. Также прикрепите примечание к самой заявке, которое относится к созданным тестам, которые ожидают, чтобы быть проигнорированными и выполненными. Это помогло бы человеку, фиксирующему билет, но также не было бы красным флагом для того, кто сталкивается с тестом.

И на вашу следующую проблему с TDD. TDD - это написание небольшого теста, а затем написание небольшого фрагмента кода для прохождения этого теста . Затем продолжайте итерацию, пока у вас не появится небольшой функциональный модуль. Я чувствую, что если вы пишете 4-5 тестов, то уезжаете в отпуск, возможно, вы делаете это неправильно. Вы можете связать программу с кем-то так, чтобы один из вас написал тест, а другой - соответствующий код. Однако вам не следует использовать основной репозиторий строк кода, чтобы делиться этим кодом между вами, пока готовый модуль не будет готов к фиксации. Как и предполагали другие, разделенная ветка решит ваши проблемы там.

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

c_maker
источник
Вам не нужно никаких инструментов, чтобы поделиться с человеком, с которым вы программируете, - просто сдайте клавиатуру. Если вы используете разные компьютеры, в этом нет ничего плохого, просто это не «парное программирование».
Кристофер Кройциг
1

Я думаю, что ваша основная проблема заключается в том, что вы включаете тестовые РЕЗУЛЬТАТЫ в состав сборки. Хотя очевидно, что некоторые люди согласны с вами, другие нет. Разрушение сборки происходит, когда она не строится. Не тогда, когда он не строится без ошибок.

Рассмотрим крупный проект, такой как Windows или Linux, или даже что-то вроде Firefox - как вы думаете, они поставляют без ошибок? Конечно, нет. Сейчас эти проекты не выполняют TDD, но это действительно не имеет значения - TDD не меняет два основных факта: ошибки существуют, и для их устранения требуется время. Время, которое проект (с открытым исходным кодом или нет) просто не может позволить себе тратить на ошибки с низким приоритетом. Недавно в KDE была исправлена ​​ошибка, которой более десяти лет. Когда в последний раз вы слышали, как кто-то сказал: «Я рад, что мы подождали десять лет, чтобы отправить наш проект»?

TDD, в некотором смысле, вероятно, облегчает доставку с ошибками - потому что вы лучше понимаете, в чем заключается недостаток. Если вы можете точно определить причину ошибки, у вас есть отличная основа для оценки стоимости ее устранения.

Моя рекомендация состоит в том, чтобы найти проект, который не имеет ничего против красного среди зеленого.

jmoreno
источник
1
 > a common best practice is to have all the tests passing (green) at all times.

Я предпочитаю, чтобы все тесты не проваливались (не красные).

С этим немного другим определением вы также можете определить тесты, которые

  • еще не реализовано (серый в nunit, если есть исключение NotImplementedException)
  • известно, что это не удалось = "нужно сделать", пометив / пометив тест как игнорируемый (желтый)

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

k3b
источник
0

Вы можете рассмотреть две разные "концепции" сборки CI.

  1. Обычные сборки CI. Обычная сборка CI должна компилировать и запускать только те тесты, для которых был написан код, чтобы сделать их успешными, так что отчеты CI о тестах пройдены / не пройдены являются ясным, однозначным индикатором регрессии по отношению к ранее принятому состоянию кода.
  2. "Будущее" CI build. Эта сборка компилирует и запускает только те тесты, для которых специально не написано ни одного кода, который бы позволил им пройти. Может быть несколько причин для такого теста:

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

    • Добавлены тесты для новых необходимых функций, которые еще не были реализованы.

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

Как и в «стандартном» CI, в обычном режиме разработки команда будет смотреть только на результаты ежедневной сборки обычной сборки.

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

Наконец, если у члена команды есть дополнительное время, он может взглянуть на исправление одной из проблем из «будущего» и, если ему удастся, перенести ее в «обычное» (при обновлении статуса средства отслеживания проблем).

Йорис Тиммерманс
источник
0

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

Проблема не в том, чтобы провалить тесты, а в простом, не зависящем от контекста индикаторе регрессии. Ака: как разработчик, я могу проверить один индикатор и узнать, ввел ли я код регрессии или взлома.

В тот момент, когда вы вводите концепцию «мягких» сбоев (это нормально, мы работаем над этим / еще не реализованы / ждем новую версию / она снова пройдет, как только эта другая сборка будет исправлена), вам потребуется все, кто может запустить или посмотреть на тест, чтобы знать ожидаемое состояние. Что в достаточно большой команде изменится с каждым часом: ваш индикатор теряет смысл. В меньшем контексте (например, тест на личную интеграцию команды), я думаю, что это похоже на технический долг и все в порядке - просто нужно управлять.

Способ адреса большинства инструментов, который заключается в том, что «зеленый / проходящий» отражает ожидаемый результат, а не то, что код работает:

  • Фитнес имеет концепцию ожидаемого отказа.
  • JUnit имеет @Ignored / @Test (ожидаемо =)
  • Огурец имеет статус «еще не реализован» (или как он там называется)

У них есть свои проблемы (как вы различаете «да, мы знаем, что он сломан, работает над этим» и «правильное поведение - исключение») - но они помогают.

ptyx
источник
0

Я использую пропущенные тесты.

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

Уинстон Эверт
источник