Мой баг дня (записки тестировщика)
243 subscribers
169 photos
23 videos
11 files
126 links
Precondition:
Repro steps:
1. ...
2. ...
3. ...
Expected: good
Actual: bad

Связь: @MyachinDA
Download Telegram
То есть в моей голове сложилось такое предположение:
0. Если все варианты будут такими, как я ожидаю — я прав
1. Я сделаю Х попыток не покидая приложение — всё будет работать правильно
2. Я сделаю Х попыток с покиданием приложения после каждой — всё будет плохо и не предсказуемо
3. Я сделаю Х попыток с покиданием приложения и ручным его прибитием (свайпом из Недавних) после каждой — работать не будет вообще ничего — рандом всегда будет говорить true

Ну и да. Так и оказалось. Осталось об этом сообщить и ждать скорого фикса.
Не воспроизводилось это ни у кого больше, потому что ни в Windows, ни в Linux продукты не выгружались, в отличие от мобилок.

Фикс пришёл и с тех пор, уже много лет, вероятноть 0,01% реально означает одну сотую процента.


* Например, есть одна прошивка одной модели одного производителя, где на команду "удали файл" происходит СНАЧАЛА проверка, удалось ли удалить файл, а ЗАТЕМ удаление. В итоге метод бросает исключение, потому что считает, что у него нет прав на удаление файла. Но стоит вызвать удаление снова, происходит СНАЧАЛА удаление, а потом проверка, что удаление произошло на самом деле. Предсказать, как произойдёт в каждый новый раз невозможно. Такое поведение есть лишь на одной прошивке конкретного производителя. Ребята поняли, что они залезли туда, куда лезть не нужно было и в ближайшем обновлении откатили свои невероятно странные изменения. Проблема в том, что существующие модели не получили обновления прошивки. Новая версия раскатывалась на новые трубки.
Благо это реально редкий производитель. Прям правда редкий. Но даже такие сверх редкие ситуации у нас обрабатываются. Потому что никто не должен портить статистики.
Сегодня хотел рассказать о том, как обнаружил ошибку в новой фиче, но т.к. фича ещё не существует публично, а только тестируется, рассказывать о ней пока рано. Но надо бы не забыть, там как раз случай, одна одна ошибка покрыла другую и в итоге если бы не мой автотест, ошибка ушла бы в релиз.

Но пока NDA, я расскажу о простых проблемах. Но то, что просто для авторов, может быть серьёзной проблемой для клиентов. В общем, немножко о документации.
Техписатели исправили ошибки документации, которые я обнаруживал, пока писал автотесты. Все автотесты у меня написаны по Public API и проверяют примерно всё, что может использовать клиент. И такой у меня была цель изначально. А потому тесты писались так, будто я сам и есть клиент. Всё писалось по документации, которая сопровождает продукт. Если что-то было не очевидно или спорно — записывал ошибки на документацию.

Записал не так, чтобы много, но всё же. Более-менее интересное перечислю ниже. Для лучшего понимания я буду использовать слово "документация", когда речь идёт именно о документации, т.е. таком тексте, который можно читать как книжку, где используется более-менее литературный язык и которая понятна любому человеку с улицы. Также в ней очень много вставок кода, где показано, как лучше использовать ту или иную фичу.
Для JavaDoc я буду писать "ДжаваДок". Это документация, сгенерированная из исходного кода на основе специальных комментариев. ДжаваДок нужен разработчикам и тестировщикам. Здесь сухой технический язык, зато всё строго по делу. В документации хоть и есть описания методов, в ДжаваДок оно более полное. А в документации более понятное людям, которые впервые с этим столкнулись.
— В документации были уже удалённые API
— В документации, из-за ошибки вёрстки (потерялись хтмл-теги), часть описания одной фичи залезла в другую
— В документации в разделе описания интеграции библиотеки обран пермишен на чтение логката, а также вставлен блок текста с информированием, что начиная с API level 16 (это Android 4.1) пермишен android.permission.READ_LOGS более не работает и, если у вас уже есть проект, то при переходе на новую библиотеку этот пермишен можно безболезненно убрать. Потому что новая версия библиотеки работает только с 16-го АПИ как раз
— В документации к одной из фич был дан кусок кода, который бы даже не скомпилировался. Код этот был написан ещё в процессе создания фичи, но ещё до релиза новой фичи, но уже после написания этого примера для справки, её расширили в возможностях, что потребовало в сигнатуре метода использовать другой объект
— В JavaDoc не было явно задано использование UTF-8 для текста, из-за чего Firefox, если в нём выставлена локаль en_US, пытался отобразить текст в ISO 8859-1 (он же Latin-1, он же Windows-1252). В целом это даже работало. Но кроме тех мест, где был символ "типографского тире" (или как он называется): —. Вообще проблемы были бы и с символом многоточия, но он в ДжаваДок не использовался.

