|
Автор: Майкл Болтон (Michael Bolton) Оригинал статьи Перевод: Ольга Алифанова
В мире разработки программного обеспечения популярна идея, что за тестирование отвечает вся команда.
Исходя из этого, некоторые люди встают на крайнюю позицию: раз уж тестируют все, специализированные тестировщики больше не нужны. Дескать, разработчики, или аналитики; или сами заказчики могут и сами выполнять тестирование.
Есть и противоположное мнение (что раздражающе часто исходит от самих тестировщиков): разработчики якобы не умеют тестировать, а потому каждая команда разработки обязательно должна иметь собственного тестировщика или даже целую команду тестирования.
Обе эти крайности — непродуманные и наивные. Это примеры того, что я называю «тирания слова всегда».
Глупо утверждать, что разработчики не умеют тестировать. В процессе написания продукта они постоянно что-то тестируют: пишут код, проверяют, работает ли он; если нет — чинят; если да — двигаются дальше. Разработчик не может стабильно писать полезный код, не проверяя хоть что-нибудь хотя бы время от времени. И всё же было бы опрометчиво полагаться на то, что у разработчиков всегда есть время, мотивация, стимул и нужный взгляд на вещи, чтобы полностью взять на себя весь объём тестирования.
Чтобы избежать крайностей, начнём с разумной части. Да, каждый член команды может участвовать в тестировании или помогать другим тестировать. Да, для разных людей тестирование означает разные вещи. То же касается и качества самого тестирования.
Большинство людей — не разработчики, и большинство программных продуктов создаётся именно для таких пользователей. Люди используют софт, потому что у них есть задача, которую нужно решить. Им нужно что-то, что поможет выполнить работу, разобраться в информации, проанализировать что-то или просто развлечься. Как мыслит пользователь: «Мне нужно решение моей проблемы». Пользователю неинтересно разрабатывать софт — именно поэтому он его покупает или просит кого-то его сделать. Разработчики, в свою очередь, обладают мотивацией, знаниями и навыками, чтобы сказать: «Я создам то, что решит твою проблему!» Поскольку пользователи знают, что им нужно, а разработчики знают, как это реализовать, обе группы должны быть способны качественно тестировать.
Качество тестирования подчиняется правилу относительности. Оно всегда существует в контексте — в системе связей между самим тестированием, состоянием продукта и задачами, которые тестирование должно решать в конкретной ситуации. Смысл, значимость и ценность тестирования зависят от точки зрения.
На восприятие ценности тестирования сильно влияет критическая дистанция — разница между точками обзора, между тем, насколько близко или далеко мы находимся от объекта наблюдения и оценки. Я считаю, что помимо точек зрения пользователя и разработчика, есть и ещё одна заслуживающая внимания точка.
Близкая критическая дистанция Критическая близость и точка зрения создателя
Довольно легко понять, как близость к коду — или, если точнее, критическая близость (постскриптум: понимаю, что «близкая критическая дистанция» звучит как логический узел, поэтому давайте называть это критической близостью) — помогает тестированию. В этом и состоит суть тестирования разработчиком, а также подходов «glass-box» или «open-box». Когда вы понимаете код и сам процесс программирования, вы с куда большей вероятностью заметите в нём проблемы. Если вы знаете, как работают функции продукта и как они реализованы в коде, вам проще придумать, какие проблемы можно протестировать, как и когда это лучше делать. Даже если вы не знакомы с конкретным кодом продукта, общее знание принципов программирования помогает проводить его ревью или тестирование.
Человек, находящийся в наивысшей критической близости к коду, — это, конечно, сам его автор. Именно он лучше всех ориентируется в логике, чаще всего пишет без ошибок, но иногда и оступается. Все разработчики сталкиваются с недопониманием, мелкими ошибками и незначительными проблемами. Точно так же, как автор текста замечает и исправляет множество своих опечаток и неудачных формулировок прямо в процессе написания, программист на лету выявляет и устраняет массу багов, пока пишет код. Дисциплинированные разработчики применяют практики и инструменты, позволяющие предотвратить ускользание таких ошибок: разработка через тестирование (TDD), тесты до написания кода (test-first development), встроенные проверки в IDE, запуск кода сразу после сборки, контрактное тестирование… Все эти подходы дают немедленную обратную связь — сигнал, что в коде есть проблема. Это и есть тестирование на стадии высокой критической близости.
На первый взгляд может показаться, что такого тестирования вполне достаточно: кто, как не сам разработчик, лучше всего знает, как должен работать код? Не логично ли доверить всё тестирование ему? Раз уж он знает каждую строчку, разве его собственные проверки не докажут, что «всё работает»? Почему бы не поручить всё тестирование автору кода?
Одна из проблем с фразой «всё работает» в том, что она означает лишь: «на первый взгляд, требования в какой-то степени выполнены». Она не означает, что «все требования абсолютно всех полностью удовлетворены», или что «никаких проблем никогда не возникнет ни у кого». Некоторые баги легко заметить в процессе создания продукта — когда ты полностью погружён в работу. Но другие проблемы, наоборот, сложнее распознать именно потому, что ты слишком близко к ним находишься.
Создание требует концентрации. А когда мы на чём-то сфокусированы, мы неизбежно теряем фокус на всём остальном. Чтобы создать продукт, нам нужно видеть цель, представлять себе успех — а значит, как минимум частично отбрасывать мысли о возможных неудачах. Это не баг, а, скорее, фича: альтернатива — это «думать слишком много» (overthinking) или «паралич анализа» (analysis paralysis). Постоянная тревога обо всём и сразу может парализовать процесс.
Конечно, недомыслие — тоже проблема. Поэтому хорошие писатели и разработчики намеренно создают критическую дистанцию между собой и своей работой. Разумный создатель время от времени прерывает процесс и как бы выходит за рамки — чтобы оценить уже сделанное, посмотреть на это критическим взглядом, поискать в нём ошибки. Это требует смены мышления: от создателя к критически настроенному наблюдателю, от внутренней перспективы к внешней. Такой переход возможен, но требует немалых умственных усилий.
Есть ли способ его упростить? Вот один из них: бросить все на какое-то время. Всем нам знакомо чувство, когда спустя недели перечитываешь свой текст и думаешь - «Святые угодники, о чём я вообще думал, когда это писал?» Перерыв — хороший способ обрести критическую дистанцию. Но вот беда: у большинства разработчиков на такие паузы просто нет времени. Что тогда остаётся? Что ещё мы можем сделать?
Дальняя критическая дистанция и точка зрения разработчика
Привлечь кого-то со стороны, чтобы он взглянул на нашу работу — это мощный эвристический приём, позволяющий заметить то, что мы упустили. Именно поэтому у писателей есть редакторы. Это одна из причин существования парного или группового программирования. По той же причине ответственные разработчики просят других разработчиков провести ревью, а ответственные менеджеры поддерживают и поощряют такую практику. Когда один разработчик проверяет работу другого — это действительно хорошая идея.
Есть тут и социальный аспект: людям проще и естественнее развивать взаимное уважение, если у них есть общее поле знаний, умений и опыта. Критическая близость и социальная близость часто связаны одной и той же бечёвкой.
Разработчики, как правило, отлично замечают проблемы коде - особенно в чужом. Если в продукте есть проблемы, которые может найти другой разработчик, — значит, в нём есть проблемы. Кто, как не разработчики с глубоким знанием технологии, лучше всех заметят баги в коде? Так почему бы тогда не поручить всё тестирование разработчикам, всем разработчикам?
Начнём с довольно очевидного момента: да, точка зрения разработчика-ревьюера отличается от взгляда разработчика-создателя — и это помогает тестированию. Но разработчики всё равно не всегда и не во всём похожи на конечных пользователей.
Здесь в силу вступает проклятие знания: чем глубже ты забираешься внутрь продукта, тем сложнее тебе взглянуть на него глазами человека, который его просто использует. Как точно выразился Дэвид С. Платт, автор книги Why Software Sucks: «Познай своего пользователя, ибо он — не ты». Вот почему даже близкая критическая дистанция может сыграть злую шутку: если ты знаешь, как всё устроено изнутри, тебе легко не заметить проблемы, раздражающие тех, кто снаружи. А иногда можно и просто отмахнуться от этих проблем.
Даже если вы, как разработчик, очень стараетесь вжиться в мир пользователя, есть знания, которые невозможно полностью отбросить. Например, вы можете сопереживать человеку, который не читает по-английски. Но если вы читаете этот текст в оригинале, то, будь вы носителем языка или выучили его позже — гарантирую, вы никогда не увидите этот текст так, как его воспринимает человек, который только начал осваивать английский, который только пытается понять длинные слова и мои местами витиеватые конструкции. То же самое с программированием: если вы разработчик, вы никогда полностью не избавитесь от своей профессиональной оптики. Ваше восприятие всегда в какой-то мере будет окрашено знанием того, как оно устроено «под капотом».
Вот еще менее очевидный для разработчиков момент: код — это ещё не продукт. Да, продукт зависит от кода, но для пользователя продукт — это не набор строк в репозитории. Продукт — это опыт, услуги и польза, которые код приносит людям и организациям – тем, кто покупает продукт, тем, кто им пользуется, и тем, на кого эти пользователи работают. Как говорит Дэвид Платт, «Пользователь приходит к вам не за программой. Он приходит за тем, что программа делает».
Критическая дистанция с точки зрения пользователя
Пользователь смотрит на продукт с большого критического расстояния — вдали от «фасада из кода». Именно потому он чувствителен к проблемам, которые разработчик не замечает — или даже не считает проблемами. Что еще важнее, эти проблемы влияют на пользователя.
Некоторые продукты — например, API, фреймворки, библиотеки, инструменты разработки — создаются для разработчиков. Но и в этом случае: разработчик, использующий API, — это уже не тот, кто его писал. Он всё равно смотрит на продукт со стороны, без «инсайдерского» знания, доступного разработчикам, которые этот API построили.
Тестирование только с точки зрения разработчика — неполноценно. Если в тестировании участвуют пользователи, они находят баги, которые разработчики пропустят. А если пользователь находит проблему — значит, у продукта действительно есть проблема. Тогда может возникнуть новый вопрос: почему бы просто не отдать тестирование, неподвластное разработке, пользователям?
Ответить на него будет сложнее. В книге Кента Бека Extreme Programming — пожалуй, одном из первых манифестов гибкой разработки — говорится, что в проекте есть всего две роли: Программист и Клиент. Программисты оценивают код и функции, убеждаясь, что код делает то, что должен делать, а Клиенты оценивают пользовательский опыт, убеждаясь, что продукт их устраивает. Казалось бы, что тут может не хватать?
Но вот чего тут не хватает: активного, целенаправленного поиска неприятностей.
Критическая дистанция с точки зрения тестировщика
И разработчики, и пользователи, как правило, смотрят на продукт с оптимизмом. Как я уже отмечал и выше, и в прошлых статьях этой серии, разработчики сосредоточены на воображаемом успехе. Разработчик хочет что-то создать. В то же время тот, кто использует или заказывает продукт, хочет получить от него ценность. Пользователь хочет что-то сделать. И пользователи, и разработчики хотят, чтобы все было хорошо.
Но качественное тестирование требует другого подхода — критического. Нужно отбросить надежду, что всё работает, и целенаправленно искать, где что-то может пойти не так. Тому, кто активно и с оптимизмом создает продукт, понадобится переключиться на более пессимистичное видение и подумать о том, где и как что-то пойдет не так. Тестирование требует задач, которые до какой-то степени рушат первичную цель разработчика, его стремление закончить создание.
Иногда организации просят пользователей помочь с тестированием. Но и пользователям для успешного тестирования надо выйти за пределы обычного поведения. Даже тестирование через пользовательский интерфейс отвлекает их от их привычных целей и стремлений, разрушает их. Более того, большинство пользователей не ныряет под капот и не занимается намеренным развитием понимания продукта на техническом уровне – да они и не должны. Именно поэтому они и платят деньги разработчикам и компаниям. Тестирование противоречит основным задачам пользователя, его стремлению выполнить задачу.
Тестировщик — это другая роль. Главная задача ответственного тестировщика — понять текущее состояние продукта, особенно то, есть ли в нём проблемы, угрожающие ценности продукта – чтобы люди смогли принимать информированные решения. Когда речь заходит о проблемах, первичная задача тестировщика – сделать так, чтобы проблемы заметили.
Тестировщики находятся на более дальней критической дистанции от кода по сравнению с разработчиками. Их дистанция от продукта тоже больше по сравнению с пользователями. Но тестировщики располагаются на очень близкой критической дистанции, когда речь идет о проблемах – багах, ошибках, упущениях, рисках. Главная роль тестировщика – в изучении продукта образом, дополняющим и знания разработчиков о продукте, и возможные разочарования пользователей. Задача тестировщика – найти значимые проблемы, пока еще не поздно.
Чтобы замечать проблемы, нужно ставить под сомнение сам продукт, а также убеждения команды о его качестве. Критическая позиция — это исходная позиция тестировщика. Его цель — уберечь команду и бизнес от необоснованной уверенности. Тестировщик не визуализирует успех — он предвосхищает провал. Что может пойти не так? Где видны риски — а где они могут прятаться? Как мы можем сами себя обманывать? Начав с этих вопросов, мы изучаем то, что сделано командой, пробуем с этим поработать, смотрим на это критически и непрерывно сомневаемся в собственных и чужих убеждениях, касающихся созданного.
Конечно, разработчики тоже думают о возможных проблемах в своей работе, а пользователи время от времени сталкиваются с неприятностями. Смысл тут в том, что ни создатели, ни потребители не сосредоточены на поиске проблем как на своей главной задаче. Чтобы переключиться на такую позицию, нужно время и умственные усилия, затраченные ещё до того, как начнётся собственно тестирование. А на само тестирование тоже требуется немало сил и времени. Поэтому логичный обходной путь – выделить отдельную роль: человека, который занимается тестированием постоянно.
Критическая роль полезна на всех этапах и для всего, сделанного командой разработки — и в отношении уже реализованных функций, и на стадии обсуждения замыслов, требований и дизайна. Мой друг Джордж Динвуди предложил по этому поводу простую и запоминающуюся эвристику — он называет её «Три Товарища» (в честь довольно неудачного фильма, но название прижилось).
Вместо того чтобы ждать, пока задача попадёт в спринт и только тогда полностью её изучать, команда начала заранее обсуждать задачи, которые планировались к следующему спринту. Владелец продукта или аналитик — представитель бизнеса — спрашивали, есть ли у разработчика и тестировщика время вместе с ним посмотреть на задачу. Все трое вместе старались ответить на все вопросы, прежде чем считать задачу готовой к разработке.
Эти три роли были выбраны для «Трёх Товарищей» потому, что они предоставляют взаимно дополняющие, почти ортогональные взгляды на любой создаваемый продукт. Представитель бизнеса думает о том, чего бизнес хочет достичь, создавая этот продукт. Разработчик — о деталях реализации: какая информация нужна когда и какие технологии помогут достичь целей. Тестировщик — о том, что может пойти не так, как внутри системы, так и во внешних условиях, от которых она зависит.
Джордж подчёркивает ценность присутствия людей с разными ролями в одном месте и в одно время на раннем этапе процесса. Когда вместе работают владелец продукта, разработчик и тестировщик, у нас есть люди с разной степенью критической дистанции до области проблем, области решения и области рисков. В то же время при этом сокращается социальная дистанция между людьми и ролями. Это также позволяет гибко и мгновенно менять роли и позиции. Эти три роли образуют коллектив, что очень ценно — каждый получает пользу от знаний и идей других, а возможности коллектива почти наверняка превосходят сумму возможностей его членов.
Есть одна причина, по которой всё это может пойти не так — когда тестировщик ослабляет свою роль и критическую позицию. Это происходит, когда тестировщики не осознают важность критической позиции или когда они подвергаются давлению со стороны других членов команды, чтобы соответствовать их взглядам; когда от тестировщиков требуют доказать, что всё в порядке; когда у них недостаточно технических или аналитических навыков; или когда задача «закончить тест-кейсы» вытесняет настоящую цель — поиск проблем. Тестировщики должны культивировать критический настрой и исследовать продукт с целью найти действительно значимые проблемы — и для этого им нужны клиенты и организации, которые ценят работу тестирования.
В методологии Rapid Software Testing мы не утверждаем, что каждой команде разработки обязательно нужен выделенный тестировщик. Мы не говорим, что разработчики не могут или не должны тестировать. Мы также не считаем плохой идеей привлекать пользователей к тестированию — наоборот.
Однако мы утверждаем, что наличие человека в роли тестировщика — это мощный эвристический приём для быстрого достижения критической дистанции, облегчения переключения мышления, развития навыков тестирования и выполнения сосредоточенной работы по тестированию.
Эта статья (на данный, по крайней мере, момент) завершает серию. Обсудить в форуме |