Руководство по тестированию в Agile

Автор: | 03.08.2009

Автор: Асхат Уразбаев © (scrumtrek.ru)

В текст перевел: Алексей Лупан (testitquickly.com)

Вместо введения

Доклад был представлен на конференции SQA Days’2009 24 апреля. Его можно было послушать в виде слайдкаста (слайды, снабженные звуком), но слайдкаст утерян.

Текст совсем чуть-чуть поправлен и снабжен (не всеми) картинками в нужных местах.

Руководство по тестированию в Agile

Кто-нибудь работает по эджайлу? Пожалуйста, поднимите руки. Уау… А из тех, кто не поднял, кто-нибудь собирается это сделать? Хорошо. Давайте я сначала представлюсь — меня зовут Асхат Уразбаев, меня уже представили, поэтому я коротко… Он сказал всю правду обо мне, немножко преувеличил местами… Работаю в компании ScrumTrek, мы занимаемся внедрением гибких методологий, помогаем компаниям и организациям всем этим заниматься.

Итеративность

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

Что такое эджайл — в большинстве случаев это просто итеративная разработка. Видите, там цель — бизнес-цель — сменилась?! Она во время пути, естественно, меняется. Мы следуем так, чтобы не выпускать ее из вида, даже если требования меняются, мы, постепенно корректируем движение и направление нашего проекта. Работаем при этом вот такими короткими итерациями.

ashat1

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

Проблемы ответственности

Проблемы, которые тут возникают, прекрасно раскрыл Саша Орлов — его доклад был полностью посвящен раскрытию этих проблем. Не только между тестировщиками и программистами — такие проблемы существуют, например, и между двумя разработчиками одного модуля, проблемы связанные с ответственностью. Если отвечаю за свой модуль — у меня все работает на машине, а если там что-то не работает, то это не мои проблемы. Поэтому люди не пускают других программистов в свой модуль, потому что говорят — я за него отвечаю, ты не имеешь права тут что-либо делать, потому что это, якобы, порождает проблемы. Что действительно бывает…

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

И еще одна проблема: «Настоящий мужик решает свои проблемы сам». У меня серьезный баг, я с ним вожусь уже три недели, но я буду сражаться, пока не сумею его побороть, потому что я — мужик, у меня есть проблема, но я о ней никому не скажу, я всегда сам…

Это — проблема ответственности.

Самоорганизация

Какой ответ на это дает эджайл? Самоуправляемые, самоорганизующиеся команды. Команды у которых до какой-то степени нет менеджмента — какой-то менеджмент, конечно, есть всегда, только он переквалифицировался. Product owner не раздает задачи людям — команда сама распределяет задачи.

Вот определение, которое мне очень нравится:

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

ashat2

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

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

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

Доверие — мы должны доверять, иначе мы никогда не договоримся. Для доверия нужна взаимная ответственность.

Взаимная ответственность не работает без прозрачности.

Например… знаете, что такое daily scrum? Или stand up meeting? Это когда мы ежедневно общаемся на какую-то тему. Это способ увеличить прозрачность. Без такой прозрачности доверия между людьми не будет. Это способ установить взаимоответственность между людьми внутри команды — я отвечаю перед тобой, ты отвечаешь передо мной. Ты что-то не сделал? Ты виноват не по отношению к менеджеру, а по отношению к команде — ты нас задерживаешь.

Как устроено тестирование в Agile? Первая, самая важная вещь — за качество отвечает команда…

Жизненный цикл

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

ashat3

Как все это происходит — есть Product Owner – менеджер, он определяет набор фич, которые нам нужно сделать. Это просто фичи, на уровне одного абзаца текста максимум. Команда помогает Product Owner’у создавать требования. Требование — это фича, детализированная на уровень, например, приемочных тестов.

