Говоря о качестве, обычно имеют ввиду некое соответствие требованиям. Часто под требованиями подразумевают те, что явно выдвинул заказчик, аналитик или кто-то другой, кто ставит задачи. Хуже, если они трактуются как неоспариваемые, и это неявно ведёт к самоцели — удовлетворить требования заказчика. Это часто происходит в аутсорсе, и такой фокус внимания негативно влияет на конечный результат — то, что видят и с чем работают пользователи.

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

Качество — это про «сделать классно» с точки зрения многих сторон: разработки, заказчика и конечного пользователя.

Как это сделать? Сложно. Начать стоит с формирования mindset на «встроенное» качество. Расскажу о принципах, которые могут помочь в этом.

Качество — это про разработку, а не про тестирование

Почему качество жестко связывают с тестированием? Непонятно.

Качество определяется тем, как сделан продукт, а не тем, как он протестирован.

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

Итак, проектирование качества должно быть включено в реализацию. Качество включено в понятие «сделать».

Устойчивость к изменениям

В продуктах, которые живут долго, наряду с качеством сейчас (например, в момент после разработки фичи) важно качество системы, её устойчивость к изменениям. А изменения неизбежны.

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

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

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

Отсутствие детальных требований — не проблема

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

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

Детальные требования — это набор решений, вынужденно принятых вначале — тогда, когда информации для этого ещё слишком мало (об этом неплохо написано в Getting Real от Basecamp).

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

Конечно, нужно понимать, что мы делаем и зачем. Но детально описывать — не обязательно.

Баги неизбежны, но не в любом количестве

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

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

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

Не всё есть баг

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

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

Не нужно также тестировать компетентность исполнителя. Если вы тестируете задачи определенного разработчика больше только потому, что не доверяете его компетентности, то ваша проблема не в багах, а в недоверии или несоответствии уровня исполнителя сложности задачи. Людям нужно доверять. А тестировать — ПО.

Я также не вижу смысла в тестировании дизайн-макетов и написанных требований. Сами по себе, пока не реализованы, они не приносят ценности пользователям. Ревьюить, смотреть, обсуждать, совместно проектировать макеты и требования — можно и нужно. Но не стоит их формально тестировать.

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

Что тогда тестировать?

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

Задача тестировщика — не найти больше багов, а сделать так, чтобы их было меньше. В такой парадигме, наоборот: чем меньше багов найдено, тем лучше.

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

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

Тестирование эффективно, когда оно приносит дополнительную ценность, а не компенсирует недостатки разработки.

Итого

  1. Выполнение заранее составленных требований — не самоцель. Важнее сделать «классный» продукт в результате.

  2. Пользовательский опыт важен.

  3. Уровень качества задаётся при разработке. Тратя усилия на компенсацию разработки тестированием, мы лишаем себя возможности направить эти усилия на развитие разработки и, как следствие, качества.

  4. Тестирование — бонус, улучшающий систему, а не критическая необходимость.

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