MVP. Как выводить на рынок товары и услуги, которые нравятся покупателям — страница 13 из 18

Создание и оптимизация продукта

Глава 12Создание продукта с помощью методов Agile-разработки

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

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

Agile-разработка

До этого момента мы успешно применяли итеративный подход, поэтому вполне логично будет использовать его и при непосредственном создании продукта. «Agile-разработка» – это термин, используемый для описания различных итеративных и поэтапных методов создания продукта. До внедрения Agile-разработки большинство программных продуктов создавались с использованием «водопадного» подхода, суть которого состоит в последовательном выполнении ряда шагов. При нем команда разработчиков сначала определяет все требования технического задания, и лишь затем приступает к разработке продукта. Далее проводится внедрение и тестирование, чтобы убедиться, что все работает так, как было задумано. Ключевой особенностью «водопадного» подхода является то, что разработчики не переходят к следующему шагу до тех пор, пока предыдущий этап не будет завершен на 100 %. Другими словами, никакого проектирования не происходит до тех пор, пока не будут определены все требования, и никакой программный код не пишется до тех пор, пока не будет спроектирован весь продукт. Такой подход также называют BDUF (Big Design Up Front)[22].

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

Я упоминал выгоды концепции бережливого производства небольших партий в главе 6, но давайте рассмотрим, почему она так полезна при разработке программного обеспечения (или при любой другой разработке, осуществляемой в условиях с высокой степенью неопределенности). Когда разработчики оценивают количество времени, которое им потребуется для создания новой функции, в их оценке присутствует некоторая неопределенность. Наличие такой неопределенности приводит к тому, что произведенная оценка затрат оказывается ошибочной и фактическая продолжительность разработки отличается от расчетной. Хороший способ сравнения фактической и расчетной продолжительности разработки заключается в количественном измерении их соотношения. Если реализация проекта заняла в два раза больше времени, чем ожидалось, величина такого соотношения будет равна 2x; если же на реализацию ушло вдвое меньше расчетного времени, соотношение будет равно 0.5x.

Стив Макконнелл[23] создал диаграмму под названием «Конус неопределенности», которая характеризует диапазон величины ожидаемой ошибки при оценке затрат на протяжении всего срока реализации проекта. На его диаграмме верхняя и нижняя границы ошибки оценки представляют собой симметричные кривые, которые начинаются с уровней 4x и 0.25x, соответственно, в начале проекта, и плавно опускаются по мере продвижения разработки, сходясь в конце на нулевой отметке. Это иллюстрирует интуитивно понятный и подтвержденный практическим опытом факт, что в начале разработки величина ошибки при оценке затрат потенциально выше, чем ближе к завершению проекта.

Однако на практике я не сталкивался с тем, чтобы подобные ошибки оказывались симметричными. Другими словами, я не замечал, чтобы разработчики с одинаковой вероятностью опаздывали и завершали задачи раньше намеченного срока. В большинстве случаев задачи по разработке программного обеспечения занимают больше времени, чем предполагалось изначально. И хотя некоторые действительно выполняются досрочно, количество сэкономленного времени, как правило, оказывается намного меньшим, чем масштабы отрицательных сюрпризов. Почему так происходит? Чтобы объяснить асимметричную природу ошибок в оценке затрат на создание программного обеспечения, я процитирую эпистемолога и бывшего министра обороны США Дональда Рамсфелда:

«Существуют известные нам известные. Это вещи, о которых мы знаем, что мы о них знаем. Мы также знаем о существовании известных нам неизвестных. То есть мы знаем, что есть некоторые вещи, о которых мы не знаем. Но есть и неизвестные нам неизвестные. Это то, о чем мы не знаем, что мы о них не знаем».

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

Допустим, я подсчитал, что выполнение задачи A займет у меня пять минут, а выполнение задачи B – пять месяцев. С обеими задачами могут быть связаны неизвестные мне неизвестные. Однако неопределенность не является линейной при увеличении масштаба задачи, о чем свидетельствует верхняя кривая конуса неопределенности. Вероятность того, что пятиминутное задание выйдет из-под контроля, довольно мала. В отличие от нее, пятимесячная задача, которая более чем в 30 000 раз масштабнее, имеет гораздо больше шансов на то, что с ней могут быть связаны неизвестные нам неизвестные факторы.

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

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

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