В команду, которая создает требования, составной частью входят тестировщики. Они помогают менеджеру создавать требования в виде тестов, поэтому оторванность тестировщиков от команды, когда в конце программист говорит «Вот, тестируй то, что я написал». А что ты написал? «А я вот сейчас тебе расскажу...» — вот такого не происходит. Если тестировщики принимают работу, то они должны ее и ставить. Иначе это просто безумие 🙂

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

Получается план итерации — фичи, задачи, и оценка. В течение итерации команда работает. Каждые 24 часа происходит daily scrum. Каждый отчитывается перед командой о том, что он делал вчера, что он будет делать сегодня, и какие у него проблемы… Мы выявляем проблемы, и мы можем коллективно их решить.

В конце итерации у нас демонстрация. Фактически это «приемка» — каждый демонстрирует, что он сделал, и product owner принимает результат.

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

Как это все выглядит?

Task Board

Одна из практик, которую я очень рекомендую, называется task board. Что это такое — вот у нас есть To Do, In Progress и Done – три свимлайна, и вот фича большая (сверху), декомпозированная на кучу мелких задач.

ashat4

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

На планировании мы не распределяем задачи по людям. Иначе мы получаем проблему ответственности, когда у меня, у программиста, есть куча своих задач, и какой мне смысл помогать своим товарищам?! Меня попросят помочь, а я скажу «Вообще-то, я занят». Или «Пошел ты в задницу!» в самом пиковом случае. А если будете достаточно вежливы, то просто скажете «У меня сейчас нет времени, но в конце итерации, когда я освобожусь, я тебе помогу…» — то есть, этого не произойдет. Поэтому задачи на людей не планируются.

На daily scrum вы можете распределить задачи по людям.

Таким образом, задача переносится сюда, в In Progress, человек под ней подписывается, и, как только она сделана, она перевешивается направо, в Done. Таким образом, задачи слева все время перевешиваются направо. Когда они все перелезли, значит, мы сделали нашу работу. Это обеспечивает прозрачность — и это очень удобный механизм.

Методы обеспечения качества

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

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

ashat5

Чем раньше найдем ошибку, тем дешевле она нам обойдется. Самый простой способ исправлять ошибки — это вообще их не делать.

Я часто езжу на поездах в разные города. Прекрасный сервис, не надо платить за проживание, но там есть одна проблема — некоторые граждане храпят. А я довольно чутко сплю, и это всегда было проблемой. Я придумывал всякие способы, как от этого избавиться (есть баг — человек храпит, как это исправить). Иногда я просто стучал в стенку — дыщ-дыщ…. Человек просыпался, на какое-то время это помогало.

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

Голос из зала: Есть еще один способ! Вот такой — еще пива.

Еще пива — способ, да, я его тоже пробовал, но это полумера.

И вот я, по дороге сюда, все-таки исправил этот баг. Я сделал так, чтобы он вообще не появлялся. Я купил себе беруши. Знаете такие штуки? В уши вкручиваешь, и ни хрена не слышно, великолепно спишь. Кстати, появляются другие проблемы, можно проспать свою остановку.

Итак, как мы сделаем так, чтобы проблем не было вообще?

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

Некоторая «полумера» — ревью кода. Оно должно происходить до коммита, тогда имеет смысл его делать.

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

Если уж сделали ошибку, ее лучше исправить как можно раньше. Как это можно сделать? Ну вот:

  • Непрерывная интеграция
  • Юнит-тесты
  • Разработка через тестирование (TDD)
  • Автоматизированное приемочное тестирование

В эджайле это особенно важно, потому что каждые две недели требования могут поменяться. Это не значит, что у вас есть огромный пул задач, которые вы можете продумать достаточно далеко, и стабильно по ним жить. Требования поменяются, код будет деградировать, и вы рано или поздно столкнетесь с проблемой поддержки — когда у вас 50% времени занимает поддержка, исправление кода из-за того, что он не очень качественный. Код вообще, и в особенности в эджайле, надо поддерживать в великолепном качестве.

А что тогда такое «Ручное тестирование»? Если вы делаете все то, что написано на двух предыдущих слайдах, (это, кстати, бывает не всегда), то что остается на долю ручного тестирования?

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