Читайте документацию, которую прикладываете к своим продуктам. Берите пример с Опен Сорс проектов. Как правило, их документация очень хороша. Чего не скажешь о многих проприетарных проектах. Это печально, господа.
Только что НЕ записал баг, хотя всё указывало на то, что баг есть.

В продукте есть много механизмов безпасности и дополнительных проверок. Два из них работают примерно так:
1. У приложения проверяется подпись
2. Если подпись доверенная (по локальному вердикту), то срабатывает механизм, защищающий от ложного доверия. Ложное доверие может быть, например, на скомпроментированном устройстве (когда сторонний процесс может лезть в нашу память и делать что пожелает) или просто потому что подпись отозвали 5 секунд назад и продукт ещё не знает об этом. Механизм не тупой, он ещё решает, нужно ли делать дополнительную проверку или нет
3. Дополнительный менанизм может или поменять доверие, или оставить его. Это решение окончательное (но только с точки зрения проверки подписей, другие дополнительные проверки ещё не закончились)

Кроме прочего, есть механизм, понимающий, что приложение не может быть подписано ВОТ ТАК (вы можете повесить на приложение хоть 10 подписей, но в GPlay не попадёте тогда). На этот механизм, который понимает, что приложение может или не может быть подписано конкретным образом, и срабатывал тест. Он сообщал о провале — продукт доверился подписи, которой быть не может.

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

Я просто взял тестовую apk и проверил её утилиткой apksigner. Она входит в состав Android SDK и живёт в build tools. Вот эта команда:
umnik@myachin:~/Android/Sdk/build-tools/28.0.3$ ./apksigner verify --verbose ~/Downloads/app-release-test-1.2.3-chain-v1.apk

Проверка показала, что здесь с подписями всё в порядке. Среди нескольких ожидаемых оказалась одна доверенная и всё.

В общем, банально тестовое приложение не то, что нужно. Скорее всего по нему кто-то прошёл zipalign'ом, от чего слетели все подписи версии 2 и осталась только честная доверенная подпись.

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

Ошибки нет. А значит под НГ будет релиз.

P.S. Описания механизмов очень упрощены. Всё сделано круче :)
О тестировании в Тинькофф в двух скриншотах. Ребята скрывают фамилию получателя в приложении. Просто Анастасия Л. Но в СМС имя и фамилия написаны целиком, без сокращений :)
Из старого прошлого несколько багов, заведённых и исправленных много лет назад. Продукты самые разные, т.к. за 10 лет принимал участия во множестве проектов, часть из которых даже никогда не попали в публичный релиз.

В 2008 году тестируемый продукт под Windows не показывал справку, потому что её вызов забыли назначить на F1

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

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

2009 год. В распаковщике 7z архивов не было поддержки юникода. См. скриншот
2010 год. Продукт мешал работе торрентов. Было сделано три разных изменения в драйверах, дабы не мешать торрентам работать. С точки зрения пользователей это могло выглядеть как "ничего не делают", а внутри же выходили фиксы за фиксами на проверку. Потому что ничего не должно мешать раобтать торрентам.

2010 год. Если продукт работал под Windows XP SP2, установленной на FAT32, он мог "забыть", что видел каждую запускаемую программу раньше. Проблема не распространялась на сменные носители и на не системные разделы. Только если FAT32 был системным.

2010 год. Продукт был несовместим с АнреалЭнджен3. Причина обнаружилась быстро и патч быстро пришёл. Но вот для воспроизведения проблемы я писал популярным в России продажникам игр и просил лицензионные копии игр на этом движке. Быстрее и лучше всех отреагировала Бука, которая вообще курьером мне эти игры привезла. Далее была проблема с проверкой, потому что наши рабочие станции были с норм процессором и памятью, но без нормальных видеокарт. Игры просто отказывались запускаться при проверке железа. Приходилось каждый фикс проверять дома.
2010 год. При обновлении баз в трее крутился глобус. Его первые версии вращались через полюса. Затем стали вращаться вдоль экватора, но в другую сторону. Затем в правильную сторону, но без наклона оси.