Основные принципы гибкой разработки были изложены в «Манифесте Agile», который был написан в 2001 году (вы можете ознакомиться с Манифестом и принципами Agile по ссылке: http://agilemanifesto.org). Agile поощряет раннюю и непрерывную поставку работающего программного обеспечения с ориентацией на создание ценности для потребителей. Ключевой частью Agile является определение продукта с точки зрения потребителя и использование с этой целью пользовательских историй. Как уже было сказано в главе 6, история пользователя – это краткое описание преимуществ, которые должен предоставлять конкретный функционал. Это описание включает как самого персонажа – для которого предназначены эти преимущества, так и его цели. Хорошо написанные пользовательские истории обычно соответствуют шаблону:

Я как [тип пользователя]

хочу [что-то сделать],

чтобы [получить желаемую пользу].

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

Существует несколько различных разновидностей Agile-разработки, включая экстремальное программирование (сокращенно XP) и бережливую разработку программного обеспечения. Далее я приведу краткий обзор двух наиболее часто используемых методологий Agile: Scrum и Канбан.

Scrum

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

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

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

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

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

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

Рисунок 12.1 дает наглядное представление о рабочем потоке, совещаниях и подведении итогов, согласно принципам Scrum.


Рисунок 12.1. Структура Scrum


Каждый спринт команда начинает с проведения совещания по планированию спринта, на котором принимается решение, какие пользовательские истории будут реализованы в ходе очередной итерации. Отобранные истории перемещают из бэклога продукта в бэклог спринта. Частью этого процесса является оценка масштаба каждой истории, которая осуществляется с использованием оценочных баллов, отражающих относительную трудоемкость реализации конкретной истории. Сам процесс оценки часто является скорее искусством, чем наукой. В разных источниках вы можете найти множество используемых систем начисления баллов. Некоторые из них позволяют присваивать истории любое количество баллов: 1, 2, 3, 4, 5, 6 и так далее. Распространенным подходом является использование ряда Фибоначчи, где допустимыми значениями являются числа: 1, 2, 3, 5, 8, 13 и так далее. Преимущество такого подхода заключается в том, что он лучше отражает различия между разными парами рядом стоящих оценок. Другой популярной системой, которая в еще большей степени отражает различия в оценочных значениях, является шкала, построенная на «степенях двойки»: 1, 2, 4, 8, 16 и так далее. Еще один популярный метод основан на «размерах футболки» и использует для оценки масштабов пользовательских историй обозначения, обычно применяемы к размерам одежды: S, M, L, XL. Истории, набравшие наибольшее количество баллов в любом из применяемых диапазонов оценок, имеют значительную степень неопределенности и должны быть разбиты на более мелкие истории (см. главу 6). Истории, которые слишком велики для того, чтобы их можно было завершить за одну итерацию, называют эпопеями. Прежде чем добавить их в спринт, они в обязательном порядке должны быть разбиты на части. Многие применяемые в Agile инструменты отслеживания позволяют использовать эпопеи для создания связанных историй и управления ими на протяжении нескольких итераций.

Если описанный оценочный подход выглядит для вас немного абстрактным, то это лишь потому, что он таковым и является, – по крайней мере, на первый взгляд. Его цель состоит в том, чтобы определить работоспособность команды, отслеживая, сколько баллов она способна отработать на каждой итерации. Данный показатель называют скоростью работы команды. При известной средней скорости команды этот показатель используется для планирования спринтов. Таким образом, несмотря на то что система балльной оценки поначалу кажется несколько оторванной от реальности, она успешно применяется для определения эмпирических значений. Чтобы рассчитать скорость работы, каждая пользовательская история должна быть оценена в числовом выражении (в случае применения в качестве оценок размеров футболки необходимо соотнести каждый размер с определенным количеством баллов).

На Рисунке 12.2 представлен пример того, как команда отслеживает свою скорость на протяжении нескольких итераций. По горизонтальной оси показана пронумерованная последовательность итераций. Вертикальная ось показывает количество отработанных баллов. На протяжении приведенных на рисунке 12 итераций скорость работы команды была переменной (от 22 до 40 баллов), что является нормой. Несмотря на подобную изменчивость, линия тренда показывает, что с течением времени команда неуклонно увеличивала скорость своей работы.


Рисунок 12.2. Скорость работы команды


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

Покер планирования – популярная техника получения быстрой, но при этом надежной оценки пользовательской истории. Все члены команды получают набор карт, каждая из которых соответствует одному из возможных значений оценки (например, 1, 2, 3, 5 и 8 баллов). После обсуждения истории каждый участник независимо от других выбирает карту, соответствующую его оценке истории в баллах. Затем все участники одновременно вскрывают свои карты. Если в предъявленных оценках наблюдается относительный консенсус, это говорит в пользу их большей точности. Если в оценках имеются существенные расхождения, обсуждение истории продолжается с целью приближения к согласию. При этом каждую историю часто разбивают на набор задач по кодированию. Это позволяет гарантировать, что при оценке трудозатрат были объективно учтены все известные факторы. Кроме того, оценить масштаб каждой из небольших задач обычно легче, чем всю историю целиком. Объем таких задач некоторые команды измеряют все также в баллах, другие предпочитают оценивать их в часах работы. Иногда разработчики не утруждают себя оценкой масштаба отдельных задач, ограничиваясь оценкой на уровне истории.

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

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

Реализация пользовательских историй происходит, начиная с верхней части бэклога спринта. При этом члены команды взаимодействуют между собой по мере необходимости. Существует множество Scrum-инструментов, помогающих командам управлять своей работой и отслеживать результаты. Среди наиболее популярных из них: JIRA Agile, Rally, VersionOne и Pivotal Tracker. Все они облегчают планирование спринтов и бэклогов, а также общее управление процессом. Члены команды используют их, в том числе, для отслеживания хода реализации каждой пользовательской истории, например, путем присвоения ей различных статусов готовности: «для разработки», «в разработке», «кодирование выполнено», «готово».

В целях отслеживания прогресса команды часто используют график выполнения спринта, который показывает, какой объем работы осталось выполнить для завершения итерации. На таком графике оставшийся объем работы отражается либо в баллах, либо в часах, в зависимости от выбранной единицы измерения. На Рисунке 12.3 показан пример дневного графика выполнения скрипта, где по горизонтальной оси указаны дни спринта, а по вертикальной – количество оставшихся до завершения баллов истории. График берет свое начало в «нулевой день» спринта с количеством не отработанных баллов, равным, в данном случае, 45. На горизонтальной оси отложены 10 дней, что соответствует двухнедельному спринту (учитываются только рабочие дни). В идеале, в конце спринта количество не отработанных баллов должно равняться нулю.

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


Рисунок 12.3. График выполнения спринта


Цель, которая должна достигаться в конце каждого спринта, состоит в «приращении» функциональности продукта. Руководство по Scrum предписывает командам определять, что именно в их случае будет подразумеваться под статусом «Готово». Многие команды понимают под готовностью так называемый «выпущенный продукт» или «потенциально выпущенный продукт». Во многих случаях количество выпусков продукта соответствует количеству итераций, когда результаты спринта представляются клиентам вскоре после завершения спринта. Другие разработчики организуют более длительные циклы, когда выпуск продукта происходит по результатам нескольких спринтов. В любом случае цель состоит в том, чтобы к окончанию спринта обеспечить готовность продукта к выпуску. По завершении каждого спринта члены команда проводят обзорное совещание по спринту (также называемое демонстрационным совещанием), на котором они показывают результаты своей работы. Это позволяет гарантировать, что продукт работает должным образом, и делает прогресс команды более заметным. В идеале для участия в таких совещаниях приглашаются клиенты или иные заинтересованные лица, чтобы они могли оставить свои отзывы, которые будут учтены при проведении последующих спринтов.

Как и другие Agile-методологии, Scrum фокусируется на последовательном улучшении рабочих процессов. Для достижения этой цели команды проводят ретроспективы, в ходе которых обсуждают, как прошел их последний спринт, что сработало хорошо, что пошло не так, и какие улучшения стоит внедрить при проведении следующего спринта. Некоторые команды проводят такие обсуждения после каждого спринта; другие делают это по итогам двух или трех спринтов.

Это был лишь краткий обзор методологии Scrum – если вы хотите узнать о ней больше, ознакомьтесь с последней версией руководства по Scrum по ссылке: http://scrumguides.org.

Канбан

Другой популярной разновидностью Agile-разработки является Канбан – процесс, созданный на основе системы, разработанной автоконцерном Toyota для улучшения сборки автомобилей. Система Toyota ориентирована на производство по принципу «точно в срок» и ликвидацию отходов (издержек). Я изучал оригинальную систему Канбан и принципы бережливого производства во время обучения в аспирантуре Технологического института Вирджинии.

На производстве работники используют бумажные карточки – «канбан» – в качестве сигналов, передаваемых на предыдущий этап процесса, о необходимости пополнения запасов (заготовок). Канбан был адаптирован для целей разработки программного обеспечения с применением виртуальных карточек, каждая из которых представляет находящееся в работе задание, но при этом уже не выполняет сигнальной функции. Основным принципом Канбана является визуализация рабочего процесса. Каждая карточка представляет собой историю пользователя или относящееся к ней задание для разработки. Карточки помещают на специальную канбан-доску, состоящую из набора столбцов, каждый из которых соответствует определенной стадии рабочего процесса. Столбцы расположены слева направо в том порядке, в котором выполняется работа. Пример канбан-доски приведен на Рисунке 12.4. Здесь вы можете видеть следующий набор столбцов (стадий рабочего процесса) слева направо: «Бэклог», «Подготовлено», «В процессе разработки», «Разработка завершена», «В процессе тестирования», «Тестирование завершено» и «Выпуск», которые определяются следующим образом:

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

• Подготовлено: задания, которые были взяты из бэклога, и готовы к передаче в разработку.

• В процессе разработки: задания, разработка которых происходит в данный момент.

• Разработка завершена: задания, прошедшие этап разработки, но еще не переданные на тестирование.

• В процессе тестирования: задания, находящиеся в процессе тестирования.

• Тестирование завершено: задания, которые успешно прошли тестирование, но еще не были выпущены.

• Выпуск: задания, которые были выпущены после их разработки и тестирования.


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


Рисунок 12.4. Пример канбан-доски


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

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

В Канбане количество заданий, находящихся в активном состоянии, регулируется путем ограничения объема «незавершенных процессов» или сокращенно – НЗП. Команда определяет максимальное количество карточек, которое может накапливаться в каждом столбце, что представляет собой лимит НЗП. Члены команды последовательно перемещают карточки заданий между этапами работы. Однако они могут перенести карточку в следующий столбец только в том случае, если там имеется свободное место (то есть лимит карточек, находящихся в следующем столбце, еще не исчерпан). Это правило помогает выровнять процессы обработки и добиться стабильного рабочего потока. Командам предписано периодически корректировать установленные лимиты НЗП в целях оптимизации рабочего процесса. На канбан-доске размер лимита НЗП указывается над каждым столбцом. Как показано на Рисунке 12.4, команды часто используют единый лимит НЗП для связанных стадий одного этапа – «В процессе» и «Завершено». Например, общее количество карточек в столбце «Разработка» (включая обе его стадии: «В процессе» и «Завершено») не может быть больше трех. Это помогает стимулировать более быстрое продвижение карточек, находящихся в ожидания обработки.

Возьмем для примера ситуацию, представленную на Рисунке 12.4. Когда разработчик завершит работу над заданием D, он переместит его карточку из столбца «В процессе» в столбец, соответствующий стадии «Завершено». Однако при этом он не сможет перенести задание F из состояния «Подготовлено» в столбец «Разработка», поскольку лимит НЗП для этой стадии, равный трем карточкам, уже исчерпан. Аналогично, когда тестировщик завершит работу с заданием B, он переместит его карточку в столбец «Тестирование завершено», но не сможет взять в работу задание C, поскольку для стадии «Тестирование» исчерпан лимит НЗП, равной двум карточкам. Для продолжения работы необходимо «вытолкнуть» одну из карточек из столбца «Тестирование завершено». Как только это произойдет, задание C может быть переведено в состояние «В процессе тестирования», что, в свою очередь, освободит место в столбце «Разработка» для задания F.

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

Основное внимание в Канбане уделяется рабочему потоку. Здесь нет ограниченных по времени итераций, как это принято в Scrum. Карточки рабочих заданий непрерывно перемещаются слева направо по канбан-доске по мере выполнения работы. В Канбане не применяется обязательная оценка масштаба пользовательских историй, поэтому Scrum-концепция скорости выполнения работы (количество баллов пользовательских историй, отрабатываемых за одну итерацию) в этом случае не работает. Тем не менее, вы можете измерить так называемую пропускную способность команды, просто оценив количество рабочих заданий, выполненных за определенный промежуток времени, например, 10 заданий в неделю. Если вы отслеживаете изменение производительности работы вашей команды во времени, то она должна увеличиваться за счет постепенного совершенствования рабочих процессов и накопления опыта.

Двумя наиболее часто используемыми показателями в Канбане являются продолжительность цикла – среднее количество времени, проходящего с момента начала разработки до момента выпуска; и время выполнения заказа – среднее количество времени, проходящего с момента создания заказа (например, по запросу клиента) до момента сдачи готового результата работы. Важно отметить, что продолжительность цикла и время выполнения заказа не обязательно коррелируют с затраченными усилиями. Так, непосредственно разработка и тестирование может занять всего час, но при этом время выполнения окажется гораздо большим, если задание долго лежало в очереди на отработку.

Вы можете визуализировать ход работы в системе Канбан с помощью диаграммы кумулятивного потока (Рисунок 12.5), которая показывает, сколько карточек заданий находилось в каждом из рабочих состояний в конце каждого дня. Для простоты на Рисунке 12.5 отслеживаются только три вида рабочего состояния: «Бэклог», «В процессе» и «Завершено». Вы можете видеть, что продолжительность цикла измеряется горизонтальной толщиной слоя, относящегося к заданиям, находящимся «В процессе», а показатель времени выполнения равен суммарной горизонтальной толщине слоев, отражающих количество заданий в «Бэклоге» и «В процессе». Количество НЗП равно вертикальной толщине слоя, характеризующего количество заданий, находящихся «В процессе».


Рисунок 12.5. Диаграмма кумулятивного потока


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

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

При существенном различии масштабов выполняемых рабочих заданий можно наблюдать расширение диапазона значений продолжительности цикла, поскольку небольшие задания отрабатываются быстрее, чем более масштабные. Некоторые практикующие Канбан разработчики применяют оценку масштабности заданий, используя описанную выше систему, основанную на размерах футболок (S, M, L и так далее). Это позволяет обеспечить получение более адекватных значений показателя продолжительности цикла; разные значения данного показателя соотносятся с оценками сложности отрабатываемых заданий.

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

Инструменты Канбана

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

Однако существует множество цифровых инструментов для управления канбан-процессами. Одним из наиболее популярных приложений для визуализации канбан-доски в ходе разработки программного обеспечения является Trello. На самом деле, многие используют Trello для управления и другими рабочими процессами. Это приложение особенно популярно среди менеджеров по продуктам и дизайнеров. Они используют собственные рабочие панели, которые могут подключаться к канбан-доскам разработчиков. Многие канбан-команды используют такие приложения, как JIRA Agile, SwiftKanban и LeanKit.

Еще одним достойным внимания приложением является Pivotal Tracker, хотя оно и не относится к инструментам, специализированным для Канбана. Я использовал Tracker при создании нового продукта, когда получал полезный опыт работы с Pivotal Labs. Это приложение использует виртуальную доску со столбцами, отведенными для каждого из заранее определенных рабочих состояний. Данный инструмент поддерживает интересное сочетание Канбана и Scrum (существует даже Agile-методология под названием «Scrumban», которую будет полезно изучить, если эта идея выглядит для вас привлекательной).

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

Выбор правильного метода Agile-разработки

Теперь, когда у вас есть общее представление о Scrum и Канбане, осталось решить, какой из методов больше подходит для использования в вашем конкретном случае. Несмотря на то что приверженцы каждой из этих методологий видят в них серьезные различия, на самом деле оба подхода построены на общих принципах Agile. Я обнаружил, что Agile-фреймворки подобны обуви: чтобы понять, насколько хорошо вам подходят те или иные туфли, их нужно просто примерить. Разумный выбор подходящей методологии состоит в том, чтобы поочередно опробовать их в течение нескольких месяцев. Многие команды начинают с того, что пробуют применять либо Scrum, либо Канбан. Если методология работает хорошо, они продолжают ее придерживаться. Если нет, переходят к следующей. Примерив обе «пары обуви», команда получит все необходимое, чтобы решить, какая из них подходит ей лучше.

Тем не менее, вот несколько советов, которые увеличат шансы начать «выбор обуви» с наиболее подходящего варианта: Канбан, как правило, подходит для небольших команд разработчиков. Меньшие накладные расходы и отсутствие заранее определенной продолжительности итерации могут обеспечить более быстрый выпуск продукта. Но, по мере того как компания разрастается до нескольких команд разработчиков, применение Канбана может становиться все более сложным. Отсутствие строго определенного графика выполнения работы может усугубить ситуацию, поскольку многочисленным группам разработчиков требуется больше времени на коммуникации, чтобы оставаться на одной волне. Команды, которые имеют хороший опыт совместной работы, способны масштабировать Канбан до больших размеров без негативных последствий. Но, если в вашей компании есть несколько команд, которым необходимо координировать свою работу, то Scrum с его предсказуемым темпом разработки может оказаться более полезным.

Идея жестких плановых сроков запуска новых продуктов плохо соотносится с любыми методами гибкой разработки. Большинство компаний, применяющих «водопадный» подход, привыкли к тому, что у них есть нисходящая дорожная карта, которая диктует, какие функции они должны запускать каждый месяц или квартал, хотя эти сроки часто оказываются фикцией из-за регулярных задержек. При переходе на Agile многие из них по-прежнему придерживаются «водопадного» подхода в отношении бэклогов своих продуктов. Мне нравится использовать термин «Agilefall»[24] для описания компаний, переживающих трудности перехода с «водопадного» подхода на Agile и пытающихся поначалу усидеть сразу на двух стульях. Если вашей команде будет трудно отказаться от «подушки безопасности» в виде жестких сроков запуска, то вам, скорее, подойдет Scrum, нежели Канбан. По крайней мере, используя Scrum, вы знаете, что определенный объем работ будет выполнен к концу каждой итерации, и можете примерно оценить, сколько спринтов потребуется для запуска той или иной функции. Большинство команд, работающих по Канбану, не тратят время на оценку трудоемкости или планирование сроков завершения работ. Тщательно отслеживая продолжительность цикла и используя простые статистические методы, даже в случае с применением Канбана можно делать относительно достоверные прогнозы в отношении срока запуска продукта, однако лишь немногие команды разработчиков могут похвастаться настолько высоким уровнем точности отслеживания своих рабочих процессов.

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

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

Возможно, совместное посещение членами команды тренинга по Agile стнет в такой ситуации весьма удачным решением. Я знаю множество примеров, когда команды внедряли новую методологию разработки в условиях отсутствия достаточного уровня понимания у всех участников. Неудивительно, что многие из этих команд испытывали трудности. Прежде чем внедрять новую методологию, неплохо было бы оценить степень готовности каждого члена команды. Даже если некоторые из них имели дело со Scrum или Канбаном на предыдущих местах работы, есть вероятность, что практическое применение любой из этих методологий имело там свои особенности. Если вы не будете устанавливать для членов команды новых ожиданий, они, скорее всего, решат, что вы следуете тем методам, с которыми они уже знакомы. Очень важно, чтобы все участники одновременно услышали одно и то же объяснение того, как должен протекать процесс разработки продукта. Это позволит гарантировать наличие одинакового понимания, отсутствие недоразумений и повышение производительности.

Достижение успеха с помощью Agile

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

Взаимодействие внутри команды

Одной из основ Agile является тесное межфункциональное взаимодействие, под которым подразумевается свободное постоянное общение между менеджерами по продуктам, дизайнерами, разработчиками, тестировщиками и любыми другими членами команды. Важно избегать создания изолированных подсистем, в которых каждая функциональная группа живет собственной жизнью и перебрасывает свою часть продукта «через стену» для перехода на следующий этап рабочего процесса. Живые коммуникации в режиме реального времени имеет решающее значение для достижения максимального взаимопонимания и высокой скорости работы команды. Эффективность совместной работы поддерживается также за счет использования таких средств коммуникации, как чаты, инструменты для отслеживания разработки (например, JIRA Agile), а также приложения для совместной работы с базами знаний (например, wiki или Google Docs).

Каждая функция должна быть задействована на протяжении всего процесса разработки, хотя вполне естественно, что на определенном этапе какая-то из них будет задействована в большей степени, если ей определена ведущая роль. Короче говоря: менеджеры по продуктам пишут пользовательские истории, затем проектировщики создают соответствующие артефакты, для которых разработчики пишут программный код, после чего тестировщики проводят проверку полученного результата. Каждый занят своим делом, но при этом разработка продукта – это командный вид спорта. Разработчики и тестировщики должны в определенной степени участвовать в ранних стадиях рабочего процесса, чтобы понимать, на чем основаны пользовательские истории, UX-дизайн и другие базовые решения в отношении продукта. Они должны быть заинтересованы в том, чтобы задавать вопросы и вносить свой вклад на всех этапах рабочего процесса. Аналогичным образом менеджеры по продуктам и дизайнеры должны быть в курсе событий, происходящих в зоне ответственности разработчиков и тестировщиков, тем более что там часто возникают непредвиденные вопросы или неполадки. В Intuit у нас была любимая поговорка: хорошие идеи приходят отовсюду. О достигнутом внутри команды уровне сотрудничества можно судить по тому, насколько чаще члены команды, говоря о своих коллегах, употребляют местоимение «мы» вместо «они».

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

Жесткая расстановка приоритетов

Вы должны поддерживать актуальность бэклога с учетом приоритетности входящих в него заданий. Важно иметь четкое представление о наборе пользовательских историй, которые планируется отработать в следующем цикле, как только для этого появятся ресурсы. Применение такого подхода позволяет действовать быстро. Команды разработчиков высокотехнологичных продуктов обычно работают в динамичной среде, для которой характерна быстрая смена требований и приоритетов. При этом явно недостаточно присваивать заданиям такие нечеткие приоритеты, как высокий, средний и низкий. Если в бэклоге будет 15 заданий с высоким приоритетом, то как понять, к какому из них разработчик должен приступить в первую очередь? Поэтому необходимо дополнительное ранжирование заданий, входящих в состав бэклога. Я являюсь сторонником жесткой расстановки приоритетов (в противовес расплывчатому ранжированию заданий). Четкая расстановка заданий внутри бэклога дает ясное понимание того, какое из них стоит первым в очереди на отработку. Это также значительно облегчает определение места в бэклоге для вновь поступающих заданий.

Тонкость заключается в том, что жесткая расстановка приоритетов не означает отсутствие гибкости этого процесса. Вы должны четко представлять себе приоритеты ранжирования в любой момент времени; но при этом также должны уметь быстро реагировать на изменение существующих или появление новых требований. Я вижу здесь аналогию с водой и льдом. Большую часть времени бэклог подобен льду: порядок ранжирования находящихся в нем заданий фиксирован – находится в замороженном состоянии. Но с появлением новых требований или изменением приоритетов вы на короткое время растапливаете лед, переводя его в жидкое состояние, чтобы произвести перенастройку. После определения новой очередности выполнения заданий вы снова замораживаете свой бэклог. Следование такому подходу гарантирует, что всякий раз, когда кто-то из членов команды обращается к бэклогу за получением нового задания, он имеет дело с его максимально актуальной версией. Таким образом, разработчик может просто брать задание, стоящее первым в очереди, ни с кем при этом не советуясь и не тратя время на получение дополнительных подтверждений.

Создавайте для разработчиков адекватное описание продукта

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

Опережайте разработчиков

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

Другими словами, к сроку окончания спринта N они должны уже подготовить артефакты проектирования для спринта N+1 или даже N+2. Конечно, для этого проектировщикам потребуются качественно написанные пользовательские истории, поэтому менеджеры по продукту должны в свою очередь опережать дизайнеров также на один или два спринта.

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

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

Разбивайте истории на фрагменты

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

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

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

Гарантия качества

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

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

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

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

Еще одним шагом в том же направлении является парное программирование – это метод, предусматривающий, что созданием программного кода одновременно и совместно занимаются сразу два разработчика. Они сидят рядом друг с другом за одним компьютером и клавиатурой, глядя в один и тот же экран. Разработчик, которому досталась роль «драйвера», занимается непосредственным написанием кода. Второй разработчик играет роль «наблюдателя» и просматривает код по мере его создания партнером. Затем они меняются ролями. Работа в паре способствует обучению и обычно приводит к улучшению дизайна и качества продукта. Парное программирование – это центральный принцип экстремального программирования, еще одной популярной методологии Agile.

Возвращаясь к теме обеспечения качества продукта, стоит отметить, что существует два основных типа QA-тестирования: ручное и автоматизированное. При ручном тестировании один или несколько человек проверяют функционал продукта, чтобы убедиться, что он работает должным образом. Ручное тестирование также называют тестированием по методу «черного ящика», потому что тестировщику не требуется иметь представление о том, как был создан продукт или какая технология лежит в его основе. Во многих компаниях имеются выделенные специалисты по контролю качества, нанятые на полный рабочий день. В компаниях, которые не могут себе позволить содержание профессиональных тестировщиков, бремя выполнения их функций ложится на других членов команды (чаще всего, разработчиков и менеджеров по продуктам). В таких случаях разработчики часто вынуждены тестировать свой собственный код. Одним из преимуществ наличия выделенных специалистов по контролю качества является то, что они с большей вероятностью обнаружат ошибки и недочеты, чем сам создатель проверяемого кода, поскольку проводят проверку свежим взглядом. Кроме того, выделенные специалисты обычно проводят тестирование более тщательно. Это объясняется тем, что, во-первых, это их основная работа и, соответственно, у них есть больше времени на ее проведение. Во-вторых, хорошие специалисты по контролю качества подходят к тестированию системно, что позволяет проводить проверку по большему количеству параметров. В-третьих, квалифицированные специалисты по контролю качества знакомы с проблемными местами программного обеспечения и распространенными ошибками, поэтому им бывает проще их обнаружить.

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

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

Второй из требующих проверки аспектов состоит в том, чтобы ни одна из имеющихся функциональных возможностей продукта не была непреднамеренно нарушена в процессе создания новой или улучшения существующей функции. Другими словами, после добавления в состав продукта функции D вы хотите убедиться, что функции A, B и C работают так, как они работали до внедрения функции D. Это называется регрессионным тестированием. В этом контексте слово «регресс» означает «ухудшение текущего состояния», то есть внесение в существующий функционал ошибки, которой там раньше не было.

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

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

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

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

Непрерывная интеграция

Многие команды для ускорения разработки продуктов применяют метод непрерывной интеграции. Чтобы объяснить, что это значит, нужно начать с описания того, как разработчики программного обеспечения осуществляют управление создаваемым кодом. Обычно для этого используют систему контроля версий, позволяющую отслеживать и управлять всеми вносимыми в программный код исправлениями. Контроль версий также упрощает процесс восстановления кодовой базы до любого предшествующего состояния, благодаря чему нежелательные изменения могут быть отменены. На момент написания этой книги, пожалуй, самой популярной системой контроля версий для Agile-разработки является Git.

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

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

Непрерывное развертывание

Многие команды, применяющие непрерывную интеграцию, также практикуют непрерывное развертывание, когда код, успешно прошедший все тесты, развертывается автоматически. Некоторые компании выполняют автоматическое развертывание в промежуточной среде (внутренняя среда, к которой клиенты не имеют доступа), в то время как другие осуществляют развертывание непосредственно в продуктовой среде. Все это требует автоматизации процесса развертывания. Прогресс в автоматизации операционных задач обусловлен развивающейся областью DevOps, которая фокусируется на создании и эксплуатации быстро меняющихся, адаптирующихся к масштабированию систем. Ключевым элементом системы непрерывного развертывания является возможность автоматического отката, то есть быстрого возврата к предыдущей версии кода при обнаружении каких-либо проблем. Для этого используются метрики, позволяющие отслеживать работоспособность продукта.

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

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


В этой главе было рассмотрено множество вопросов, связанных с разработкой продукта. Я поделился с вами советами, относящимися к этой области, и представил обзор нескольких важных концепций. Многим из затронутых здесь тем посвящены отдельные книги. Представленные лучшие практики – в области Agile-разработки, контроля качества и DevOps – позволили многим командам разработчиков повысить свой уровень мастерства и стать намного более эффективными. Общим для представленных идей является то, что все они помогают быстрее и с меньшими рисками создавать успешные продукты.

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

Глава 13