Баг для лога

В предыдущем посте речь шла о пользе чтения логов при исследовании и описании дефектов ПО. Сегодня я хочу зайти немного с другой стороны.

Логи, безусловно, помогают исследовать поведение приложения, но в то же время логи – часть тестируемого продукта. То есть – их тоже можно тестировать. И вокруг них тоже могут водиться баги, а как же.

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

Полнота

Все ли операции, которые выполняет приложение, логируются (на том или ином уровне)? Тут, конечно, сразу возникает вопрос, что мы считаем операцией, должны ли все они действительно попадать в лог и т.д. Как обычно, все зависит от приложения. Где-то достаточно упомянуть самые верхнеуровневые бизнес-сценарии. В другом потребуется детальная информация о выполняемых запросах. Опять же, разным уровням логирования обычно соответствует и разная степень детализации.

Настраиваемость

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

Безопасность

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

Производительность

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

Читабельность

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

Документация

Упомянуты ли логи в документации? Описаны ли возможные/рекомендуемые настройки, советы по работе с логами? Нужна ли вообще подобная информация в документации?

Автоматизация

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

Добавить свой вариант

Я уверен, мой список далеко не полон.

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

Удачи вам и интересных логов.

Лог для бага

Опытным тестировщикам не нужно рассказывать о важности и пользе логов. Логи помогают исследовать проблемы, с их помощью быстрее и точнее локализуются дефекты, они могут рассказать, что происходит на самом деле (а не должно, как нам кажется, происходить).

Логи в чём-то подобны скриншотам – это такое же документальное и объективное свидетельство о работе приложения, с которым нет смысла спорить. Его можно обсуждать, изучать, уточнять сопутствующие условия, но факт есть факт, и отмахнуться от него не получится.

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

Загнал баг без лога – увеличил энтропию

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

Нашли проблему, что слоны с неба падают; написали, что автобус за углом стоит

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

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

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

А что вообще нужно знать, чтобы суметь выкусить адекватную «цитату» из лог-файла?

Для начала надо знать о существовании лога. Ну просто сам факт, что тестируемое приложение куда-то там что-то пишет о своей деятельности.

Второе, что потребуется узнать, – где хранятся логи.

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

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

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

Такие вот довольно очевидные и неоригинальные соображения и рекомендации.

Удачи вам, парящих слонов и логов без ошибок.

40 и 90

Как и многие, однажды я задумался о звучании чисел 40 и 90 в русском языке. Почему они — «сорок» и «девяносто», а не «четыредесять» и «девятьдесять»? В том же английском языке все честно: forty и ninety. И у нас вроде бы должно быть так же, если сравнивать с другими числами: «пятьдесят», «семьдесят». Что не так с этими двумя?

Наверняка я не знаю, конечно; разные есть версии на этот счет. Приведу те, что мне самому кажутся интересными и правдоподобными.

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

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

Впрочем, речь не о числах, интересно другое. Замеченная «странность мира» (нелогичные названия чисел) позволила по-новому взглянуть на числа и связь их названий с историей. То есть, заметив странное и покопав в этом направлении, я узнал что-то новое.

Странности мира — отличный источник знаний о мире.

Дефекты продукта — отличный источник знаний о продукте.

Есть куча других, более официальных, что ли, источников информации о продукте. Требования и спецификации, диаграммы и собственно код; много всего интересного, что можно изучать, анализировать и сравнивать друг с другом и действительностью. Однако, это все, в том или ином смысле, — документы. А обнаруженный дефект — он живой и светится. Особенно когда дефект нетривиальный, вызывающий искреннее изумление. Код не все станут читать; требования расскажут, что мы хотим сделать, но не расскажут как. Зато дефект наглядно продемонстрирует неожиданные выверты внутренней логики приложения. Или — не очень наглядно. Но появится повод поинтересоваться, а чего оно вообще так себя ведет?

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

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

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

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

Отчасти поэтому и нужны тестировщики — они смотрят на продукт по-своему.

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

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