И то, что в английской литературе называется Exploratory testing — это такое «Талантливое» тестирование, когда тестировщик садится без плана тестирования, и ловит ошибки в совершенно невероятных местах. То есть, это такое исследовательское тестирование, которое, если честно, намного приятнее и интереснее, и более мотивирует, чем просто тестирование по тест-плану. Тест-план должен быть автоматизирован.

Вот и все тестирование 🙂

Я тут с Лешей Кривицким разговаривал, говорю «Я поеду на конференцию, буду про тестирование в эджайле говорить», а он говорит «Я не понимаю, о чем вы там рассказываете. Просто автоматизируйте все тесты, и всё».

Леша рулит в agile, но он программист. У программистов всегда всё так — взять всё и поделить автоматизировать!

Проблемы

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

Недостаток дисциплины — да, мы решили, да, мы будем делать код-ревью, договорились. И не делаем. Тоже бывает достаточно часто — как мы это будем делать, как мы это будем контролировать?

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

Definition Of Done

Такой инструмент есть — его упоминал Саша Орлов в своем докладе — в оригинале этот инструмент называется Definition Of Done.

Мы должны определить, что значит «ГОТОВО». Определить критерии готовности той или иной вещи, которая нас интересует. Ну, самые распространенные кандидаты на определение Defintion of done это требования. Задачи. Фичи. Что значит «фича сделана до конца» — мы должны это определить. И итерация — что значит «Итерация сделана»?

Требование. Каждая история…

  • снабжена приемочными тестами
  • снабжена сценарием демонстрации
  • имеет приоритет

Для задачи

  • Для каждой задачи проведено code review (если не разрабатывалась в паре)
  • Написаны автоматизированные тесты на основные методы
  • Все тесты успешно проходят

Для фичи

  • Созданы автоматизированные приемочные тесты
  • Неавтоматизированные тесты добавлены в Check list
  • Все пофиксенные дефекты валидированы
  • Фича получила статус Validated

Для итерации

  • Система прошла регресионное тестирование
  • Вся созданная документация прошла ревью

То, что здесь написано, это не означает, что вы должны это взять и использовать. Это только пример, отнеситесь к нему только как к примеру. Но это реальный пример из реальной команды.

Значит, требования.

Перед тем, как фича падает вам в разработку, она должна быть снабжена приемочными тестами. Вы так считаете, и вы договорились об этом. В конце тестирования вы просто будет ставить галочки — это сделано, то сделано — все это значит, что фича готова. Она должна быть снабжена сценарием демонстрации. Мы должны в фиче указать, как мы потом будем демонстрировать ее результат. И она должна иметь приоритет.

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

Для каждой задачи проведено code review — вы договариваетесь об этом внутри команды — если она не разрабатывалась в паре (в этом случае код-верью проводить необязательно).

Написаны автоматизированные тесты на основные методы. Все тесты успешно проходят.

Вы можете определить, что значит «написан автоматизированный тест». Определить какое покрытие вы требуете — например 100% для бизнес-логики…

Для фичи – созданы автоматизированные приемочные тесты. Это значит, что создан приемочный тест, который проверяет, что фича готова.

Те тесты, которые не автоматизированны — добавлены в Check list.

Все пофиксенные дефекты валидированы — фича получила стату Validated.

Какие-то еще вещи, например, в фиче не должно быть критических дефектов.

Или вы можете определить долю дефектов: ни одного критического, не больше двух Major, не больше трех Minor. Или вообще ноль.

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

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

Как мы вырабатываем Definition of Done

Очень просто, как всегда в эджайле — мы собираемся командой, куда входят тестировщики, разработчики, аналитики, менеджеры — все, кто вовлечены в разработку, у кого руки по локоть в работе. И мы выписываем на бумагу и договариваемся о том, что такое «готово». Все в команде должны быть согласны с тем, что это то, что нам нужно. Все. Если хотя бы один не согласен, то договариваемся дальше. Вы понимаете, зачем это нужно? Консенсус означает, что — вы же будете потом всем этим пользоваться?!