2012 год. И последняя на сегодня ошибка. Вычитывайте тексты, коллеги. Не ленитесь. Даже когда этого текста много и он мелшим шрифтом. Потому что опечатки бывают не только вида тся/ться, как это было в подборке выше.
Баг конца нулевых.
Мы все привыкли, что в Windows переменная окружения %APPDATA% резолвится в %USERPROFILE%\Application Data\. По техническим причинам, о которых ниже, в продукте в список защищаемых ресурсов был внесён путь именно %USERPROFILE%\Application Data\, а не %APPDATA%. И всё работало хорошо.
До тех пор, пока не сели проверять работу на разных дистрибутивах Windows. Оказалось, что в немецкой локализации Windows нет никакого "\Application Data\". Там есть %USERPROFILE%\Anwendungsdaten\. Во как.
Если вы под Windows, то проверьте, у вас точно \Application Data\ прямо сейчас.
Пришлось решать эту проблему. А чтобы решить, нужно быть разрулить проблему с резолвом %APPDATA%. Но в чём же проблема с ним?

Дело в том, что все эти переменные окружения резолвятся в зависимости от текущего пользователя. Это логично, да. Но кто такой текущий пользователь? У вас может быть три разные учётные записи на ПК. У вас активен один сеанс и второй сеанс жив, но там никто не залогинен (Switch User, который был в XP и выше). В кого разворачивать переменные окружения из этих двух пользователей? Логика подсказывает, что в того, кто смотрит на рабочий стол, да?

Усложним задачу. Это терминальный сервер и сейчас одновременно залогинено 100500 разных юзеров (механизм разворота переиспользуется и в домашних продуктах, и в корпоративных). В кого разворачивать переменные тогда?
Логика подсказывает, что пусть GUI разворачивают сами, да?

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

Усложняем задачу. GUI вообще ничего не может делать сам, он только мордочку показывает. Всё делает сервис, который общается с драйвером. Так что НА САМОМ ДЕЛЕ все переменные окружения у сервиса должны резолвится в его собственного пользователя — SYSTEM!

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

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

К слову, в Android тоже есть профили пользователей. Но т.к. в Android нельзя работать с высокими привилегиями (по умолчанию, без su), то нельзя из профиля пользователя А достучаться до данных приложений в профиле пользователя Б, потому там такой проблемы нет.
Про неуспешные решения. Был такой конкруент (он и сейчас есть, но ошибки уже давно нет), который вообще не парился по поводу каких-то там профилей, прав. У него сервис стартовал с правами SYSTEM (что абсолютно ожидаемо, разумеется) и уже он запускал GUI со СВОИМИ ТЕКУЩИМИ ПРАВАМИ. То есть GUI тоже работал с правами SYSTEM.

Плюс такого подхода был, например, в возможности из GUI достучаться до путей, недоступных простому пользователю. Минус же перевешивал любой возможный плюс — локальное повышение привилегий. Любой пользователь в системе, даже супер ограниченный Гость, мог открыть GUI продукта, нажать F1, чтобы открылась справка, использующая движок IE, в ней ввести локальный адрес и в ответ система запускала explorer с правами SYSTEM в сеансе Guest. Ну а дальше делайте что хотите вообще, выше вас только звёзды.

Ну и раз речь зашла про то, как антивирусы добавляли огромные дыры в систему, оставлю здесь эту ссылку: http://4pda.ru/forum/index.php?showtopic=64914 Здесь идея в том, чтобы обходить систему безопасности поздних версий Symbian путём добавляения всяких патчеров в карантин некоторы антивирусов (тех, кто не особо заботился о безопасности — правильного вы там не найдёте) и затем восстановить их из карантина. После восстановления патчеры будут чудестным образом подписаны подписью антивируса.

Строго следите за безопасностью того, что вы делаете. Продумывайте векторы атак. Даже если для успешной атаки нужно иметь знание, доступное только в вашей команде — это всё равно проблема. Security through obscurity НЕ работает.
Если вам придётся ссориться с коллегами ради защиты клиентов — ссорьтесь. Деньги приносят клиенты, а не коллеги.
Коллеги тестировщики. Вычитываете все тексты. Держите в голове тот факт, что никто не читает инструкции и документы, кроме клиентов. Авторы инструкций сами их не вычитывают, а корректоров у вас в штате обычно нет.

Пример. Топаем на сайт Сбербанка и находим услугу "Прямое управление счетами": https://www.sberbank.ru/ru/legal/bankingservice/corporative/linecontrol
Прокручиваем страницу и находим "Инструкция по продукту «Прямое управление счетами»": https://www.sberbank.ru/common/img/uploaded/files/pdf/legal/sberbank-corp/instrukcia_pus.pdf

Открываем документ и делаем поиск по слову "корпор" — должно быть найдено 19 вхождений. Это слово "Корпор@ция". Теперь делаем очевидную фекальную опечатку — слово "копро". И видим 2 вхождения!

Тестировщик! На тебе лежит отвественность за всё. Ошибок не должно быть не только там, над чем работаешь лично ты, но вообще нигде. Ты единственный, кто умеет искать ошибки и ты обязан это делать.
Появилась задача проверить, можно ли установить apk весом более 4 ГБ на Android. Как оказалось, файл такого размера даже подписать не удаётся. Ни jarsigner из OpenJDK, ни apksinger из build-tools 28.0.3 не могут обработать файл такого (5 ГБ) размера. Аналогично проваливается и zipalign.

