В релизе Selenium 2.46 была устранена проблема падения Firefox 38 на старте, и сейчас я расскажу вам небольшую историю про то, как исправлялся этот баг.
Сразу после выхода версии Firefox 38 сообщения об этой проблеме стали валиться со всех сторон – баг-трекер, мейл-лист, стековерфлоу, далее везде.
Найти причину удалось достаточно быстро – оказалось, что Selenium при инициализации драйвера запускает браузер дважды, сначала с опцией ‑silent, а потом без неё, а в новой версии Firefox что-то сломали, так что при запуске браузера с опцией ‑silent возникает вот такой крэш.
Но дальше начались проблемы…
Разумеется, в коде не оказалось никаких комментариев, которые объясняли бы, зачем выполняется этот предварительный запуск.
Некоторый намёк содержался только в названии метода clear, где всё это происходило. Выполняется какая-то чистка. Но что можно чистить перед запуском браузера? Непонятно…
Документация по опциям запуска браузера тоже не добавляла ясности, ни о какой “чистке” чего бы то ни было в описании этой опции не упоминалось.
Пришлось выяснять, кто, когда и зачем написал этот код.
Увы, на следующем этапе расследования выяснилось, что этот “магический очищающий код” появился в драйвере Firefox с самого начала его существования.
Опять тупик?
Но ведь кто-то придумал это написать, должно же быть какое-то объяснение!
Подсказка нашлась в ещё более старом коде – в реализации запускателя браузера, который использовался ещё в Selenium RC, технологии предыдущего поколения!
В далёком 2009 году Patrick Lightbody, когда исправлял проблему с запуском Firefox в операционной системе Snow Leopard, попутно (!!!) добавил эту опцию ‑silent.
С какой целью он её добавил – это вполне объяснимо. Пока он это не сделал, старт браузера выглядел так – сначала выполняется предварительный запуск, на секунду появляется окно браузера и тут же исчезает, после чего появляется вновь, но это уже второй, полноценный запуск.
Вопрос в том, зачем вообще нужен этот предварительный запуск?
Пришлось устроить опрос людей, которые хоть как-то были причастны к этому делу и могли что-нибудь помнить.
Судя по всему, это было необходимо для того, чтобы обойти ограничения Firefox какой-то древней версии.
Браузер не мог сразу нормально запуститься, если профиль не до конца заполнен. Действительно, Selenium сначала создаёт шаблон профиля, а Firefox уже сам делает из него полноценный профиль, дополняет его при запуске. Так вот, первый предварительный запуск требовался для того, чтобы создать из шаблона полноценный профиль, а второй запуск выполнялся уже с нормальным профилем.
Ну хорошо, был такой баг в старых версиях Firefox. А сейчас как обстоят дела? Сможет Firefox нормально построить профиль и запуститься с одной попытки?
Кто бы знал…
David Burns поспрашивал, кого смог – разработчики браузера отвечали уклончиво, мол теоретически должен, но зуб не дадим.
Что делать?
И тогда мы решили, что из двух зол следует выбирать меньшее, сказали себе – “а, хуже всё равно не будет” – и смело удалили “магический очищающий код”!
Понаблюдали за тестами на сервере непрерывной интеграции – вроде бы ничего не падает.
Выпустили релиз – никто не жалуется.
А, нет, вру! Есть одна жалоба. После этого исправления не получается отключить выполнение JavaScript-кода на страницах браузера, profile.setPreference(“javascript.enable”, false) вроде бы выполняется, но реально значение не меняется. Всё таки была какая-то магия при запуске с этой опцией ‑silent! Ну и ладно. Внесли эту настройку в список запрещённых для изменения. Кого сейчас интересует браузер с отключенным JavaScript. Зато не падает :)
Какова мораль этой басни?
Тестировщики часто жалуются, что криворукие разработчики не могут нормально исправить какой-нибудь баг. Тут исправят – там сломают. И вообще, исправляют так, как будто вообще не понимают, что они делают, пытаются действовать наугад.
Увы, иногда они оказываются недалеки от истины :)
Стоит побывать в шкуре разработчика, почувствовать это ощущение, когда ты видишь баг, знаешь, чем он вызван – но не понимаешь, как его исправить. Или понимаешь, но не можешь просчитать всех последствий этого изменения. И никто не может. Знания утрачены.
Да, иногда проще/быстрее/дешевле исправить баг, руководствуясь принципом “а давайте удалим этот кусок кода и посмотрим, что будет, авось пронесёт, а если что – тестировищки подстрахуют” :)
Может быть это и не совсем “правильно”, но… Такова жизнь.