Удачи вам, удивительных дефектов и интересных открытий.

Правильный багрепорт 2: точность описания и исследование проблем

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

В прошлом посте про качество багрепортов я писал, как не забыть упомянуть в описании проблемы важную информацию, которая в момент описания бага кажется очевидной (для тестировщика, находящегося в контексте собственных действий). Я тогда предлагал простое техническое решение, которое напоминало, что помимо самой проблемы нужно еще упомянуть ряд параметров окружения и ожидания тестировщика от поведения приложения. Однако подобным образом можно перечислить только небольшой набор самых общих параметров, упоминание которых необходимо, но зачастую недостаточно для исследования/понимания сути проблемы. Набор данных, которые стоит упомянуть в описании проблемы, разнится от проблемы к проблеме — где-то достаточно сделать скриншот, где-то нужно добавить логи, нередко и в базу данных заглянуть полезно. Как же понять, что писать, а что нет? Ведь избыток информации тоже может запутать разработчика.

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

Важно докопаться до сути проблемы и акцентировать на ней внимание в багрепорте. Так, в случае особого поведения при специфических настройках, с точки зрения приложения все может быть верно: оно и должно так себя вести. И программист закроет баг как «инвалид» — ведь в программе проблемы нет. Однако в продукте проблема есть: документация должна явно сообщать о подобных зависимостях поведения приложения от настроек. Соответственно, если в багрепорте написано про нехватку описания работы программы, фокус багрепорта смещается с непосредственной работы приложения, и становится понятно, что хотя приложение и ведет себя правильно, баг продукта тем не менее присутствует.

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

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

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

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

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

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

Статистика дефектов.

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

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

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

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

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

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

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

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

Ок, людей не анализируем. Что же тогда можно извлечь?

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

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

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

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

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

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

Аномалии в статистике — это повод задать вопрос: «Почему так?» И постараться на него правильно ответить.

Правильный багрепорт для всех и каждого

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

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

Проблема

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

С другой стороны работать с неясными багрепортами не хочется никому. Как же выходить из ситуации? Ну, вариантов может быть масса — наказание кнутом любителей навести тумана, поощрение пряником способных дать зацепки, проверка ясности изложения при приеме на работу… Все эти методы имеют право на жизнь (имхо, недолгую, но сейчас не об этом), однако все они содержат одну родовую травму: все они стремятся изменить человека так, чтоб он всегда говорил ясно, говорил то, что нужно, и не говорил при этом лишнего. Люди же, как известно, меняются небыстро. Хуже того: люди могут меняться в разные стороны. Совсем плохо: люди подвержены настроению и болезням, так что даже самый лучший тестировщик может однажды написать багрепорт, из которого на следующий день сам ничего не поймет. Хороший метод, который работает: менять не людей, а рабочее окружение.

Решение

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

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

История вопроса

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

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

Далее: мне стало лень каждый раз копировать информацию из текстового файла, и я вгляделся в интерфейс багтрекера (в моем случае это была Bugzilla). Оказалось, что там есть чудесная кнопка [Remember values as bookmarkable template]. При нажатии на нее Bugzilla генерит ссылку, которую можно добавить в закладки браузера; вкусность в том, что в этой сслыке сохраняются значения всех полей, в том числе текст введенный в поле для описания проблемы. Естественно, я тут же перенес данные из текстового файла в форму багтрекера и создал закладку. На качестве багрепортов это сказалось не сильно, но теперь на каждый баг я тратил чуть меньше времени.

И наконец: мы сели и подумали еще раз, как должны выглядеть наши багрепорты, чтобы быть более понятными окружающим. Мы выписали основные пункты, которые должны присутствовать, чтобы человек, читающий багрепорт понял, какая проблема имелась в виду, как ее воспроизводить и где проводить исследования (если они нужны). Там пунктов-то немного, и можно сказать что я их все уже перечислил. А потом мы сделали так, чтобы шаблон правильного багрепорта подставлялся в соответствующее поле багтрекера сразу и всегда, когда кто-то создает новый багрепорт. Ну да, пришлось залезть в код багтрекера и немного там повозиться — ну так на то и opensource. Зато теперь все и всегда видят, что в багрепорт нужно внести:

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

