Reproduce first debugging (отладка через повторение)

В TDD (Test driven development) есть простое правило - test-first. То есть, сначала напиши тест, а потом уже код. По сути это нужно для постоянного автоматического контроля того, что ты всё делаешь правильно. Сначала пишешь тест, он фейлится, ты исправляешь код, тест начинает срабатывать - цикл закончен.
А можно ли этот же подход перенести на другие области разработки? Например на отладку?


Конечно можно. Представляю вам мою адаптацию концепции TDD для отладки - Reproduce first debugging (отладка через повторение).



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

Многие баги кажутся достаточно простыми и их исправляют сразу без всяких проверок и повторений. И это кажется правильным, т.к. тратить часы на создание теста или установку энвайромента, если очевидно, что надо только в одном месте одну переменную увеличить на 1 - это перебор.
Но на самом деле тут всё также, как и с юнит-тестами. С одной стороны, хорошее покрытие юнит тестами уберегает от ошибок в будущем, а с другой - занимает больше времени в настоящем.
Также и с отладкой - повторить баг бывает в десятки раз сложнее и дольше, чем исправить его. Но зато исправление будет точным и правильным. А можно просто исправить что-то, что программист посчитал возможной причиной бага. Но можно ли быть увереным в правильности этого исправления, если баг не можешь повторить и исправление не можешь проверить? Риторический вопрос.


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


Но есть другой путь.
Можно потратить еще немного времени на этапе исправления бага и создать тест (system test, unit test, regression test - что угодно, что поможет поймать этот конкретный баг), который будет проверять наличие этого бага без сложной настройки энвайромента. Это может быть простой exe файл, скрипт на любом скриптовом языке, даже просто bat файл - что угодно, если вы можете запустить это и увидеть, есть ли баг или нет. Создать такой тест зачастую бывает непросто и надо признать - вообще-то это может занять даже еще больше времени, чем настройка энвайромента и ручное повторение бага.
Зато имея такой тест вы можете легко проверить исправление без нужды в ручном тестировании.
И, самое главное, вы можете встроить этот тест в свою систему автоматического тестирования, которая у вас, конечно же, есть. А если её и нет, то вы можете написать простой bat файл, который просто будет все эти тесты по очереди запускать. Даже такой bat файл даст вам +10 к уверенности в качестве продукта.


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

Понравилась статья? Подпишись на RSS!

Похожие записи:
Потоки и память
Знай свою память
Книги + программисты = деньги
Не будите спящего программиста
2 признака кода с душком: убей его и лови всё молча
Я умею программировать на С++!?

Рекомендую книги по этой теме:

