Стратегия ветвления Git интегрирована с процессом тестирования / контроля качества

131

Наша команда разработчиков использовала стратегию ветвления GitFlow , и это было здорово!

Недавно мы наняли пару тестировщиков, чтобы улучшить качество нашего программного обеспечения. Идея состоит в том, что каждая функция должна быть протестирована / QA тестером.

В прошлом разработчики работали над функциями в отдельных ветвях функций и по завершении объединяли их обратно в developветку. Разработчик сам проверит свою работу на этой featureветке. Теперь с тестерами мы начинаем задавать этот вопрос

В какой ветви тестировщик должен тестировать новые функции?

Очевидно, есть два варианта:

  • в отдельной функциональной ветви
  • на developветке

Тестирование в ветке разработки

Изначально мы считали, что это верный путь, потому что:

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

Самые большие проблемы с этим:

  • developФилиал загрязняется с ошибками.

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

Тестирование в функциональной ветке

Мы подумали еще раз и решили, что нужно протестировать функции в ветках функций. Перед тестированием мы объединяем изменения из developветки в функциональную ветку (догоняем developветку). Это хорошо:

  • Вы по-прежнему тестируете эту функцию с другими основными функциями.
  • Дальнейшее развитие (например, исправление ошибки, разрешение конфликта) не приведет к загрязнению developветки;
  • Вы можете легко решить не выпускать функцию, пока она не будет полностью протестирована и одобрена;

Однако есть и недостатки.

  • Тестировщик должен выполнить слияние кода, и в случае конфликта (что весьма вероятно) он должен попросить помощи у разработчика. Наши тестировщики специализируются на тестировании и не умеют кодировать.
  • функция может быть протестирована без наличия другой новой функции. например, функция A и B тестируются одновременно, две функции не знают друг друга, потому что ни одна из них не была объединена в developветку. Это означает, что вам придется снова протестировать developветку, когда обе функции все равно будут объединены с веткой разработки. И вы должны не забыть проверить это в будущем.
  • Если функция A и B протестированы и одобрены, но при объединении обнаружен конфликт, оба разработчика обеих функций считают, что это не его собственная ошибка / работа, поскольку его ветвь функции прошла тестирование. В общении есть лишние накладные расходы, и иногда тот, кто разрешает конфликт, разочаровывается.

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

Дэвид Лин
источник
5
Этот вопрос кажется более подходящим для программистов , поскольку он касается не проблемы программирования, а скорее процесса разработки. Может кто-нибудь перенести?
2
Наша модель точно такая же. Мне интересно услышать о том, как ваша команда QA сообщает о проблемах в ветках функций иначе, чем о проблемах на местах или о проблемах во время процесса UAT (если он у вас есть). Мы используем Atlassian JIRA, и у нас для них другой рабочий процесс.
void.pointer
2
Решаю то же самое прямо сейчас. Кроме того, поскольку наша среда представляет собой приложение java spring, сборка и развертывание в тестовой среде занимает около 20 минут. Счастливый, что кто-то задал мне те же сомнения.
digao_mb
Первый недостаток не присущ процессу тестирования на функциональных ветках. Такие инструменты, как Github Enterprise и Bitbucket, могут требовать утверждения для запросов на вытягивание, а лицо, ответственное за QA, может утверждать, сигнализируя разработчику, что они могут слиться с разработкой.
Дерек Грир

Ответы:

102

Мы делаем это следующим образом:

Мы тестируем ветки функций после того, как объединим с ними последний код ветки разработки. Основная причина в том, что мы не хотим «загрязнять» код ветки разработки до того, как функция будет принята. Если функция не будет принята после тестирования, но мы хотели бы выпустить другие функции, уже объединенные при разработке, это было бы адом. Разработка - это ветка, из которой создается релиз, и поэтому лучше быть в готовом к выпуску состоянии. Длинная версия состоит в том, что мы тестируем в несколько этапов. Более аналитически:

  1. Разработчик создает отдельную ветку для каждой новой функции.
  2. Ветка функций (автоматически) развертывается в нашей тестовой среде с каждой фиксацией для тестирования разработчиком.
  3. Когда разработчик завершает развертывание и функция готова к тестированию, он объединяет ветвь разработки с веткой функции и развертывает ветвь функции, которая содержит все последние изменения разработки, в тесте.
  4. Тестер тестирует на ТЕСТ. Когда он закончил, он «принимает» историю и объединяет функциональную ветку при разработке. Поскольку разработчик ранее объединил ветку разработки для функции, мы обычно не ожидаем слишком большого количества конфликтов. Однако в этом случае разработчик может помочь. Это сложный шаг, я думаю, что лучший способ избежать этого - сделать функции как можно более мелкими / конкретными. В конечном итоге, так или иначе, необходимо объединить разные функции. Конечно, размер команды играет роль в сложности этого шага.
  5. Ветка разработки также (автоматически) развертывается на TEST. У нас есть политика, согласно которой, даже если сборки ветки функций могут давать сбой, ветка разработки никогда не должна давать сбоев.
  6. Как только мы достигли замораживания функций, мы создаем выпуск из develop. Это автоматически развертывается на ЭТАПЕ. Перед развертыванием в производственной среде там проходят обширные сквозные тесты. (хорошо, может быть, я немного преувеличиваю, они не очень обширны, но я думаю, что они должны быть). В идеале там должны тестировать бета-тестеры / коллеги, т.е. реальные пользователи.

Что вы думаете об этом подходе?