Если вы знаете, как подписать apk весом в 5 ГБ, вы очень поможете.
@Umnik_ADS
Я очень люблю плавающие баги. Их сложно обнаружить, их сложно локализовать, в них сложно разобраться, их сложно воспроиводить. С ними даже не всегда ясно, ошибка ли это. Так что такие ошибки — вызов. Да, я искренне люблю плавающие проблемы.

Ошибка из 2012 года, на исправление которой потребовалось два месяца и взаимодействие нескольких команд.

Описание предельно простое:
19/7/2012 17:32:44 - Dmitry Myachin (2502):
1. Change settings to custom. For example enable Interactive mode and allow detection for "Othes" category
2. Save settings
3. Reboot Windows
4. Check settings
Expected:
Settings are custom
Actual:
Settings are default

Первый подход к снаряду случился уже на следующий день, но он не помог. Стали копать дальше. По логам выходило, что сервис долго завершался и это как-то приводило к несохранению. Значит нужно было ускорить завершение сервиса?!
Второй подход к снаряду должен был ускорить завершение работы сервиса на выключении системы, однако ничего не изменилось в самой ошибке. Настройки всё также не сохранялись, но стали не сохраняться реже. У разработчиков же вообще проблемы не было. Не было проблемы и у тестировщиков. Но проблема была у меня на личном ПК и то не всегда.
Скилов текущего разработчика уже не хватало, подключили экспертов по компонентам, чтобы те посмотрели, как быстро завершаются их собственные компоненты. Каждый из разработчиков ответил, что с их стороны всё в порядке, из компоненты завершились задолго до завершения работы сервиса.

Тогда почему не сохраняются настройки? И почему не всегда? И почему не на всех машинах? Как вообще связано сохранение настроек и завршение работы сервиса.
Новый подход к снаряду — расширенные логгирования. По ним стало видно, что настройки не сохраняются по причине "пока не нужно". Это "не нужно" вешала команда, занимающаяся производительностью. Задачу перевесили на них, чтобы разобрались.
Команда производительности сказала, что у них всё нормально. Они не флашат настройки после каждого перетыкивания галки в интерфейсе, чтобы не нагружать системы. Они накапливают изменения и записывают настройки либо когда никто ничем не занимается в системе, либо когда система завершает работу.

Стало немножко яснее. У тестировщиков и разработчиков виртуалки часто простаивали и потому у них проблемы не было. А мой личный комп не простаивал вообще никогда. Отсюда это "пока не нужно".

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

Задачу перевесили на очень экспертного эксперта, который и разобрался со всем. Как оказалось, продукт не может записать настройки на выключении, потому что нечно убивает сервис. Нечто — это ОС. Но почему? Поведение системы должно быть таким, что система оповещает всех о выключении. На этом оповещении сервис быстро бы записал настройки, буквально за одну секунду (на самом деле быстрее) и всё бы должно быть хорошо.

Оказалось, что операция записи настроек выполнялась не оптимально именно в сценарии, когда система оповещает о выключении. Ну то есть как не оптимально. Использовался тот же самый механзим записи настроек. Если сильно упростить, то дёргался метод .saveSettings(), внутри которого была всё та же проверка на нагрузку на ОС и продукт принимал решение подождать момента, когда и проц посвободнее будет, и диск не будут жрать. На выключении, ага. А Windows даёт лишь 5 секунд и после этого завершает сервис сама.
Когда с этим разобрались, фикс появился очень быстро. И разобрался с этим один конкретный разработчик. Пожалуй, один из самых сильных в компании. Мне кажется, что если он захочет, он может переписать продукт целиком по памяти, каждый компонент, каждый драйвер. И вот это его понимание всех компонентов продукта позволило увидеть проблему сверху, тогда как каждая из подкоманд не видела проблемы со своей стороны. С точки зрения каждой подкоманды всё шло хорошо.

Кстати, параллельно этому разбору разработчик нашёл баг и в самой Windows. В Windows есть пециальный параметр в реестре, которым можно увеличить таймаут на завершение сервиса. И этот параметр не рабтает в Win7/2003: https://support.microsoft.com/en-us/help/2549760/waittokillservicetimeout-registry-value-does-not-work-in-windows-7-or Примечательно, что MS знал уже об этом баге, а разработчик просто нашёл его при исследовании. После обнаружения проверил на сайте MS и нашёл, что даже патч есть, но персональный. То есть персональным он был на тот момент, сейчас уже, наверное, раскатан на всех.

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