LikeaDuck🦆
1.45K subscribers
65 photos
3 videos
97 links
Дима Тучс (https://t.iss.one/dtuchs). QA директор в DODO, спикер и программный комиттёр на конфах, создатель авторского курса QA.GURU Advanced. Здесь будет об IT, QA, менеджменте и немного обо мне.
Download Telegram
О чем врут тестировщикам.
И тестировщики?

Свой взгляд на большие проблемы в образе мыслей QA инженеров будет в моем offline докладе на Codefest. Приходите, если вы в Новосибирске 🙂
🔥1413👍2
#java #обучение #qaguru

Вчера провел первое занятие уже 5-го потока своего авторского курса Java Advanced в QA.GURU. Как и все предыдущие, курс будет глубоко погружать в разработку и тестирование вокруг Java.

Если вдруг кто-то из вас желает залететь в уходящий поезд 5-го потока, можете воспользоваться моим персональным промокодом DTUCHS10, который даст вам скидку 10% до 25 апреля включительно. Для активации промокода напишите в QA.GURU-SALES.
10
#gradle

О моем любимом Gradle.
Имеем мы, значит, официальный туториал Spring о том, как настроить генерацию JAXB. Идем по нему, вставляем в наш build.gradle строки из туториала и - все работает 🙂. Строки такие:
task genJaxb {
ext.sourcesDir = "${buildDir}/generated-sources/jaxb"
ext.schema = "src/main/resources/countries.xsd"
...


И все бы ничего, но ${buildDir} самим Gradle объявлена deprecated, и здравствуй вечный WARNING при сборке проекта, а в будущем - и невозможность перейти на какой-нибудь Gradle 9 или 10. Сейчас я на 8.6.

Что может быть проще загуглить на что предлагают заменить ${buildDir} сами разработчики gradle? И есть официальный док, который дает нам ответы на этот вопрос:

Deprecations
Deprecated Project.buildDir is to be replaced by Project.layout.buildDirectory
The Project.buildDir property is deprecated. It uses eager APIs and has ordering issues if the value is read in build logic and then later modified. It could result in outputs ending up in different locations.

It is replaced by a DirectoryProperty found at Project.layout.buildDirectory. See the ProjectLayout interface for details.


И есть даже пример кода:
было: file("$buildDir/myOutput.txt")
стало: layout.buildDirectory.file("myOutput.txt")

Ну, все просто, но кажется .file в нашем случае лучше заменить .dir. Пишем:

tasks.register('genJaxb') {
ext.sourcesDir = "${Project.layout.buildDirectory}/generated-sources/jaxb"
ext.classesDir = "${Project.layout.buildDirectory}/classes/jaxb"
...

Собираем проект, и ошибка:
`No such property: layout for class: org.gradle.api.Project
Possible solutions: layout`

ОКЕЙ, пробуем по-другому
    ext.sourcesDir = "${layout.buildDirectory}/generated-sources/jaxb"
ext.classesDir = "${layout.buildDirectory}/classes/jaxb"
...

и классы генерятся в niffler-gateway/property(org.gradle.api.file.Directory, fixed(class org.gradle.api.internal.file.DefaultFilePropertyFactory$FixedDirectory, /Users/dmitriitucs/IdeaProjects/qg/niffler/niffler-gateway/build))/generated-sources - уже лучше, есть прогресс, но хотелось то в build/generated-sources🙂

Идем дальше
    ext.sourcesDir = layout.buildDirectory.dir("generated-sources/jaxb").toString()
ext.classesDir = layout.buildDirectory.dir("classes/jaxb").toString()

- ну вот это-то должно нам дать строку с путем к папке?
результат опять с таким путем:

niffler-gateway/map(org.gradle.api.file.Directory property(org.gradle.api.file.Directory, fixed(class org.gradle.api.internal.file.DefaultFilePropertyFactory$FixedDirectory, /Users/dmitriitucs/IdeaProjects/qg/niffler/niffler-gateway/build)) org.gradle.api.internal.file.DefaultFilePropertyFactory$PathToDirectoryTransformer@4fe6e613)/guru/qa/niffler/userdata/wsdl

КОРОЧЕ ВОПРОС. Кто знает как это прописать чтоб работала mkdir и создавала папку тупо build/generated-sources🙂?? Ни чатгпт, ни гугл пока не помогли. Так и живем с Gradle 🙂
👍1😁1
Среда - день хороших новостей!

Сегодня опубликован подкаст "Гости из IT" с моим участием и тем самым Антоном Комоловым😁

В подкасте никаких JUnit-ов и Gradle-ов не будет, но точно будет много моих мыслей о состоянии дел с QA. Интересно будет всем, залетайте, слушайте, пишите комменты, опровергайте, и будьте крутыми QA 🚀
🔥267👏4
Анонсирую продолжение Сибирского тура оффлайн выступлений. Вслед за выступлением на Codefest 25 мая я поеду в Омск на небольшую, но обещающую быть ламповой конфу Сибирь.JS 22-23 июня. Буду рад пообщаться offline со всеми 🙌
🔥32
Вернулся из отпуска в Малайзии, Сингапуре и Корее. Так много эмоций, что хочется разбавить канал тревел-блогерством🙂 А пока я ездил в отпуск - пригласили в гости на еще один подкаст QAk-QAk — и в продакшен. Из интересного - будем пробовать записывать прямо во время Codefest, обсуждать будем мой доклад и не только.
🔥49👍4
Когда код пишет нервный программист, ошибка выглядит как минимум так 🙂 Программист если что не я, а кто-то из grpc-ecosystem
😁31
#automation #patterns

Давненько не писал ничего околотехнического, и сегодня про вопрос с собеседований "А какие паттерны знаешь"?

Что я думаю про PageObject и гордо звучащий PageFactory, про которые вспомнят 9 из 10 на этот вопрос?

Первое - это не "паттерн" в прямом смысле этого слова. В том смысле, что если мы будем делать ООП-программу про зоопарк, там будет обект "Жираф" с полями "private вес" и "private рост" и методами "поесть()" / "поспать()". Так же будет объект "Зебра" и объект "Вомбат". Можно ли сказать, что мы изобрели паттерн "ЗверьОбжект"? В нашей системе каждый зверек это объект. в котором есть свойства (поля) и методы, через которые мы взаимодействуем с ним.

Так вот, Web-тесты на Java (и другом любом ООП языке) - и есть программка про зоопарк (про веб-странички), и PageObject - это просто класс с полями и методами, описывающий предметную область. И если понимать это, то легко понять и точку зрения, например, Андрея Солнцева: "PageObject не всегда и не очень-то и нужен". Ровно в той же степени, как класс (объект) "Жираф" может быть не очень то и нужен, если в нашем зоопарке с ним не так уж и много взаимодействий. И если дизайн этого класса сделан плохо.

А PageFactory - это чтение аннотаций в классе, которому придумали нелепое название. Это не имеет никакого отношения к Factory - который, сам по себе, хороший паттерн и встречается часто.
А еще я встречал точку зрения, что если методы в PageObject возвращают ссылку this, то это PageFactory. Что тут сказать? Я не знаю откуда взялось мнение, что это так называется. В ООП у этого есть вполне конкретное название - Fluent interface.

Поэтому не надо на собеседовании говорить, что вы знаете паттерны PageObject и PageFactory.

На такой вопрос лучше ответить так:
Если вы меня спрашиваете про "паттерны тестировщиков" и хотите послушать про PageObject - я вам расскажу, но если вас интересует понимаю ли я, что такое Decorator, Singleton, Proxy, Factory (настоящую) - то сейчас я вам расскажу про них
.

И рассказать 🙂
29👍14🔥6👎1
В самое сердце 💙
45👍5👎1
Codefest #14 сегодня закончился.

Хочу рассказать про свою работу в программном комитете этой конференции (в котором я уже три года подряд).

Я точно не самый ответственный ПК-шник, особенно пару последних лет, когда перешёл в ДОДО и стал иногда сходить с ума от созвонов и дел на работе. Я вел мало докладчиков в этом году.

И все же, знаете, я испытываю гордость за те немногие доклады (их было всего три), к которым я действительно приложил руку. Я иногда сам себе кажусь "злым полицейским" на прогонах: увеличь текст! Слишком много текста! Слишком много кода! Слишком мало кода! С какой главной мыслью человек уйдет из зала?

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

Мне уже почти 35, мне больше хочется радоваться за чужие доклады, а не за свои.

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

Посмотрите его когда-нибудь после.
29🔥10👍4
Об интересных багах, обнаруживаемых прямо в ресторане;

Есть у нас телевизоры, показывающие статус заказа. И есть возможность завести себе длинное имя в приложении - например, в честь советского журнала "Юный натуралист". И в результате имеем очень загадочного юного натурала...

Как бы вы предложили это пофиксить?
И какие еще можете придумать имена, которые будут забавно обрезаться по маске {12 символов}{3 точки}? 😁
😁42🤣1
#Менеджмент

Только что прочитал в одном из QA каналов, что главная проблема начинающих лидов (менеджеров) - делегирование. И это правда🥲 Но, есть еще одна - критически важная - вещь в менджерстве, о которой мало говорят.

Я ее называю "работа с сомнениями".

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

К сожалению, часто мы видим менеджеров которые чем-то недовольны, но не идут к решению проблемы. Почему? Потому что возникает необходимость принимать на себя риски и ответственность (кстати, понимание слова ответственность - повод для отдельного поста🙂).

На мой взгляд, при возникновении сомнений, надо обязательно с ними работать, что бы качнуть весы в ту или иную сторону. И, кстати, если меня просят на собесе вспомнить свои менеджерские фэйлы - почти все они связаны с тем, что я давал этим сомнениям "самим рассосаться".

Сомнения надо устранять.
💯19👍14
16 ноября в Алматы будет крупный IT-event "от авторов и создателей" уже легендарного Сибирского Codefest. Я, как участник Программного комитета, жду ваши заявки по QA теме в нашем CFP. А на любые вопросы о конфе постараюсь ответить в треде.
6👍3
Кружка за второе место в рейтинге зрительских симпатий СИБИРЬ JS...🥲 А первое место - и заслуженно - у Вадима Никитенко из Раййфа. Подписывайтесь, Вадим крутой: джавист, тайпскрипист и создатель крутых презентаций.
18🔥10👍7
Куда опять пропал Дима?

После Сибирь.JS уехал в отпуск на Алтай и накопил целую кучу новостей и мыслей, которыми и начинаю делиться прямо сейчас. И начну с подкаста, который мы записали прямо во время Codefest 2024 с ребятами из Т-банк (да-да, чуть было не написал Тинькофф🥲)

🎙 О чем болтали?
— Выясняли, как работают QA в Dodo Engineering и можно ли поймать баги прямо в пиццерии.
— Обсуждали, на что ориентироваться, чтобы нанять правильного кандидата и какие книжки нужно читать, чтобы понравиться директору по качеству 😁.
— Узнаем, в какой день пиццерии испытывают самую высокую нагрузку и как выход на зарубежный рынок влияет на тестирование.

Слушайте на любимых платформах:
Яндекс.Музыка
Apple Podcasts
Youtube
Остальные платформы
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥293🥰2
#patterns #automation

О неправильном понимании Принципа единственной ответственности (Single-responsibility principle) применительно к PageObject.

На днях один из моих студентов задал вопрос:

Добавили в РО вместе с остальными шагами. Насколько правильно шаги с ассертом объединять в одном РО?
Вот в РО на авторизацию. У меня есть и шаг заполнения полей с кликом и проверка результата. На работе настучали по рукам, чтобы проверка была не в РО, а именно в тесте


Казалось бы, простой вопрос с простым ответом🙂
И далее:

Я после своего вопроса решил сам исследовать проблему. В некоторых "умных книжках", сказали, что нельзя использовать ассерты. Так как разделяют на: "методы для взаимодействия с элементами страницы" и "методы для проверки состояния элементов страницы". Это, как я понимаю, ведет к нарушению принципа SOLID по единой ответственности и поэтому нельзя.


И вот тут я понял, что надо писать пост.

Всем мы на подсознательном или осознанном уровне понимаем, что такое Single responsibility. Это - максимально упрощая - когда класс UserController отвечает за создание и редактирование юзеров, и не отвечает за отправку e-mail-ов с прогнозом погоды.

На чем базируется это с технической точки зрения в ООП?

На инкапсулированных зависимостях UserController-а. Нет, я понимаю что все можно написать на static методах, но все-таки, UserController должен выглядеть примерно так:

class UserController {
private final UserRepository userRepository;


и вот этот userRepository - он работает с юзерами в БД (я в курсе, что инжектить репозитории в контроллеры не надо, это просто пример).

Важно тут то, что наш UserController не должен инкапсулировать EmailWeatherNotifier, и чисто технически не должен получить возможность отвечать за что-то не то (нарушать S в слове SOLID).

А теперь к PageObject🙂:

class LoginPage {
private final SelenideElement usernameInput = $("#username");
private final SelenideElement passwordInput = $("#password");


Что он инкапсулирует? Элементы на странице. У этих элементов есть метод click(), setValue(...) и, внезапно, shouldBe(...).
Я не понимаю, как использование shouldBe(...) (ассерта) может являться здесь нарушением Single responsibility, а setValue(...) - нет.

И то, и другое - это работа со страницей авторизации. И это и есть одна ответственность класса LoginPage.

Пока в ваших PageObjecta-х инкапсулированы только элементы страницы, вы не нарушите никаких Solid-ов.

Добавляйте методы с ассертами и проверками в свои PageObject-ы на здоровье, если хотите - не добавляйте, создавайте AssertObject-ы, но во всех этих случаях - не слушайте псевдоумные рассуждения про SOLID применительно к данному случаю.
👍272
На Сибирь.JS проводил перепись олдфагов в формате 100к1 с вопросом - "Из каких шагов состоит CI с тестами?", задаваемого мной на собесах новичкам в автоматизации после тех или иных курсов. Первые 2 самых популярных ответа видны на фотках, а кто угадает оставшиеся 4?
🔥16😁3