Аспазия
источник
2
Как мы можем убедиться, что feature1 и feature2, которые были протестированы независимо, также хорошо сочетаются друг с другом (как указано в вопросе)?
Кумар Дипак
2
мы делаем косвенно, путем слияния одного, а затем другого для развития. Это шаг 4 описанного выше процесса, и он имеет отношение к хронологическому порядку. Таким образом, если функция 2 готова к объединению, но функция 1 уже была объединена, разработчик и тестировщик функции 2 должны убедиться, что их объединение будет работать.
Aspasia
1
Я думаю, что в соответствии с этой моделью ветвления git вы не должны объединять две ветки функций друг с другом.
Aspasia
1
На шаге 6 мы столкнулись с проблемами, особенно в периоды кризиса, когда несколько функций были перемещены для разработки, из-за нетривиальных слияний, которые происходят после того, как QA подписал ветку функции, несмотря на слияние devlop с функцией как можно позже. Я прокомментировал немного подробнее здесь: stackoverflow.com/a/25247382/411282
Джошуа Голдберг
8
У вас есть полная тестовая среда (БД, сервер, клиент и т. Д.) Для каждой функциональной ветки? Или они разделяют среду и просто имеют разные имена (например, app-name_feature1- app-name_feature2 и т. Д.)
hinneLinks
41

Перед тестированием мы объединяем изменения из ветки разработки в ветку функций.

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

Заставьте разработчика выполнить перебазирование своей featureветки поверхdevel и протолкнуть эту featureветку (которая была подтверждена разработчиком как компилирующая и работающая поверх самого последнего develсостояния ветки).
Это позволяет:

  • очень простая интеграция в функциональную ветку (тривиальное слияние с быстрой перемоткой вперед).
  • или, как это было рекомендовано Аспазии ниже в комментариях , запрос тянуть (GitHub) или запрос объединения (GitLab) : сопровождающий делает слияние между функцией PR / MR ветви и develop, но только если не конфликта обнаруживаются GitHub / GitLab.

Каждый раз, когда тестировщик обнаруживает ошибку, он / она сообщает об этом разработчику и удаляет текущую ветку функции.
Разработчик может:

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

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

VonC
источник
Вы говорите «не используйте слияние, используйте вместо этого rebase»? Если это так, то я запутался, учитывая Git FAQ о разнице между ними: git.wiki.kernel.org/index.php/…
Вики
1
@VickiLaidler: да, если функциональная ветка отклонена QA, разработчик должен выполнить перебазирование, а не слияние ( stackoverflow.com/a/804178/6309 )
VonC
1
@VonC Я полностью согласен, но есть некоторые проблемы: 1) Удаление ветки влияет на другие инструменты, такие как Stash Pull Requests (удаление ветки закрывает PR). Предпочитаю силовое толкание. 2) Если это большая функциональная ветка, в которой в течение всего времени существования работали два человека, слияние было бы предпочтительнее, чем ребазирование. Перемещение его в конце создает кошмар конфликта, так как коммиты слияния будут удалены, и если код зависел от этих изменений слияния, исправить это нетривиально
void.pointer
1
Оглядываясь назад на свой ответ, я бы также сделал перебазирование, а не слияние для более чистой истории.
Aspasia
1
@Aspasia Хорошие отзывы. Я включил в ответ запросы на вытягивание для большей наглядности.
VonC
12

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

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

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

Для получения дополнительной информации перейдите по этой ссылке .

Джонни З
источник
Вы все еще можете делать CI с ветками + ребазинг в Git.
void.pointer
9

Мы используем то, что мы называем «золотом», «серебром» и «бронзой». Это можно назвать prod, staging и qa.

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

Когда ошибка или функция готовы к тестированию, они переходят в «бронзу». Это запускает сборку jenkins, которая помещает код в предварительно созданную среду. Наши тестировщики (кстати, не супертехнологи) просто нажимают на ссылку и не заботятся о системе контроля версий. Эта сборка также запускает тесты и т. Д. Мы ходили туда и сюда по этой сборке, фактически отправляя код в среду тестирования \ qa, если тесты (модульные, интеграционные, селеновые) терпят неудачу. Если вы тестируете в отдельной системе (мы называем ее ведущей), вы можете предотвратить внесение изменений в среду qa.

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

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

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

Экстренные исправления вносятся прямо в золотое дерево. Если изменение является простым и сложным для QA, оно может перейти непосредственно в серебро, которое попадет в дерево тестирования.

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

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

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

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

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

Эрик Твилегар
источник
1

Я бы не стал полагаться только на ручное тестирование. Я бы автоматизировал тестирование каждой функциональной ветки с помощью Jenkins. Я настраиваю лабораторию VMWare для запуска тестов Jenkins в Linux и Windows для всех браузеров. Это действительно отличное кроссбраузерное решение для кросс-платформенного тестирования. Тестирую функционал / интеграцию с Selenium Webdriver. Мои тесты на селен выполняются под Rspec. И я написал их специально для загрузки jRuby в Windows. Я запускаю традиционные модульные тесты под Rspec и тесты Javascript под Jasmine. Я настраиваю безголовое тестирование с помощью Phantom JS.

Натус Дрю
источник
1

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

Наш подход к работе с GIT таков;

Мы внедрили «Git Flow» в нашей компании. Мы используем JIRA, и в производство должны поступать только утвержденные билеты JIRA. Для утверждения Test мы расширили его, создав отдельную Test-Branch.

Шаги по обработке заявок JIRA:

  1. Создайте новую ветку из Develop-Branch
  2. Внесите изменения кода в Feature-Branch
  3. Извлеките из Feature изменения в ветку Test / QA
  4. После утверждения бизнеса мы переносим изменение из функциональной ветки в разработку.
  5. Разработка часто идет в выпуске, а затем, наконец, в основной ветке

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

Полный процесс выглядит так: введите описание изображения здесь

Кристиан Мюллер
источник