Выгода

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

Впрочем, не только новичкам.

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

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

Что произошло? Все просто: тестировщик сильно погрузился в контекст проблемы и забыл написать, что проблема заключается в том, что котенок не может перемещаться по наклонной поверхности с углом в 14 градусов, потому что при таком угле лапы уже скользят, а когти еще не выдвигаются. И актуально это для котят 17го поколения. А написал он просто: при 14ти градусах когтей еще нет. Что он хотел сказать? Непонятно. Ведь может и хорошо, что их нет.

А вот если бы багтрекер сразу предлагал шаблон бага, то тестировщик не смог бы описать баг только парой невнятных фраз. Само наличие шаблона уже слегка возвращает к реальной жизни, и человек задумывается: Ожидаемый результат? А кстати, что я ожидал-то? А, да: что котенок будет ходить, и когти выдвинет, если нужно. Как повторить проблему? Посадить котенка на доску и наклонить ее под нужным градусом. И так далее.

Резюме

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

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

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

Почему их так много?

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

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

Вот что получилось.

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

Если много дубликатов, то возможно, что

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

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

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

Что делать: объяснять нюансы работы приложения, улучшать архитектуру системы, внедрять/расширять тестирование методом белого ящика (white/glass box testing)

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

Что делать: отслеживать срок жизни багов, искать пути его сокращения

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

что делать: объяснять архитектуру приложения; при написании багрепорта думать, насколько общая функциональность затронута; слушать, по какому поводу матерят продукт коллеги.

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

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

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

Что делать: тщательней смотреть, к какому продукту относится проблема; если проблема описана для продукта А, а на самом деле беда в продукте К, то не переносить багрепорт в базу продукта К, а создавать там клон этого багрепорта.

Большое число невоспроизводимых багов говорит о

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

Что делать: максимально точно устанавливать и описывать сценарий повторения проблемы. Обычно это требует хорошего понимания работы продукта.

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

Что делать: исследовать описанную проблему в том окружении, где она была найдена.

— том, что часть из них инвалиды. Просто по каким-то причинам их не сочли таковыми.

 

Если много описанных проблем закрывается как Wontfix, то вероятно

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

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

Что делать: улучшать продукт; уточнять приоритеты тестирования.

 

Кроме того, для любой из этих резолюций (Invalid, Worksforme, Duplicate, Wontfix) ненормально большое количество таких багов может указывать на то, что резолюции по каким-то причинам используются неверно.

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

Кроме резолюций, можно обратить внимание и на статусы багов.

Много новых (New) багов:

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

Что делать: аккуратней работать, чтобы багов в целом было меньше. Включать в планы починку багов.

Много починеных, но не проверенных багов:

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

Что делать: тщательней планировать работу тестировщиков.

Высокий уровень Reopen’ов может указывать на то, что

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

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

Что делать: всем быть внимательней. Дьявол в деталях.

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

P.S.

Определения:

Возможные резолюции багов:

Инвалид (Invalid) — багрепорт, описывающий ситуацию, не являющуюся багом, система работает правильно.

Дубликат (Duplicate) — багрепорт описыват проблему уже описанную ранее в другом багрепорте

Невоспроизводим (Worksforme) — при попытке воспроизвести проблему по описанию из багрепорта проблема не воспроизводится. С другой стороны нет и уверенности/доказательств, что это инвалид.

Оставлен (Wontfix) — багрепорт описывающий реальную проблему, которую решено не чинить.

Починен (Fixed) — багрепорт, описывающий реальную проблему, которая была починена в продукте.

Возможные статусы багов:

Новый (New) — решение по багу еще не принято (возможные решения: Invalid, Duplicate, Worksforme, Wontfix, Fixed)

Закрыт (Resolved) — багрепорт, по которому принято то или иное решение (возможные решения: Invalid, Duplicate, Worksforme, Wontfix, Fixed).

Проверен (Verified) — багрепорт, решение которого было проверено соответствующим подразделением, в процессе проверки не было найдено несоответствий.

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

Никто не любит «инвалиды». А зря?

Нередкая претензия к  тестировщикам со стороны разработчиков:

— Сколько можно плодить «инвалиды»? Достали уже. Вы б хоть немного думали перед забиванием багов!

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

Что делать, если число багов с резолюцией (resolution) INVALID зашкаливает? Очевидно, что такого быть не должно, но как бороться? Для начала — понять, в чем причина такого положения и бороться уже с причинами. А они могут быть разными, «тестировщики идиоты» — не единственная.

Небольшой список возможных причин:

1. Проблемы спецификации. Сюда относятся — устаревшая спецификация, невнятная спецификация (допускающая разные толкования), отсутствующая спецификация. В этом случае разработчик создает ПО так, как ему удобнее/понятнее. И тестировщик ожидает от программы такого поведения, которое ему кажется верным. И эти мнения редко совпадают.

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

Что делать? Договариваться. Вырабатывать культуру общения, когда мнение тестировщика не отметается с порога, а рассматривается всерьез. Привлекать третье лицо для независимого суждения. Объяснять подробнее свое мнение. А то опять же часто разработчик просто заявляет «obviously, INVALID», и все тут. А тестировщик, который потратил время на написание бага с подробной инструкцией воспроизведения должен теперь из этих двух слов понять, в чем он ошибся. Так начинаются холивары :). Объяснять почему баг инвалид тем более полезно в случае отсутствия документации. Тогда такой документацией в каком-то смысле становится сам баг-трекер: достаточно просто почитать инвалиды, и узнаешь много нового :).

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

Что делать? Повышать статус отдела тестирования. Объяснять, что спецификация, а не разработчик, определяет что и как должно быть сделано. Ограничить круг лиц, которые могут поставить багу статус INVALID.

3. Улучшения. Баги, которые призваны улучшить функциональность, но спецификация о таких улучшениях ничего не говорит.

Формально тут прав разработчик: спецификация такого не содержит, делать не будем. На деле такая формальная правота может привести к тому, что пользоваться продуктом почти невозможно.

Что делать? Аппелировать к общепринятым стандартам и best practices. Ввести процедуру расширения спецификации по запросу отдела тестирования. Превращать такие баги в feature requersts.

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

Что делать? Исправлять/улучшать/дополнять тестовую документацию. Можно завести в багтрекере отдельную компоненту для таких багов, переводить их туда и фиксить.

5. Невнятный багрепорт. Описание проблемы неполно, не хватает данных чтобы понять, что пошло не так или почему. Тестировщик недоисследовал проблему. Статус INVALID в таком случае вполне оправдан.

Что делать? Объяснять тестировщикам необходимость подробного описания («загнал баг без лога — увеличил энтропию»). Завести шаблон багрепорта и обязать всех следовать ему.

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

Что делать? Обучать тестировщиков тому, что надо тестировать, и смежным областям. Нередко разработчикам дают время разобраться со смежными вещами перед началом разработки, а тестировщикам нет. С этим нужно бороться. Полезно чтоб перед началом тестирования разработчик объяснил неочевидные нюансы работы приложения.

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

Что делать? Составлять тест-планы таким образом, чтоб подобных ситуаций было меньше. При изменении system-wide настроек предупреждать коллег об этом (голосом или почтой в зависимости от ситуации).

Как видно из этого списка, «инвалидные» баги могут возникать по вине всех участников процесса — аналитиков, разработчиков, тестировщиков. Качество продукта — общая забота, да. Никто не застрахован от ошибки. Дело не в том, кто виноват.

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

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