18 комментариев к Reproduce first debugging (отладка через повторение)

  • хех. если бы все было так просто, а то регулярно попадаются баги, для воспроизведения которых надо гонять софтину три недели подряд на 4-х процессорном компутере :-)

    • Вот именно для таких случаев написать тест, который будет фейлиться быстро - это исскуство :)
      На прошлой неделе поймал баг, который случался раз в 100 лет. Исправил. Но подумал, что хорошо бы сначала репродуцировать его научиться. Написал тестовую апликуху, которая в много потоков слала сообщения и создавала жуткий стресс-тест. И он сработал - всего за 10-20 секунд баг проявлялся.
      И оказалось, что моё исправление от бага не спасло на самом деле :) И если бы эту тулзу не написал - еще бы через 100 лет опять получил бы этот баг.
      А так есть и тулза и ее можно встроить в систему тестов и баг исправлен 100%.

      • konstantin

        А в систему проверки билда тестовую аппликуху встроил?
        А то весь тру и насмарку пойти сможет, когда исправят твой фикс ;)
        Вот интересно, а кто и чем “реально” пользуется для запуска и проверки результатов работы таких “тестовых апликух”?

        • Пока не встроил, но встрою.
          У нас для запуска тестов есть спец. система, основанная на WMVare - там автоматически все билды устанавливаются и все тесты прогоняются.

  • dstd

    да, вспомнилась классификация багов: гейзенбаг, мандельбаг, шрёдинбаг и т.п. :) есть в википедии [напр., http://ru.wikipedia.org/wiki/Шрёдинбаг ]

  • возникает вопрос — почему этот баг не находился тестом?
    может стоит дописать тест так, чтобы он покрывал эту проблему?

    • Каким именно тестом? Юнит тестом?
      Так системные баги юнит тестами не находятся.
      Идея не нова и состоит как раз в том, чтобы на каждый баг писать тест :) Причем писать его ДО исправления, как и юнит тесты до написания кода.
      В итоге правим баг и заодно имеем тест, который нам будет в будущем помогать этот баг заново тестить.

  • dDIMA

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

    • Да, идея именно в этом. Чем сложнее и интереснее ошибка, тем должно быть важнее сделать для нее тест и научиться ее не просто повторять, а автоматически повторять в будущем.
      Тогда эта ошибка точно больше не появится случайно в будущем.
      Но это всё стоит денег и времени, а в геймдеве с этим обычно очень непросто, а особенно сейчас :)

      P.S.: а с другой стороны - играю сейчас в изданную вами Kings Bounty и ни одного глюка пока не заметил. Не только нет серьезных глюков, а даже мелких. Так что кто-то умеет же :)

  • dDIMA

    Для устранения ошибки не обязательно может быть тест. Может быть, например, регламент, который надо соблюдать. Или изменения в code standards. Или tips/tricks программисту “смотри как ЭТО надо делать и никода больше не делай другим образом”. Или что-то еще.
    Главное - это то, чтобы в рамках большой компании Reproduce first debugging касался не каждого отдельного программиста, а еще и обобщался на компанию в целом, чтобы типовых ошибок, сопровождающих даную конкретную архитектуру данного конкретного проекта было меньше.
    Ну то есть второй раз ошибку не должен допускать не только программист, но и его коллега :)

    • Регламент и coding standards не сильно-то помогают, если нет автоматизированного теста. Например, можно сколько угодно вносить в стандарты фразу “инициализировать все переменные в конструкторе”, но иногда кто-то да забывает. И тут без статик аналайзинг тулзов не обойтись, а это тоже своеобразный тест.
      И у остальных договоренностей “на словах” такая же проблема - иногда люди ошибаются. И тут тесты сразу находят ошибки :)
      Да, если пишутся только тесты и нет реагламента и стандартов - это не поможет, т.к. ошибок будет слишком много и тесты будут фейлиться всегда, а значит все на них будут забивать.
      Так что нужно всё вместе чтобы синергично работало.

  • arti

    А как быть в ситуации, если необходимо участие пользователя в процессе воспроизведения бага? Или я что-то не так понял.

    • SS

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

  • dDIMA

    Если проблема возникает у пользователя и не может быть воспроизведена у разработчика, то это уже называется удаленной отладкой, и задача программистов - сделать так, чтобы участие пользователя не потребовалось. Это может быть решено разными способами:
    1. Активное протоколирование хода работы приложения;
    2. Сбор сведений о системе и конфигурации компьютера;
    3. Минидампы в момент ошибки;
    4. Отладочный режим работы приложения с возможностью реконфигурации каких-то отладочных переменных или исключения отдельных блоков из работы системы.
    И так далее…

    • konstantin

      А мы кроме тотального протоколирования всех значащих действий ещё и даём возможность записать всё что идёт на вход системы со старта до выключения. Соответственно действия приведшие к сбою тоже записываются. С возможностью проиграть на вход системы записанные внешние события - сильно облегчает процесс отладки. Ибо есть “творческие” системы в лице Cisco, у которых при одном и том же сценарии на неизменившейся системе могут сгенерироваться 5 разных наборов сообщений нам на вход.

  • SS

    Юнит тесты это конечно круто и прикольно но кто проследит за разработчиком чтобы он не забыл написать тест или не забыл внести изменения в написанный тест после изменения кода? :)
    Т.е. скажем в конструкторе проводим инициализацию есть юнит тест проверки значений переменных членов класса после инициализации. Разработчик добавил еще переменную добавил код для установки ей значения, написал на добавленный метод тест. Все работает. Начал др. задачу…
    А изменить тест проверки инициализации забыл. Потенциальный баг добавлен и тестирование не помогло.

    • Один только юнит тестинг не дает 100% гарантии. Да и ничто не дает - нет серебрянной пули.
      Надо добавлять статистический анализ кода, код коверейдж для юнит тестов, автоматические системное и регрешшен тестирование, код ревью, запуск с всякими боундсчекерами и апликейшен верифайрами и т.п. - тогда можно процентов 90 ошибок ловить - это уже офигительно улучшит качество.

Ответить

 

 

 

Вы можете использовать эти HTML тэги

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>