Мой баг дня (записки тестировщика)
Open in Telegram
Precondition: Repro steps: 1. ... 2. ... 3. ... Expected: good Actual: bad Связь: @MyachinDA
Show more229
Subscribers
No data24 hours
-27 days
-630 days
Posts Archive
Только что пришёл ответ. Проблема исправлена, обновитесь на последнюю версию. Ну, всё хорошо, что хорошо заканчивается.
Написал инструмент для вытягивания приложений из разных сторов на Android. В случае вот такого сообщения бросаю себе исключение "у нас нет аусвайса для этого пакета"
xyz.myachin.letsappsbeupdated.exceptions.StoreException: We have not an ausweis for com.bmw.ConnectedRide.na
Потому что так себя и чувствую
Подписался, чтобы оставить единственный комментарий. Всё, отписаться больше нельзя. ВК это сделали или ещё со времён Яндекса баг - не знаю: воспользовался дзеном впервые в жизни. И сразу вляпался
Появилась задачка сделать автотест Android параметризируемым. Если быть точным, то нужно уметь читать экраны Google Play Store сотни разных приложений. Можно сделать сотни тестов с именами пакетов, но лучше сделать метод
@Test всего один, но чтобы он мог принимать пакеты.
Как вы решали подобные задачи? Что говорит Гугл? Я просто и не искал, т.к. уже делал подобное и просто повторил то, что делал давно.
Суть такова:
@Test
fun demoMethod() {
val arguments = InstrumentationRegistry.getArguments()
Log.d("MyTestPackage", "first=${arguments.getString("first")}\n" +
"second=${arguments.getString("second")}\n" +
"third=${arguments.getString("third")}")
Запускается так: adb shell am instrument -w -e first "вот\ это\ я\ понимаю\ строка" -e second 100500 -e third 3.1415 -e class xyz.myachin.letsappsbeupdated.playstore.PlayStoreUpdateApps#updatePackage xyz.myachin.letsappsbeupdated.test/androidx.test.runner.AndroidJUnitRunner
Ну и получаем
2023-05-30 21:23:14.185 28039-28058 MyTestPackage xyz.myachin.letsappsbeupdated D first=вот это я понимаю строка
second=100500
third=3.1415
везде getString(), потому что аргументы приходят строкой. Можно написать обёртку с приведением к нужным типам, но это оверхед.Поисследовал поведение и похоже дело такое:
- https://issuetracker.google.com/issues/178965163
- воспроизводится на Android 11 и новее. Стреляет из-за фичи видимости пакетов. Ну знаете, нужно в манифесе прописать
<queries> либо дать разрешение на получение всех приложений
- настройки действительно являются лаунчером. Но когда пользователь таки разблокирует устройство, они передают управление лаунчеру по умолчанию
Решений этой проблемы два с половиной варианта:
1. Написать свой детект лаунчера. Я не проверял, но чел утверждает, что работает: https://github.com/adil-hussain-84/UiAutomatorExperiments. Это не мой путь. Выше я уже писал, что не хочу подменять поведение фреймворков без крайней нужды
2. В Манифесте включить ожидаемые ланчеры в видимость. В моём случае:
<queries>
<package android:name="com.android.launcher3"/>
</queries>
2.1. В Манифесте объявить разрешение android.permission.QUERY_ALL_PACKAGES, которое позволит видеть все приложения. Возможно вам будет удобнее этот вариант /**
* Retrieves default launcher package name
*
* @return package name of the default launcher
*/
public String getLauncherPackageName() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
PackageManager pm = mInstrumentation.getContext().getPackageManager();
ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
return resolveInfo.activityInfo.packageName;
}
UiDevice из uiautomator от Google утверждает, что лончером у меня является com.android.settings, а не com.android.launcher3. Лан, напишу свою определялку.Ухудшилась стабильность автотестов на Espresso. Стал разбираться, в чём дело.
У меня есть тест, который следит за таймером на экране. Так как я стараюсь не трогать код самого приложения (лезть в код, который написан много лет назад - себе дороже), то использовал банальный способ: делаю ViewAssertion на нужный мне текст и, если получаю исключение о несовпадении текста, повторяю попытку. Ну а что поделать, приходится так.
Это работало прекрасно несколько лет. И недавно сломалось. Каждый раз ассершен не обнаруживает нужный счётчик, пролетает мимо. Стал отлаживаться и увидел, что эспрессо просто замирает на 5 секунд после каждого опроса!
Оказалось, что поведение Espresso изменили в 3.5.0: https://developer.android.com/jetpack/androidx/releases/test#espresso-3.5.0
Espresso's DefaultFailureHandler now saves a screenshot on test failures to TestStorage
И вот если эспрессо не смог снять скриншот, он замирает на 5 секунд. Но хотя бы сообщает об этом в лог: java.util.concurrent.TimeoutException: Waited 5 seconds (plus 1063571 nanoseconds delay) for androidx.concurrent.futures.ResolvableFuture
Эта проблема не только у меня, вот другой человек жалуется: https://github.com/android/android-test/issues/1584
Гугл сжалился и сделал "фикс" https://github.com/android/android-test/commit/44b2b456d3052f6114ac3e3b5d2676e6f8885e37 На самом деле не фикс, а просто теперь я обязан создать свой FailureHandler и выставить отключение снятия скриншота.
Фикс доступен только в альфе: https://developer.android.com/jetpack/androidx/releases/test#espresso-3.6.0-alpha01: Allow customizing espresso's default failure handler to disable screenshots on failures
Сделал костыль, где считываю текст с вьюхи (напомню, что в Эспрессо нет метода для считывания текста, этот код тоже нужно написать самому) и уже в считанном тексте регуляркой беру число в счётчике и проверяю его.
Вот зачем было ломать то, что работало годами. Внесли непоправимое улучшение, что называется. Надеюсь на релизе 3.6 исправят всё же само поведение либы, без нужды свой хендлер определять. Я просто не люблю переопределять стандартные поведения, т.к. в будущем в стандартном поведении может появиться полезность, которая придёт на халяву, а я не узнаю об этом, ведь не слежу за чейджлогом каждой сраной альфы.
СЯУ, что клиенты ДОЛЖНЫ (MUST) сваливать коды возврата в их дженерик варианты, когда не знают реального кода. HTTP коды, в смысле.
Суть в том, что списки кодов возврата расширяемы (ну, это не новость) и, если клиент не знает конкретного кода, он MUST обработать код как x00. То есть 204 → 200, 409 → 400 и прочее.
И тут у меня флешбек из прошлого, когда в антивирусе был switch на коды возврата и dafault значение было "перезапросить снова". И как антивирусы стали класть сервак на лопатки, когда тот отвечал кодом, на который не было case.
https://music.yandex.ru/album/18910064/track/110185672
- У нас была платёжная форма, на которую было написано 9 тыс. строк тестов и ни один из них не проверял чего-то нужного
- Как так?
- Это тесты, ну там, на уровне, где вообще всё замокано. И условие такое:
if (true) { return true }. И так 9 тысяч строк кодаКто-то, простите не помню кто, но точно был подписан, спрашивал про стажировку. У меня её нет, но вот мои бывшие коллеги делают: https://safeboard.kaspersky.ru/ Оплачиваемая!
К сожалению, только для студентов. Посмотрите сами или передайте знакомым.
И нет, это не реклама. :) Просто у меня, что называется, перед глазами опыт, когда студент из сейфборда стал манагером в ЛК. Привет тебе, кстати, если ты это читаешь.
