Хороший бонус работы в IT компании, связанной с offline бизнесом - возможность поработать в этом самом бизнесе. Планирую несколько дней работать курьером, разносить нашу додо-пиццу по Алматы. Отпишусь, заработаю ли сколько-нибудь чаевых, или наоборот, сколько человек посмотрит на меня, как на 💩) Ну и заодно посмотрю, как на самом деле работают наши IT продукты - тут потрогаю все, что связано с доставкой, на проде🙂. Кстати, наш СЕО тоже будет курьером. И еще несколько ребят из QA, конечно же 🍕
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥72😁13👍8❤5🫡2
Сегодня на собеседовании спросил у QA инженера, у которого в резюме питон и джава/котлин:
Что бы вы ответили, если владеете обоими языками?
Что больше всего тебе, как инженеру (автоматизатору), кажется главным отличием питона от джавы? Что тебя радует или огорчает при переходе с одного языка на другой?
Что бы вы ответили, если владеете обоими языками?
🔥7
#обучение #java #qaguru
А еще сегодня стартую 4 поток своего авторского курса Advanced. Занятие отрытое для всех, так что приходите, даже если не хотите учиться. Ну а если вдруг думаете - надо оно вам или нет - посмотрите на один из лучших дипломов 3 потока от Миши Нестерова - проект Rococo
Фронтенд (rococo-client) к нему написан нашей командой, а именно Ириной из OZON fintech, но, каждая другая строка кода, каждый микросервис, каждая строчка тестов, и все-все все в этом репозитории - написал Миша, и это и есть наш диплом.
Мы даем front, остальное делают студенты.
На 4-м потоке мы будем давать целых два frontend-а на выбор (REST и GraphQL, совершенно разные проекты), а все бэкенды и тесты будут писать студенты. Будет очень 🚀 интересно 🚀. Промокод в закрепе 😁
А еще сегодня стартую 4 поток своего авторского курса Advanced. Занятие отрытое для всех, так что приходите, даже если не хотите учиться. Ну а если вдруг думаете - надо оно вам или нет - посмотрите на один из лучших дипломов 3 потока от Миши Нестерова - проект Rococo
Фронтенд (rococo-client) к нему написан нашей командой, а именно Ириной из OZON fintech, но, каждая другая строка кода, каждый микросервис, каждая строчка тестов, и все-все все в этом репозитории - написал Миша, и это и есть наш диплом.
Мы даем front, остальное делают студенты.
На 4-м потоке мы будем давать целых два frontend-а на выбор (REST и GraphQL, совершенно разные проекты), а все бэкенды и тесты будут писать студенты. Будет очень 🚀 интересно 🚀. Промокод в закрепе 😁
Telegram
QA.GURU in QA.GURU | Общий чат
🚀 Уже сегодня в 20:00 по Москве старт 4- го потока нашего мощнейшего курса!
Приглашаем всех желающих на бесплатное вводное занятие по Автоматизации тестирования для продвинутых инженеров Java Advanced
🗓 Добавить напоминание в календарь
⭐️ Курс разработан…
Приглашаем всех желающих на бесплатное вводное занятие по Автоматизации тестирования для продвинутых инженеров Java Advanced
🗓 Добавить напоминание в календарь
⭐️ Курс разработан…
🔥19👍3
Кстати, не обошлось без интересного бага. Завтра расскажу.
А это мы с СЕО Dodo Engineering встретились за полезным делом перед пиццерией)
А это мы с СЕО Dodo Engineering встретились за полезным делом перед пиццерией)
🔥43👍3🥰2🏆1
А вот и баг в нашем курьерском приложении, про который я хотел рассказать. Главный экран приложения (картинка, где заказ 148-2) включает в себя список готовящихся и уже приготовленных заказов. Курьер (я) видит, что готов заказ, и выделяя его, свайпает "Поехали!".
После этого мы попадаем на второй экран (на моих картинках - где 220-4).
Этот экран содержит чекбоксы всех продуктов в заказе, которые надо проставить, складывая пиццы и додстеры с соусами в термосумку. Чекк-лист, что бы клиент получил ровно то, что заказывал, и ничто "случайно" не оказалось забыто.
Так вот, как выяснилось, в момент перехода с первого экрана на второй, заказ не фиксируется за выбравшим его курьером! Реальное назначение на курьера происходит только после завершения "чек-листа" на втором экране. Таким образом я старательно складывая заказ в свою сумку сталкиваюсь с тем, что ко мне подходит мой коллега курьер и говорит "А чего это ты мой заказ тут собираешь? Он же мой, я его взял!". И действительно - я смотрю в свое приложени и вижу, что заказ-то уже не мой и я зря тут галочки жму в чеклисте. Курьеры, кто работают постоянно, конечно знают про эту особенность, и поэтому у них флоу такой - "Выбрать заказ -> Моментально прощелкать галочки чеклиста (тем самым превратив его в фикцию) -> Тем самым по-настоящему забронировать заказ за собой -> Пойти собирать его в сумку".
Этот баг - на мой взгляд - очень серьезный, так как он выкидывает в помойку целый бизнес-процесс - проверка заказа по чеклисту. Этот этап просто скипается, что бы никто другой не взял тот заказ, что ты планиурешь везти. А еще, это очень похоже на то, как если бы сайт РЖД не резервировал для вас билет, пока вы вводите свой номер кредитки🥲
После этого мы попадаем на второй экран (на моих картинках - где 220-4).
Этот экран содержит чекбоксы всех продуктов в заказе, которые надо проставить, складывая пиццы и додстеры с соусами в термосумку. Чекк-лист, что бы клиент получил ровно то, что заказывал, и ничто "случайно" не оказалось забыто.
Так вот, как выяснилось, в момент перехода с первого экрана на второй, заказ не фиксируется за выбравшим его курьером! Реальное назначение на курьера происходит только после завершения "чек-листа" на втором экране. Таким образом я старательно складывая заказ в свою сумку сталкиваюсь с тем, что ко мне подходит мой коллега курьер и говорит "А чего это ты мой заказ тут собираешь? Он же мой, я его взял!". И действительно - я смотрю в свое приложени и вижу, что заказ-то уже не мой и я зря тут галочки жму в чеклисте. Курьеры, кто работают постоянно, конечно знают про эту особенность, и поэтому у них флоу такой - "Выбрать заказ -> Моментально прощелкать галочки чеклиста (тем самым превратив его в фикцию) -> Тем самым по-настоящему забронировать заказ за собой -> Пойти собирать его в сумку".
Этот баг - на мой взгляд - очень серьезный, так как он выкидывает в помойку целый бизнес-процесс - проверка заказа по чеклисту. Этот этап просто скипается, что бы никто другой не взял тот заказ, что ты планиурешь везти. А еще, это очень похоже на то, как если бы сайт РЖД не резервировал для вас билет, пока вы вводите свой номер кредитки🥲
👍46🔥11😁6❤2
А еще сегодня маленький JUnit Extension, который дизэйблит тесты, если есть открытый issue (например, ваш тест нашел баг, и вы завели issue или ваш тест устарел, и вы завели issue на его актуализацию):
1) Создаем аннотацию
Именно в ней будет id (номер) заведенного issue
2) Пишем Extension
3) Ну и запрос в github для retrofit:
Я глубоко убежден, что если тест начал падать, то на это должен быть issue (если, конечно, там не на 5 минут исправить ситуэйшн). А если уж мы создаем issue, давайте дизэйблить тесты, как Петербуржцы
1) Создаем аннотацию
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(IssueExtension.class)
public @interface DisabledByIssue {
String value();
}
Именно в ней будет id (номер) заведенного issue
2) Пишем Extension
public class IssueExtension implements ExecutionCondition {
private static final OkHttpClient httpClient = new OkHttpClient.Builder().build();
private static final Retrofit retrofit = new Retrofit.Builder()
.client(httpClient)
.baseUrl("https://api.github.com")
.addConverterFactory(JacksonConverterFactory.create())
.build();
private final GhApi ghApi = retrofit.create(GhApi.class);
@SneakyThrows
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
DisabledByIssue disabledByIssue = AnnotationSupport.findAnnotation(
context.getRequiredTestMethod(),
DisabledByIssue.class
).orElse(
AnnotationSupport.findAnnotation(
context.getRequiredTestClass(),
DisabledByIssue.class
).orElse(null)
);
if (disabledByIssue != null) {
JsonNode responseBody = ghApi.issue(
"Bearer " + System.getenv("GH_TOKEN"),
disabledByIssue.value()
).execute().body();
return "open".equals(responseBody.get("state").asText())
? ConditionEvaluationResult.disabled("Disabled by issue #" + disabledByIssue.value())
: ConditionEvaluationResult.enabled("Issue closed");
}
return ConditionEvaluationResult.enabled("Annotation not found");
}
}
3) Ну и запрос в github для retrofit:
public interface GhApi {
@GET("/repos/qa-guru/niffler/issues/{ISSUE_NUMBER}")
@Headers({
"Accept: application/vnd.github+json",
"X-GitHub-Api-Version: 2022-11-28"
})
Call<JsonNode> issue(@Header("Authorization") String bearerToken,
@Path("ISSUE_NUMBER") String issueNumber);
}Я глубоко убежден, что если тест начал падать, то на это должен быть issue (если, конечно, там не на 5 минут исправить ситуэйшн). А если уж мы создаем issue, давайте дизэйблить тесты, как Петербуржцы
❤25👍9🤯1
Дорогие друзья, коллеги, я надеюсь вам так же было интересно в 2023 в этом канале, как мне самому - в дискуссиях с вами. В новом году будет кое-что действительно интересное от меня на поприще QA - я уже начинаю работать над действительно крутым проектом для всех нас. С новым годом!🎄
👍43🎉38❤14🔥10🎄8🍾2💯1
Куда я пропал в 2024? В отпуск) Стараюсь сейчас вообще не думать ни о работе, ни о лекциях, ни о конференциях, пока получается. Но отпуск закончится, и будет много о планах в Додо, планах в qa.guru и, конечно, технических постов. Stay tuned 🙌
🔥54❤6😎5❤🔥1
Вышел из отпуска :harold-the-pain:
Провел собеседование (неудачно), узнал, что сегодня дедлайн по OKR на 1 квартал (они-то уже есть, но были не внесены в нужную эксельку). Узнал что у нас прямо сейчас все хотят открыть 5 QA вакансий:
- Mobile QA
- Team Lead QA
- Performance QA
- Web QA
- Железячный QA 🙂
Пообсуждали архитектуру большого проекта Kotlin тестов и наметили, куда ее рефакторить.
А еще пропустил обсуждение важного вопроса в слаке*:
Теперь надеюсь, что эти знания не пригодятся 🙂
Провел собеседование (неудачно), узнал, что сегодня дедлайн по OKR на 1 квартал (они-то уже есть, но были не внесены в нужную эксельку). Узнал что у нас прямо сейчас все хотят открыть 5 QA вакансий:
- Mobile QA
- Team Lead QA
- Performance QA
- Web QA
- Железячный QA 🙂
Пообсуждали архитектуру большого проекта Kotlin тестов и наметили, куда ее рефакторить.
А еще пропустил обсуждение важного вопроса в слаке*:
Куда бежать в случае землетрясения в Алматинском офисе
Теперь надеюсь, что эти знания не пригодятся 🙂
❤11🆒3👍2
#Java #Spring
Об обновлении зависимостей.
Обновил тут в одном из своих Spring пет-проектов одну зависимость.
Было 1.1.2, стало - 1.2.1. Поменял местами 2 цифры так сказать, что могло бы пойти не так?
У меня напрочь отвалился Oauth 2.0 code flow.
Запрос
В коде спрингового сервиса даже в DEBUG логгировании нет никаких ошибок и стэктрейсов, потому что эта ошибка и не логгируется при выбрасывании.
Что делать?
Смотреть гит блэйм, кто же и что же поменял в этом
Метод
The client makes a request to the token endpoint by sending the
following parameters using the "application/x-www-form-urlencoded"
То есть, еще месяц назад реализация OAUTH 2.0 в spring-authorization-server не соответсвовала RFC, принимая GET параметры! Так же ей не соответсвовал и мой код, отправляя GET параметры. Начав бомбить о том "да как так одна циферка зависимости ломает мой прекрасный код!" закончил философским "ошибаются все, и не боги горшки спринговые обжигают".
Тут есть и еще один вопрос, а почему я вообще изначально не прочитал нормально RFC и отправлял GET-параметры?
Потому, что до получения странной ошибки я просто думал, что мне будет достаточно посмотреть воркшоп автора книги Spring Security in Action - и в нем тоже показана отправка простых GET параметров. А значит, ошибаются не только контрибьюторы Spring, но и даже авторы книг о Spring.
Мои выводы
- ошибайтесь на здоровье;
- но, любите дебаг;
- и гитблэймы;
- и чтение спецификаций и RFC
Об обновлении зависимостей.
Обновил тут в одном из своих Spring пет-проектов одну зависимость.
Было 1.1.2, стало - 1.2.1. Поменял местами 2 цифры так сказать, что могло бы пойти не так?
У меня напрочь отвалился Oauth 2.0 code flow.
Запрос
/oauth2/token? отдает 400 BAD REQUEST. И говорит вот такое понятное сообщение об ошибке - UNSUPPORTED_GRANT_TYPE. Как же так, спрашиваю сам себя? Ведь я не менял grant_type=authorization_code в своем запросе;В коде спрингового сервиса даже в DEBUG логгировании нет никаких ошибок и стэктрейсов, потому что эта ошибка и не логгируется при выбрасывании.
Что делать?
Смотреть гит блэйм, кто же и что же поменял в этом
OAuth2TokenEndpointFilter, чудес же не бывает? А изменения кроются, на самом деле, внутри OAuth2AuthorizationCodeAuthenticationConverter. Метод
OAuth2EndpointUtils.getFormParameters раньше доставал из запроса и GET-параметры, и URL-encoded параметры, а теперь - только URL-encoded параметры. Как же так, почему раньше-то можно было? Иду в RFC Oauth 2.0 и вот ответ - following parameters using the "application/x-www-form-urlencoded"
То есть, еще месяц назад реализация OAUTH 2.0 в spring-authorization-server не соответсвовала RFC, принимая GET параметры! Так же ей не соответсвовал и мой код, отправляя GET параметры. Начав бомбить о том "да как так одна циферка зависимости ломает мой прекрасный код!" закончил философским "ошибаются все, и не боги горшки спринговые обжигают".
Тут есть и еще один вопрос, а почему я вообще изначально не прочитал нормально RFC и отправлял GET-параметры?
Потому, что до получения странной ошибки я просто думал, что мне будет достаточно посмотреть воркшоп автора книги Spring Security in Action - и в нем тоже показана отправка простых GET параметров. А значит, ошибаются не только контрибьюторы Spring, но и даже авторы книг о Spring.
Мои выводы
- ошибайтесь на здоровье;
- но, любите дебаг;
- и гитблэймы;
- и чтение спецификаций и RFC
GitHub
heisenbug-2023-autumn/rococo-auth/build.gradle at 55d71aef72ad0fd2cc2f59158e5da95142e7d067 · dtuchs/heisenbug-2023-autumn
Contribute to dtuchs/heisenbug-2023-autumn development by creating an account on GitHub.
🔥24👏4👍1😁1
Гемба в Додо
В конце декабря мы провели самую масштабную гембу за всю историю✊ Dodo Brands.
170 сотрудников офисов в разных странах (и я в том числе😁) перед Новым годом работали в пиццериях, делали кофе и развозили заказы нашим клиентам.
Как это было, что такое гемба и зачем мы используем подобные практики? Обо всём этом в новой статье на VC🍕
В конце декабря мы провели самую масштабную гембу за всю историю
170 сотрудников офисов в разных странах (и я в том числе😁) перед Новым годом работали в пиццериях, делали кофе и развозили заказы нашим клиентам.
Как это было, что такое гемба и зачем мы используем подобные практики? Обо всём этом в новой статье на VC
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17❤4
Подал заявку на продолжение воркшопа The art of JUnit extensions. Если честно - не планировал, но меня очень мотивировал отзыв одного из слушателей первой части:
Если не смотрел выступление Дмитрия, то крайне советую глянуть когда запись появится, там показывали пример целого механизма, одним винтиком из которого является контекст холдер)
Когда смотрел, не знал даже чего такое эти экстеншены и оно для меня прям взрывом мозга было, целый новый мир открылся моему взору
🔥25❤8👍1
#job #вакансия #додо
Итак, о моих вакансиях с подробностями. Первая - железячный QA. Мы ищем QA инженера в Москве или в Сыктывкаре, с опытом тестирования чего-то железного. То есть, мы пишем софт для касс, киосков самообслуживания, драйверы для них и т.д. Мы тестируем новое оборудование и софт для него. И если вы знаете такого QA - или вы вдруг сами такой - мы точно договоримся о приятных условиях работы. Важно - Т.к. работа с железками, а железки в офисе в Москве и в Сыктывкаре, то надо быть там или хотеть туда (в Москву, конечно 🥲) переехать. Пишите плиз мне напрямую - @dtuchs
Итак, о моих вакансиях с подробностями. Первая - железячный QA. Мы ищем QA инженера в Москве или в Сыктывкаре, с опытом тестирования чего-то железного. То есть, мы пишем софт для касс, киосков самообслуживания, драйверы для них и т.д. Мы тестируем новое оборудование и софт для него. И если вы знаете такого QA - или вы вдруг сами такой - мы точно договоримся о приятных условиях работы. Важно - Т.к. работа с железками, а железки в офисе в Москве и в Сыктывкаре, то надо быть там или хотеть туда (в Москву, конечно 🥲) переехать. Пишите плиз мне напрямую - @dtuchs
🔥17
Media is too big
VIEW IN TELEGRAM
#job #вакансия #додо
Вторая, и не менее важная - QA в команду Маркетплейса. Что такое наш маркетплейс - смотрите в видео. Основная особенность этой вакансии - работа с API, выстраивание процессов и, пожалуй, главное - частое переключение контекстов между разными небольшими приложениями, которые это API будут использовать. Вакансия точно будет интересна тем, кто не хочет месяцами и годами тестировать одно и то же. Опять таки - пишите мне, @dtuchs
Вторая, и не менее важная - QA в команду Маркетплейса. Что такое наш маркетплейс - смотрите в видео. Основная особенность этой вакансии - работа с API, выстраивание процессов и, пожалуй, главное - частое переключение контекстов между разными небольшими приложениями, которые это API будут использовать. Вакансия точно будет интересна тем, кто не хочет месяцами и годами тестировать одно и то же. Опять таки - пишите мне, @dtuchs
🔥18❤4
#job #вакансия #додо
Третья вакансия - Performance QA. Нужно желание ковыряться в инфре (у нас все в k8s), понимать что такое микросервисная архитектура, как работать с БД и для чего нужна Кафка. Мочь писать какой-нибудь код на Java (сложнее, чем Selenide + RestAssured) - тоже мастхэв. Вакансия на 146% инженерно техническая, но мы осознанно ищем мидла, а не сеньера, которому интересно ковыряться, решать проблемы и расти. Контакты те же (я🙂)
Третья вакансия - Performance QA. Нужно желание ковыряться в инфре (у нас все в k8s), понимать что такое микросервисная архитектура, как работать с БД и для чего нужна Кафка. Мочь писать какой-нибудь код на Java (сложнее, чем Selenide + RestAssured) - тоже мастхэв. Вакансия на 146% инженерно техническая, но мы осознанно ищем мидла, а не сеньера, которому интересно ковыряться, решать проблемы и расти. Контакты те же (я🙂)
👍12🤔3🔥2🥴1