🐛 Что такое гейзенбаг и как с ним бороться?

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

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

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

Что такое плавающий баг?

Нежелательное поведение программы, которое возникает спонтанно и непредсказуемо, называют плавающим багом или гейзенбагом с отсылкой к немецкому физику Вернеру Карлу Гейзенбергу – автору принципа неопределенности из квантовой физики.

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

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

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

Как работать с плавающими багами?

Для избавления от плавающих багов используется традиционный принцип «повторить и разобрать», но с некоторыми оговорками:

  1. Как проверить, что перед вами плавающий баг, а не обычный? Во втором случае вы понимаете, откуда взялась проблема, а в первом – нет. Именно поэтому внимательность и способность ничего не упускать – одно из главных достоинств тестировщика. Самое смешное, неисправленный плавающий и исправленный обычный баги очень похожи – они не воспроизводятся, но плавающий баг может в любой момент вернуться.
  2. Чем выше тестируемость продукта, тем легче найти в нем плавающий баг.
  3. Любая произошедшая по непонятным причинам ошибка может вернуться. «Прошло само» не работает. Код – это четкая структура, поэтому умение локализовать баги важно развивать. Этот навык пригодится, когда ошибка будет воспроизведена, но как – непонятно.
  4. Плавающие баги могут легко воспроизводиться в продуктивной среде и плохо проявляться или вовсе не проявляться в тестовой. Это важно учитывать и соотносить с процессом релиза системы.
  5. В появлении плавающих ошибок может быть виноват целый комплекс причин, поэтому при тестировании используйте таблицы со множеством вариантов. Иногда простой перебор сочетаний различных условий приводит к успеху.
  6. Никогда не пытайтесь скрыть плавающий баг от заказчиков и пользователей. В будущем это может привести к еще большим проблемам.
Яркий пример того, как попытка Intel скрыть ошибку привела к убыткам:
В выпускавшихся Intel в 1994 году процессорах Pentium была проблема с некорректным делением чисел с плавающей запятой. В компании посчитали, что дефект может повлиять на работу очень узкого круга пользователей, и решили его скрыть. Возникший в обществе резонанс заставил Intel изменить позицию и принес убытков на $475 млн.

Как локализовать ошибку, если первичный анализ ничего не дал?

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

Почему возникают плавающие баги?

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

Вот примерный список причин, который поможет в случае, если вдохновение вас покинуло:

  1. Переполнение. Какое-либо поле или контейнер могут переполняться и провоцировать сбой при корректной работе связанных с ним функций. В эпоху больших запасов памяти тестировщики часто упускают это из вида. Например, внутри системы могут считаться огромные суммарные значения, и она окажется не способна переварить такое количество символов.
  2. Проблема кода, которую также называют «Проблемой ТЗ». Зачастую плавающий баг связан с тем, как написан код (мы не рассматриваем сейчас некачественную работу, только непредсказуемую). Например, составителю технического задания на разработку очевидно, что при выборке данных нужно взять некий уникальный объект, но разработчик этого знать не может и прописывает свободный выбор. Бывает, что код написан верно, но какое-то сочетание условий приводит не к поломке, а к подмене функций. В этом месте не будет ошибки, но будет неверная работа программы в целом.
  3. Проблемы ввода. Например, в поле свободного ввода пользователь внес непредусмотренные алгоритмом данные, либо ошибочный символ (запятую вместо точки и т.д.). Сюда же относятся ошибки, связанные с использованием клавиатуры вместо мыши или ошибки призрачного ввода, когда данные вносит машина (особенно где-то в середине расчетов). В таких случаях проблему можно обнаружить, проставляя контрольные «стопы» и проверяя работу кода по частям. Еще один вариант – дефектный ввод, когда данные клиент-серверных приложений повреждены или переданы с ошибкой.
  4. Проблемы оборудования возникают, когда ошибки связаны с физическими факторами. Например, из-за перебоев с электропитанием, высоких температур в серверной, физических повреждений компьютера и т.д.
  5. Случайности. Некая комбинация условий может сработать корректно, но впоследствии привести к ошибке.
  6. Deus Ex Machina. Эти проблемы возникают, когда одновременно с вами кто-то еще использует приложение: разработчик, хакер или другой тестировщик.
  7. Неочевидные моменты. При анализе специалисты часто отбрасывают ненужное, чтобы сосредоточиться на важном, а оказывается, что проблема возникает из-за отброшенных ранее вариантов.
  8. Неизвестное. Невозможно учесть все. Например, в системе может быть функция, о которой тестировщику неизвестно, или некие источники искажений. Внутри приложения могут создаваться незадокументированные переменные и т.д. и т.п.

Еще несколько советов по работе с плавающими багами:

  • Всегда проверяйте базу. Характеристики компьютера, что тестируете, исходные данные в документах и по факту.
  • Всегда проверяйте информацию со стороны. Не задавайте вопросы в чате пользователю или коллеге, лучше сходите и посмотрите сами.
  • Если кажется, что все уже проверено от и до, причем несколько раз, попросите коллег посмотреть. Без вас и ваших рассказов, с минимумом вводных.
  • Поищите похожие кейсы и посмотрите, как решались такие вопросы раньше.
  • Сохраняйте все логи. Возможно вам придется сравнивать не только исходный и последний, а еще и промежуточные.
  • Проверяйте то, что на первый взгляд не имеет значения. Даже если вам кажется, что это вообще не относится к вопросу. Часто именно оно оказывается искомым.
  • Проверяйте конфликты на границах разных модулей и систем, особенно если интеграция происходит между продуктами разных разработчиков.
  • Если используете сторонние компоненты, обратитесь в техподдержку разработчика.
  • Если нет никакой информации, ничего не помогает, а ошибка по прежнему не найдена, дайте проблеме отстояться. Вернитесь к ней завтра, а сегодня переключите внимание на другие задачи.
  • Не отчаивайтесь. Ищите инструменты, которые помогут решить вопрос – однажды вы обязательно их найдете.
  • Соотнесите пользу от устранения бага и потраченные на это усилия. Иногда достаточно знать о наличии проблемы: это не баг, это фича.
***

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

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Java Team Lead
Москва, по итогам собеседования
Разработчик С#
от 200000 RUB до 400000 RUB

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