Продолжим?

В предыдущем посте “Тестировщики не нужны” я озвучил тезис о том, что тестировщики в хорошей команде разработки не нужны, или по крайней мере не нужны в той роли которую они сейчас выполняют: проверяя косяки за программистами.

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

В отсутствие строгой логической последовательности всё это выглядит как бред.

Ожидаемо мои тезисы подняли на смех. Тестировщики не нужны? Ну что за чушь!

Реакция на пост

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

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

Мне нравится тебя, Лень, читать, и твой блог. Ты опытный программист и т.д. Но тут лажа)

Евгений

Далее другие комментаторы повторяли ту же мысль: использование тестировщиков эффективно, так как их труд дешевле труда программистов, следовательно компания экономит деньги.

Так ли это? Экономит ли компания? Давайте копнём глубже и разберёмся.

Совершенный код и бережливое производство

Краткое отступление. Мои рассуждения помимо собственного практического опыта опираются на книги “Совершенный код” Стивена Макконнелла и “Бережливое производство” Дэниела Джонса и Джеймса Вумека.

Делая отсылки в тексте я имею в виду одну из этих книг.

Зачем вообще нам тестирование?

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

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

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

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

Раз ошибки неизбежны, то надо их поискать и исправить.

Вроде бы всё так и всё логично.

Но давайте задумаемся, а сколько стоит исправление ошибок?

Затраты на исправление ошибок на разных этапах

Отладка и исправление неправильного кода занимает 50% времени

Макконнелл, Совершенный код, с. 467

50% времени тратится на отладку и исправление кода. Это очень много. Получается, что ошибки удорожают разработку вдвое.

Поэтому будет очень выгодно свести их к минимуму.

Но это ещё не всё. Согласно тому же Макконнеллу, чем раньше обнаружена и исправлена ошибка, тем меньше затраты на её обнаружение и исправление.

Стоимость обнаружения ошибок

Как правило, эксперименты показывают, что инспекции обходятся дешевле, чем тестирование. В исследовании, проведенном в Лаборатории проектирования ПО, было обнаружено, что при чтении кода число дефектов, находимых в час, было примерно на 80% более высоким, чем при тестировании (Basili and Selby, 1987). В другой организации поиск дефектов проектирования с использованием блочного тестирования был вшестеро дороже, чем при использовании инспекций (Ackerman, Buchwald, and Lewski, 1989). Более позднее исследование, проведенное в IBM, показало, что на обнаружение каждой ошибки разработчики тратили 3,5 человеко#часа в случае инспекций кода и 15–25 в случае тестирования (Kaplan, 1995).

Макконнелл, Совершенный код, с. 465

Стоимость исправления ошибок

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

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

В одном из подразделений Microsoft обнаружили, что при использовании инспекции кода — одноэтапной методики — на нахождение и исправление дефекта уходит 3 часа, тогда как при использовании тестирования — двухэтапной методики — на это требуется 12 часов (Moore, 1992). Коллофелло и Вудфилд сообщили, что при разработке программы из 700 000 строк, над которой работало более 400 программистов, обзоры кода имели гораздо более высокую экономическую эффективность, чем тестирование: прибыль на инвестированный капитал была равной 1,38 и 0,17 соответственно (Collofello and Woodfield, 1989).

Макконнелл, Совершенный код, с. 466

Подробнее про устранение ошибок

В этом пункте статьи я процитирую Макконнелла со страницы 26 по 28, без оформления в виде блока цитаты.

Для краткости опускаю ссылки на источники, вы можете найти их в самой книге.

Начало цитаты

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

Ученые из компаний Hewlett Packard, IBM, Hughes Aircraft, TRW и других организаций обнаружили, что исправление ошибки к началу конструирования обходится в 10–100 раз дешевле, чем ее устранение в конце работы над проектом, во время тестирования приложения или после его выпуска.

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

Вот данные об относительной дороговизне исправления дефектов в зависимости от этапов их внесения и обнаружения:

Стоимость исправления дефекта в зависимости от этапа внесения и этапа обнаружения, таблица

Эти данные говорят, например, о том, что дефект архитектуры, исправление которого при проектировании архитектуры обходится в $1000, может во время тестировании системы вылиться в $15 000.

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

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

Конец цитаты, Макконнелл, Совершенный код, с. 26-28

Стандартный подход к проверке кода

Как обычно выглядит цикл разработки в любой компании?

Ставим задачу, пишем код, проверяем, выпускаем. Так?

В этом случае обнаружение и исправление ошибок находится в конце цикла разработки.

Ловим их прежде чем выпустить новую версию кода в продакшен.

Всё ещё дешевле, чем править баги обнаруженные уже после релиза, но дороже чем править баги на более ранних этапах.

Поток ценности и обратный поток

Поток ценности

В бережливом производстве есть понятие “поток ценности”. Это действия, выполняемые для того чтобы доставить ценность заказчику.

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

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

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

Постойте, но как же лишние, разве можно не проверять код?

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

Обратный поток

Также в бережливом производстве есть понятие “обратный поток”. Это если мы двигались по потоку создания ценности, потом что-то случилось и нас отбросило назад, и мы вынуждены проделывать весь или часть пути заново.

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

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

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

Уменьшение количества ошибок

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

Я говорю о системном уменьшении количества появляющихся ошибок вообще, с течением времени.

Представим два завода.

Один завод производит в месяц 1100 деталей, из них 500 отбраковывает (10% брак), на выходе 1000 качественных деталей. И так месяц за месяцем.

Второй завод производит в первый месяц 1100 деталей с браком 10% и результатом 1000, второй месяц 1050 деталей с браком 5%, и третий месяц 1010 деталей с браком 1%.

Несмотря на то что результат на выходе будет одинаковый (1000 деталей в месяц), второй завод повышает свою эффективность и тем самым создаёт запас ресурсов на проиводство большего количества деталей, если потребуется.

Но как добиться системного уменьшения ошибок?

Боремся со следствиями вместо причин

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

Да, у нас есть баги, главное “не делайте их слишком часто”. Никто не измеряет частоту багов, поэтому “слишком часто” определяется субъективными ощущениями.

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

Программисты косячат, тестировщики ловят их на этом, все при деле. Эффективная работа?

Метод “пять почему”

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

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

Задаём вопрос “почему это произошло?”, устанавливаем причину, потом выясняем что к ней привело, и так пока не дойдём до истинной причины.

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

Устраняем причины ошибок

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

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

Что дешевле?

Если у нас есть отдел тестирования который просто “переваривает” всё что летит в прод, то затраты на него постянны.

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

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

Отдел тестирования будет сокращаться, вплоть до полного устранения.

Ноль тестировщиков содержать дешевле чем N тестировщиков, если N > 0.

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

Следовательно, системно уменьшая объём лишней работы программистов и тестировщиков, мы экономим деньги сильнее, чем просто наняв отдел тестирования.

Результат

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

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

Поток создания ценности “выпрямляется”, и каждая написанная строчка кода максимально быстро попадает в прод, доставляя ценность заказчику.

Мы выигрываем как во времени доставки ценности, так и в трудозатратах.

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

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