Если кто-то будет против, то он не будет этого делать? А какая же это командная работа? Мы должны договориться. Мы обсуждаем, что конкретно его не устраивает.

Definition Of Done должен отражать реальное положение дел. Это то, что вы собираетесь делать со следующей итерации. Это не то, что вы хотите делать, когда вырастите, когда у вас не будет legacy-кода, или когда вы найдете замечательных автоматических тестировщиков, которые вам все заавтоматизируют… Если вы этого делать не будете — выкиньте, потом добавите, если будет надо.

Результат стоит распечатать и повесить в рамочку, чтобы все было прозрачно.

Как мы пользуемся Definition Of Done

Корректируем на ретроспективах. Напомню, что ретроспектива — это способ скорректировать процесс. Собрались и обсудили. Какая была проблема — например, для какого-то куска кода не было написано автоматизированного теста. «Давайте обсудим, что мы с этим делаем». «А давайте, например, выкинем это нафиг из определения Definition of Done. Или давайте изменим Definition of Done, чтобы для этого типа нам не нужны автоматизированные тесты. Как-то скорректируем его, ведь это наш договор, договор внутри команды».

Используется при аппеляциях к совести разработчика. «Ты же коммитился на то, что будешь делать код-ревью, давал обязательства вместе со всеми, голосовал, мы помним, как ты голосовал — почему ты его не делаешь?» Это снимает проблему с дисциплиной. А как это снимает проблему с мотивацией — не совсем снимает, но это повод поговорить о том, какие у нас есть критерии качества. Выработать, обсудить, почему они для нас важны. В среднем, по моему опыту, команды стремятся сделать более качественный код. И, как правило, именно «бизнес» мешает писать качественный код.

Это давление снимается тем, что мы сами определяем наш time-box, что мы успеваем сделать в итерации. Вот теперь мы отвечаем за качество.

Ну вот, ребята собрались возле доски задач, и один говорит:

—  Слушайте, мы не делаем код-ревью, давайте выкинем его из definition of done.

— Да не, мы делаем, просто не всегда, — говорит второй.

— А как нам сделать так, чтобы было всегда?

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

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

И один говорит:

— И штрафовать, если ревью не проведено. Десять рублей в пивной фонд!

Всем идея понравилась, приняли.

Вот еще один способ напомнить команде о договоренностях, которые команда достигла. Я сфотографировал одну из команд, наверху там написано «Поработаем в паре», а внизу «Ты делаешь код-ревью?» — способ напомнить команде о том, насколько это важно для нее.

ashat6

Технологический долг

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

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

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

Мы следим за тем, чтобы технический бэклог постоянно уменьшался. Суммируем всю сумму, получаем, например, сто условных попугаев, и следим за уменьшением. Если оно постоянно растет — стоп, ребята, мы двигаемся не туда, сами себе роем могилу. В идеале к концу ЖЦ продукта или проекта он должен уйти в ноль, не должно быть ни одной проблемы. Ну, хотя бы он должен уменьшаться, но никак не расти.

Договариваемся с Product Owner и планируем его внутри итерации. Конечно, не то, чтобы мы теперь пять итераций занимаемся улучшением бэклога. Конечно, задачи для бизнеса тоже нужно делать. Но мы постоянно стараемся что-то добавить в итерацию, чтобы он постоянно уменьшался. Это относится к работе с legacy-кодом — все сразу поднять нельзя, работаем постепенно.

Руководство по тестированию в Agile: 1 комментарий

  1. Алексей Лупан

    Объявление
    Асхат готовит новый подкаст на тему тестирования в Agile вообще.
    В эфире будут несколько товарищей-тестировщиков с большим опытом в этой теме, которые работали с проектами разного уровня, в том числе и слабоавтоматизируемыми
    * Илья Гаврилов, Exigen
    * Яков Котляр, Black&Veatch
    * сам Асхат

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.