fa
Feedback
Валерий | AQA Engineer | Автотестирование на Python | REST, gRPC, GraphQL

Валерий | AQA Engineer | Автотестирование на Python | REST, gRPC, GraphQL

رفتن به کانال در Telegram

Сделаю из тебя крутого AQA инженера на Python. • Преподаю лучшие тренинги по автоматизации тестирования API • Senior Python developer | AQA lead, 7 лет в IT

نمایش بیشتر
1 507
مشترکین
اطلاعاتی وجود ندارد24 ساعت
+57 روز
-430 روز
آرشیو پست ها
Настало время напомнить. Раньше у меня был очень крутой тренинг "Автоматизация тестирования REST & gRPC API". Он собрал очень большое количество положительных отзывов, был актуален для своего времени. Там было довольно много тем, но не хватало деталей. Тем не менее он подготовил много крутых экспертов. После этого я решил его усилить: убрать темы, которые были даны поверхностно и требовали более детального изучения, и уделить больше времени одной фундаментальной теме - фреймворку для REST API. На его архитектуре и подходах может строиться база любого API фреймворка независимо от типа API. Так появились тренинги "REST API Advanced" и "REST API Professional". REST API Advanced 🗓 Неделя 1: Введение в автоматизацию тестирования 10 уроков. Повторим основы Python, научимся генерировать простой код, рассмотрим базу API тестирования, напишем первые тесты и настроим автоматический прогон тестов в GitHub. 🗓 Неделя 2: Архитектура и работа с данными 4 урока. Научимся использовать паттерны проектирования для решения наших задач. А также научимся подготавливать тестовые данные и рассмотрим различные виды фикстур. 🗓 Неделя 3: Проверки 7 уроков. Рассмотрим все возможные виды проверок для API, научимся валидировать структуру данных и значения. Мягкие проверки, функции-чекеры, менеджеры контекста. Будем внедрять так, чтобы не засорять код и делать его более читаемым и поддерживаемым. 🗓 Неделя 4: Работа с конфигурациями и репортинг 7 уроков. Завершающая неделя: научимся собирать Docker образы, настраивать пайплайны, дорабатывать сторонние библиотеки, собирать coverage покрытия сервиса автотестами, строить красивые и информативные отчёты. Научимся отправлять отчёты о прохождении тестов в Telegram и перепишем пайплайн для GitLab CI. Вы создадите production-ready фреймворк с архитектурой уровня энтерпрайз систем. Сможете с нуля настроить CI/CD pipeline с метриками и уведомлениями. Станете тем QA, которого не сократят. Одного моего друга пригласили на Senior позицию, после того как он показал свой проект и рассказал, что и как он сделал. REST API Professional Результат: Вы научитесь создавать инструменты, которые делают работу за целые команды. Пока другие пишут код руками, вы генерируете готовые решения одной командой. Компании будут переманивать вас не за навыки, а за инструменты, которые вы умеете создавать. Модуль 1: Поговорим, что такое платформа и для чего она нужна Модуль 2: Научимся управлять зависимостями как профессионалы. Перепишем код, используя асинхронную парадигму, и рассмотрим, для каких задач она применима. Модуль 3: Научимся поддерживать стандарты и качество кода, разработаем общий пайплайн для контроля качества кода всех проектов, будем использовать линтеры и форматтеры. Модуль 4: Рассмотрим различные инструменты для генерации структуры проекта и кода. Научимся собирать свои библиотеки и дорабатывать опенсорс инструменты, выдавая стабильный результат в отличие от использования ИИ. Модуль 5: Соберём CLI инструмент, который генерирует всё: проект, клиенты, тесты, фикстуры. Поток стартует уже в понедельник, кто откладывал, лучше не откладывать, это последний поток в этом году. 🚀 ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

"АНГЛИЙСКИЙ - ЭТО НЕ УЧЁБА. ЭТО ПРЕОДОЛЕНИЕ СТРАХА" На Бали я говорил по-английски каждый день. В кафе, на рынке, с таксистами, с гидом. Мой английский далёк от идеала. Я путаю времена. Забываю слова. Строю предложения, как индус код пишет 😅 Но знаете что? Меня понимали. В начале отпуска была забавная ситуация: один австралиец услышал мой номер комнаты на баре. И пошутил, что типа сейчас будет оформлять всю выпивку на баре на мою комнату. Я ничего не понял, жена мне перевела, я поулыбался. В течение недели в Куте мы с ним пересекались, я просто махал ему рукой, типа привет. В последний день я пошёл на бар, и там он сидел со своим другом. Опять мы пересеклись, я махнул рукой, он начал смеяться и рассказывать своему кенту, как он пошутил. Потом я шёл из душа, и они крикнули: "Russian, come here!" Я подумал: "Хера ли они там выделываются?" - и пошёл. Дальше я сказал несколько своих коронных фраз: "май инглишь из бэд" и "ай спик инглишь э литл бит", "ай андерстенд иф ю спик слоу". И всё пошло-поехало. Через 10 минут меня уже угощали пивом, говорили, что у меня крутой английский, потому что они по-русски вообще ничего не могут сказать. Относились с пониманием, где не хватало моих мозгов - общались жестами. В общем, поржали, выпили за дружбу между народами и, конечно же, "Za zdorovie!" Когда я пытался пошутить, что я сгорел на солнце как "fried chicken", меня поняли, поржали, но поправили, что правильно говорить "roasted chicken". Таким образом я запоминал и понимал, как "правильно" говорить от носителей языка. И вот что я понял. В автоматизации тестирования - та же история. Некоторые знают Python на базовом уровне, но просто боятся начать писать код самостоятельно или пользуются только LLM - считай, переводчиком. Это здорово, но мешает заговорить самому. Кто-то уже хороший инженер, умеет писать код. Но применяет знания не совсем правильно, и им нужен "носитель языка", который подскажет, как сделать так, чтобы всё выглядело круто. Точно так же, как никто не смеялся над моим акцентом, а просто пытались меня понять и помогали сказать правильно - так и я помогаю моим студентам. ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

⛔️ КАСТОВАЯ СИСТЕМА На одной из первых экскурсий у нас была прекрасная женщина Lilis. Ей под 40 лет, но выглядит она много старше и очень неплохо разговаривает на русском. Работает гидом за небольшие деньги, а выучила русский, чтобы расширить возможности для работы, хотя русских туристов там не так и много. Мы спрашивали её о жизни на Бали. Узнали, например, что у них много детей, и они просто дают им имена по порядковому номеру. Putu - первый Kadek (или Kade) - второй Coma - третий И так далее. Дальше она рассказала, что у них кастовая система. То есть если отец был врачом, то и сын должен быть врачом, если отец водитель, то и сын водитель. Я спросил: "А как быть с другой профессией, например, если я хочу быть программистом?" Она даже не поняла вопрос, их жизненный флоу вообще не предполагает, что можно заняться чем-то другим, ответ был всегда стандартный: нельзя при жизни изменить касту. То есть девушка ещё может, если выйдет замуж за мужчину высшей касты, а парню - всё, труба. Многие живут так, что после школы идут массировать ноги иностранцам, и вместо выходных они просто меняют один салон на другой. И так повсеместно. Когда мы разговаривали с девушками-массажистками 19-ти лет, про их планы после школы, то это просто сводилось к тому, чтобы выйти замуж и работать. То есть какой там техникум или уж тем более вуз - у них даже таких мыслей в принципе нет. И как живём мы? Где некоторые даже бесплатно не хотят учиться. Где ты можешь выбирать судьбу сам, у тебя нет внешних ограничений в виде даже не общества, а государства, которое тебе просто в зависимости от рождения в той или иной касте режет возможности. И мы ведь этим даже не пользуемся, многие хают государство, город, родителей, да всё что угодно, только не себя, свой страх или лень. Вместо того чтобы попытаться взять от жизни то, что она может дать. Так вот, Lilis не может изменить свою жизнь - система не даёт. Вы можете, но не даёте себе. Но вы не на Бали. У вас есть выбор. Вопрос: воспользуетесь ли вы им? P.S. Следующий пост - про то, что я понял про английский на Бали. И это изменило моё понимание того, как нужно учиться) ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

КЕМ ТЫ БЫЛ 7 ЛЕТ НАЗАД? Вернулся из отпуска. Бали, Катар, куча впечатлений. Те, кто следят за мной в запрещенограмме, думаю, в курсе. Но главный вопрос, который я задавал себе в отпуске: "Каким я был 7 лет назад? И где бы я был сейчас, если бы не сделал выбор тогда?" Мог ли я представить, что смогу видеть другие культуры, общаться с людьми на другом языке, видеть всё своими глазами, а не по телевизору? Когда я жил в Омске, я всегда мечтал уехать за границу. Там я видел финансовую стабильность и безопасность, хотел быть просто в тихом месте, чтобы меня никто не трогал. Меня не сильно интересовали какие-то вызовы, хотелось хотя бы просто покоя. Сейчас, вопреки непопулярному мнению, я вижу, что в России гораздо больше возможностей и комфорта, чем во многих странах. Я понял, что богатые люди живут не на Бали - богатые люди живут в Москве и других крупных городах, потому что уровень доходов в какой-то мере определяется уровнем расходов. А на Бали ездят отдыхать. Да, на Бали может быть интересно две-три недели, но, по большому счёту, там делать нечего. Есть в кафе, кататься на сёрфе, плавать в бассейне - надоест довольно быстро. А обычная жизнь - это ещё походы к врачу, бытовая санитария, чистота вокруг, общение, сервис, да даже тупо влажность, от которой плесневеет всё вокруг, вечно влажное бельё и кровати. Таких моментов очень много. И туда едут жить на ПМЖ, по моему мнению, те, кто не может себе позволить жить в РФ комфортно, ну и единицы, потому что им действительно нравится. Но в большинстве случаев продаётся это всё под очень красивой мотивирующей картинкой. (Не рассматриваю тех, кто уехал по каким-то политическим соображениям). С каждым своим путешествием я всё больше убеждаюсь, что мне нравится жить в РФ, а вот ездить отдыхать за границу - чтобы видеть, как живут другие. Потому что путешествия, особенно если они больше двух недель, убирают розовые очки. И понимаешь: не везде хорошо, не только у нас плохо. То есть, если проанализировать: один выбор, сделанный мной 7 лет назад, а также ряд шагов, которые позволили прийти к той точке, в которой я сейчас. Когда не голодным взглядом смотришь на жизнь других, а сам можешь в какой-то мере планировать результат. То есть, по сути, выбор сводился к тому: остаться на текущем уровне и быть в безопасности или попробовать что-то новое и, возможно, провалиться. Но знай - через 5-7 лет ты всё равно будешь на 5-7 лет старше. Вопрос только: с какими навыками? В своём рилс Даниил Бобров автор тг канала https://t.me/bobrov_frontend сказал, что нет лучшего времени, чем сейчас, делать то, что запланировал. И знаете, я с этим полностью согласен. Есть ещё несколько моментов, которые я осмыслил, пока был в отпуске. А время подумать у меня там было)) Но о них — в следующих постах. ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

Почему тестирование брокеров сообщений - это отдельная наука Готовлю кодовую базу для курса по автотестированию брокеров сооб
Почему тестирование брокеров сообщений - это отдельная наука Готовлю кодовую базу для курса по автотестированию брокеров сообщений. Несмотря на кажущуюся простоту подключения к Kafka или RabbitMQ, там огромное количество подводных камней. Основная проблема: Брокеры предназначены для непрерывной работы, а автотесты - это всегда конечная история. Это кардинально меняет подход: В разработке: - Консьюмер работает non-stop и безотказно - Соединения устанавливаются один раз - Оптимизация под долгосрочную работу В тестировании: - Тесты должны выполняться максимально быстро - Частое создание/закрытие соединений - Каждый тест изолирован: "открыл → выполнил → забыл" Реальный кейс из разработки курса: Создал интеграционную цепочку: 1. API Handler → отправляет сообщение в Kafka 2. Kafka Consumer → обрабатывает событие регистрации пользователя 3. Database → сохраняет нового пользователя 4. RabbitMQ → отправляет событие на email 5. RabbitMQ Consumer → обрабатывает отправку письма Проблема: каждый компонент работал изолированно, но полная цепочка не функционировала. Что я пробовал: Различные настройки соединений Перезапуск приложения Эксперименты с таймаутами Отладка каждого звена отдельно Решение: Оказалось, что тест нашел реальный баг в приложении, а я упорно пытался "починить" тест! Проблема была в Kafka Consumer - сообщения попадали в топик, но не обрабатывались. Фикс оказался простым: изменить одну настройку в docker-compose для тестового окружения. Вывод: Именно поэтому нанимают тестировщиков-автоматизаторов - чтобы находить такие интеграционные проблемы, которые незаметны при изолированном тестировании компонентов. Тестирование брокеров сообщений - это сложная, многогранная тема со множеством нюансов: - Управление жизненным циклом соединений - Обработка таймаутов и retry-логики - Тестирование асинхронных цепочек - Изоляция тестов при работе с очередями Все подготовительные работы завершены, блокеры устранены. После отпуска планирую завершить запись курса и поделиться накопленными знаниями по этой непростой, но критически важной области автоматизации. Этот курс будет мегаполезен всем, кто сталкивается с тестированием распределенных систем и брокеров сообщений. Совсем скоро! 🚀 ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

Привет, вот и прошел E-CODE, было очень круто. Познакомился с 4 подписчиками, почувствовал себя звездой 🤣🤣🤣 Тем кто не смог попасть на мой доклад можно посмотреть по ссылке) Ну и всем хорошего дня)

🎉 С Днём программиста! 🎉 С участием в E-CODE совсем забыл сказать, чему он приурочен - а именно Дню программиста! Программи
🎉 С Днём программиста! 🎉 С участием в E-CODE совсем забыл сказать, чему он приурочен - а именно Дню программиста! Программирование - одно из самых увлекательных занятий. Уже несколько лет живу на дофамине от решения рабочих задач. Когда ковыряешься в коде неделями и наконец решаешь задачу - всегда есть легкая эйфория от того, что преодолел новое препятствие и справился! В современном мире этот навык позволяет автоматизировать свою деятельность и облегчить жизнь - будь то телеграм-бот или парсер для поиска лучших цен на отели и билеты - Отличная профилактика болезни Альцгеймера )) - А разработка - одна из интереснейших ветвей развития Automation QA Кайфую от момента, когда создаешь что-то, что экономит кучу времени тебе и команде. И да, это единственная профессия, где можно сломать всё одной строчкой кода, а потом героически это же исправить другой строчкой 😅 Поздравляю всех причастных к празднику! Желаю: • Интересных задач • Прекрасных побед 🏆 • Собственных крутых инструментов • Чтобы продакшн не падал по выходным!

Привет) Ну кто на месте можете подтягиваться. Познакомимся)
Привет) Ну кто на месте можете подтягиваться. Познакомимся)

Привет всем! 👋 Соскучился по вам, ребята! Было просто пздц много дел последнее время - выпустил очередную группу с курса, за
Привет всем! 👋 Соскучился по вам, ребята! Было просто пздц много дел последнее время - выпустил очередную группу с курса, закончил с подготовкой презентации на E-CODE. Напоминаю, что уже 13 сентября (это суббота!) будет E-CODE конференция - отличная возможность познакомиться со многими из вас лично! Кто планирует быть? 🤝 И так как сегодня 9 сентября - День тестировщика, то поздравляю всех качественных ребят)))! Пусть баги находятся легко, тест-кейсы проходят зеленым, а продакшн не падает по выходным! 😄

🎉 РОЗЫГРЫШ ЗАВЕРШЕН! Друзья, розыгрыш 2 бесплатных проходок на E-CODE завершился! Поздравляю победителей: 🏆 @Mariya_Kramer
🎉 РОЗЫГРЫШ ЗАВЕРШЕН! Друзья, розыгрыш 2 бесплатных проходок на E-CODE завершился! Поздравляю победителей: 🏆 @Mariya_Kramer 🏆 @saramagaziner Победители, напишите мне в личные сообщения — отправлю вам детали по получению билетов на конференцию! Всем огромное спасибо за участие! ❤️ Тем, кто не выиграл — не расстраивайтесь! Следите за каналом, будут еще интересные розыгрыши и полезный контент по API тестированию 🚀 Увидимся на E-CODE! 👋 P.S. Победители, не забудьте написать в ЛС в течение 48 часов, иначе выберу новых победителей 😉

📌 D – Dependency Inversion Principle (DIP) Принцип инверсии зависимостей “Зависимости должны быть от абстракций, а не от кон
📌 D – Dependency Inversion Principle (DIP) Принцип инверсии зависимостей “Зависимости должны быть от абстракций, а не от конкретных реализаций.” В DIP помогает строить гибкие, легко тестируемые и переиспользуемые компоненты. Особенно когда нужно подменить авторизацию, логирование, сделать allure-разметку или сбор coverage В чём суть? Класс не должен напрямую зависеть от конкретной реализации, он должен зависеть от интерфейса (абстракции). 🧪 Пример: плохая реализация (без DIP) Скажу честно, сам я тоже когда-то грешил завязываясь на конкретную реализацию клиента, в данном случае requests.Session()
class ApiClient:
    def __init__(self):
        self.session = requests.Session()

    def get_user(
        self, 
        user_id
    ) -> dict:
        response = self.session.get(
          f"{API_URL}/user/{user_id}"
        )
        return response.json()
Проблемы: • Жёсткая зависимость от requests, если мы захотим использовать, например httpx, мы не сможем этого сделать без изменения кода. • Нельзя замокать поведение в тесте • Нарушен DIP: клиент зависит от деталей ✅ Как сделать правильно (с применением DIP) То есть говорим какие методы обязательно должны быть у принимаемого на вход клиента. В Python нет интерфейсов в классическом понимании, поэтому abc.ABC и @abstractmethod — это абстрактные классы, которые эмулируют интерфейсы. 1. Вводим интерфейсы:
from abc import ABC, abstractmethod

class BaseHttpClient(ABC):
    @abstractmethod
    def get(
        self, 
        url: str, 
        **kwargs: Any
    ) -> dict:
        pass
2. Реализация: Наследуемся и описываем методы соблюдая контракт, "контракт" — это обязательство реализовать методы, объявленные в абстракции (BaseHttpClient). При соблюдении этих правил, любой клиент, который соблюдает контракт, может быть безболезнено (в идеале) использован.

class HttpClient(BaseHttpClient):
    def get(
        self, 
        url: str, 
        **kwargs: Any
    ) -> dict:
        return requests.get(url, **kwargs).json()
3. Внедряем зависимости: То есть любой наследник BaseHttpClient не должен поломать код.
class ApiClient:
    def __init__(
        self, 
        http_client: BaseHttpClient
    ):
        self.http_client = http_client

    def get_user(self, user_id, headers) -> dict:
        return self.http_client.get(
          f"{API_URL}/user/{user_id}", 
          headers=headers,
        ).json()
🧪 Теперь в тесте:
# Мы можем или замокать клиент тем самым написать тест без реального апи
class MockHttpClient(BaseHttpClient):
    def get(self, url, headers):
        return {"id": 123, "name": "Test User"}

def test_get_user():
    client = ApiClient(MockHttpClient())
    user = client.get_user(123)
    assert user["id"] == 123


# Можем добавить свою логику, например логгирование запроса
class LoggedHttpClient(BaseHttpClient):
    def get(
        self, 
        url, 
        headers
    ) -> dict:
        print(url, headers)
        response = self.http_client.get(
          url, 
          headers=headers
    )
        print(response.text)
        return response.json()


# И здесь тест уже будет с логами
def test_get_logged_user():
    client = ApiClient(LoggedHttpClient())
    user = client.get_user(123)
    assert user["id"] == 123
Профит: • Подменили зависимости без боли • Не нужен реальный backend для тестов • Код клиента не меняется — только зависимости DIP особенно полезен когда: • Пишешь интеграционные и контрактные тесты • Нужно мокать внешние сервисы • В проекте много обвязки (логов, ретраев, токенов) — и ты хочешь это всё отделить • Требуется расширяемость (добавить кеш, валидацию, другой http-клиент) Вывод Применение DIP в API‑тестах: 🔹 Упрощает подмену зависимостей 🔹 Повышает читаемость и тестируемость 🔹 Позволяет изолировать бизнес‑логику от инфраструктуры 🔹 Снижает связанность компонентов 🔥Перешли другу\коллеге пусть тоже знает) На этом мы закрываем тему SOLID. ) ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

Кнопочку не забываем жмякать на посте)

🎉 Держу слово! Как и обещал, у меня есть 2 бесплатные проходки на E-CODE Напомню, что это за событие: • Крутые спикеры и технические доклады (включая мой 😎) • Отличный нетворкинг с коллегами по цеху • Очень. Много. Еды. 🍕 • Возможность погрузиться в мир современных технологий 📋 Условия участия в розыгрыше: 1️⃣ Быть подписанным на мой канал 2️⃣ Быть подписанным на @ozon_tech 3️⃣ Поставить ❤️ под этим постом 🗓 Розыгрыш проведу в следующий понедельник — 01.09 Победителей выберу рандомом среди всех участников. Участвуйте, друзья! Это отличная возможность попасть на качественное техническое мероприятие и лично пообщаться 🤝 Participants: 0 Prizes: 2 Giveaway date: 13:00, 01.09.2025 MSK (6 days)

#solid 📌 I – Interface Segregation Principle (ISP) Принцип разделения интерфейсов “Не заставляй клиента зависеть от того, чт
#solid 📌 I – Interface Segregation Principle (ISP) Принцип разделения интерфейсов “Не заставляй клиента зависеть от того, что он не использует.” В автоматизации это часто встречается, когда в один «удобный» хелпер пихают вообще всё подряд — и API, и UI, и БД. 🧪 Пример Представим, что кто-то решил упростить жизнь и создал “универсальный” интерфейс:
class TestHelper:
    def get_sms_code_by_api(self): ...
    def login_from_ui(self): ...
    def check_user_created_in_db(self): ...
    def get_kafka_message(self): ...
Теперь любой тест, независимо от контекста, тянет за собой весь этот набор. • Тесты на API зависят от методов, которые они не используют • UI‑тесты вынуждены тащить зависимости от kafka или БД • Такие классы очень быстро увеличиваются в размерах, их становится тяжело поддерживать. Нарушен ISP — мы создали жирный интерфейс, который знает всё и сразу. ✅ Как исправить? Разделить интерфейсы по зонам ответственности:
class ApiHelper:
    def get_sms_code(self): ...

class UiHelper:
    def login(self): ...

class KafkalHelper:
    def get_message(self): ...

class DbHelper:
    def check_user_created(self): ...
Теперь каждый тест получает только то, что ему реально нужно:
def test_ui_login(ui: UiHelper):
    ui.login()

def test_registration_in_db(db: DbHelper):
  ...
    db.check_user_created()
Как правильно сделать удобный хэлпер, не нарушая принцип ISP?
class TestHelper:
  def __init__(
    self, 
    ui: UiHelper, 
    db: DbHelper, 
    kafka: KafkalHelper, 
    api: ApiHelper
  ) -> None:
    self.ui = ui
    self.kafka = kafka
    self.db = db
    self.api = api
Теперь TestHelper — это фасад, который объединяет несколько интерфейсов, но не нарушает ISP, потому что: 1. Клиенты (тесты) зависят только от того, что используют – если тест работает только с UI, он может обращаться только к helper.ui, не зная о других модулях. 2. Интерфейсы внутри фасада разделены – UiHelperApiHelper и другие остаются независимыми. Теперь мы используем только то что нужно, но при этом не нарушаем ISP и тест выглядит так.
def test_user_registration(helper: TestHelper):
  helper.ui.login()
  helper.api.get_sms_code()
  helper.kafka.get_message()
  helper.db.check_user_created()
🔧 Когда мы соблюдаем ISP то: • Проще вникнуть в небольшие независимые классы • Проще переиспользовать компоненты • Удобно если много интеграций API, UI, DB Вывод: Соблюдение ISP делает код: 🔹 Более модульным — только нужные зависимости 🔹 Легче тестировать 🔹 Проще поддерживать, меньше случайных поломок ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

Привет! Много чего навалилось, и давненько не выкладывал постов 😅 Сейчас активно готовлюсь к докладу на E-CODE. Вчера был тестовый прогон, будет ещё два. Нужно править презентацию, параллельно закрывать таски на работе и, естественно, не забывать вести группу, которая у меня сейчас учится. Поэтому активностей много — сижу работаю до ночи 🌙 Из хороших новостей: недавно вы просили проходки на E-CODE. А я прислушиваюсь к своим подписчикам и сходил к нашим организаторам — пока пообещали 2 проходки, которые, если всё сложится, будут разыграны в моём канале! 🎉 Почему стоит поучаствовать? • Крутые спикеры (в том числе и я) и доклады • Крутая атмосфера и нетворкинг • И как написано в приглашении — Очень. Много. Еды. 🍕 Как только всё согласуют с маркетингом, обещаю вернуться и сделать розыгрыш проходок! Билеты на E-CODE именные по документам, поэтому просто так туда не попадёшь.

👆👆👆👆👆 Вебинар «Практический разбор способов авторизации в Postman» Привет, я Надежда Дудник, автор канала ProTestingInfo
👆👆👆👆👆 Вебинар «Практический разбор способов авторизации в Postman» Привет, я Надежда Дудник, автор канала ProTestingInfo 👋 17 августа в 16:00 (MSK) приглашаю тебя на бесплатный вебинар по работе с токенами, данными client_id, client_secret и авторизацией в Postman. Данный вебинар проводится в рамках курса по подготовке на собеседования ПО и курса по тестированию бэкенда. 👩‍💻 Кому будет полезно - Тестировщикам, которые хотят уверенно работать с API - Тем, кто готовится к собеседованиям - QA, которые путаются в способах авторизации 🖇Что будет - Разница между авторизацией и аутентификацией; - Разбор часто используемых способов авторизации: Basic Auth, Bearer Token, JWT, OAuth 2.0, API Key, mTLS (по сертификатам), cookies, используя открытые OpenAPI российских и зарубежных документаций для разработчиков; - Живые примеры в Postman с пояснением, где и зачем использовать каждый. 🕶 Зачем приходить - Быстро разбираться в API любой сложности; - Избежать ошибок при тестировании авторизации; - Уверенно отвечать на собеседованиях; - Научиться читать OpenAPI документацию и на что обращать внимание. 📒 Когда: 17 августа (воскресенье), 16:00 (MSK), продолжительность до 2-х часов. 🗺 Где: ProTestingInfo 💬 Формат: практика + примеры + теория 🔗 Присоединяйтесь к protestinginfo - будет интересно и с пользой для вашей работы и продуктивного обучения!
⚠️ На вебинаре у нас будет практика, но некоторые кейсы я покажу только в формате демонстрации - повторять за мной в реальном времени не обязательно. Для этих шагов потребуется создать организации, пространства, проекты, использовать номера телефонов, адреса электронной почты, формировать ссылки. Это достаточно объёмный процесс, поэтому я покажу его на примере, чтобы мы смогли сохранить темп и успеть пройти весь материал. Запись вебинара останется у вас, и вы сможете повторить всё самостоятельно. А если будет запрос, проведу отдельный интенсив, где сделаем каждый шаг вместе.

ВТОРАЯ НЕДЕЛЯ ТРЕНИНГА — ЗАВЕРШЕНА! Получил домашки от студентов, и результат классный! ✅ Что освоили наши студенты за вторую
+3
ВТОРАЯ НЕДЕЛЯ ТРЕНИНГА — ЗАВЕРШЕНА! Получил домашки от студентов, и результат классный! ✅ Что освоили наши студенты за вторую неделю: - Внедрили архитектурные паттерны в тестовый фреймворк - Настроили Proxy для детального логгирования API-запросов - Реализовали Facade для упрощения работы с клиентами - Добавили Decorator для автоматической обработки ошибок и retry-логики - Освоили генерацию динамических тестовых данных через фикстуры - Внедрили параметризацию и Data-driven подход в тесты 💡 Результат превзошёл ожидания: Студенты действительно превратили "не очень красивые тесты" в элегантный, масштабируемый код! Архитектура стала читаемой, поддерживаемой и готовой к росту. Если вы сравните код из прошлой недели, то почувствуете разницу) ЧТО ДАЛЬШЕ? Третья неделя будет посвящена системе проверок: 🎯 Комплексная система валидации - Виды проверок и их применение - Базовые проверки ответов API - Проверка структуры и типов данных JSON - Валидация значений в JSON структурах 🎯 Продвинутые техники проверок - Менеджеры контекста для группировки проверок - Мягкие проверки (soft assertions) - Создание собственных функций-чекеров Цель: Построить bulletproof систему валидации, которая найдёт любую проблему в API! 🎯 Уже сейчас видно, что студенты получают очень крутые навыки AQA automation engineer! Всем отличных выходных, увидимся на третьей неделе! 💪 ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

Привет, озону даже не нужно платить мне за рекламу) Почему? Потому что мой доклад взяли в программу конференции E-CODE Очень
Привет, озону даже не нужно платить мне за рекламу) Почему? Потому что мой доклад взяли в программу конференции E-CODE Очень крутая конференция всем рекомендую. А я со своей стороны приглашаю вас туда, может познакомимся с кем то лично) На предстоящей конференции буду рассказывать про: ✅ Восстановление полной схемы gRPC-сервиса через рефлексию ✅ Собственный плагин для protoc с удобными Python-клиентами ✅ Собственную open source библиотеку BPReflect для автоматизации всего workflow. Работа с gRPC станет для вас изи каткой. Так что велкам) Приходи и поделись постом с друзьями. ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

📌 L – Liskov Substitution Principle (LSP) Принцип подстановки Лисков «Если в коде вместо базового класса подставить его насл
📌 L – Liskov Substitution Principle (LSP) Принцип подстановки Лисков «Если в коде вместо базового класса подставить его наследника — поведение не должно ломаться.» На самом деле было довольно сложно было придумать пример в контексте автотестирования, но давайте попробуем. 🔍 Как это работает? Допустим, есть базовый API-клиент с аутентификацией:
class BaseApiClient:
  # Возвращает токен для аутентификации.
    def get_auth_token(self) -> str:
        raise NotImplementedError

  # Авторизованный запрос
    def send_request(self, url: str) -> Response:
        token = self.get_auth_token()
        headers = {"Authorization": token}
        return requests.get(url, headers=headers)
Ок, теперь реализуем двух клиентов:

class AuthClient(BaseApiClient):
    def get_auth_token(self) -> str:
        return "Bearer token"  # Корректный токен

class NoAuthClient(BaseApiClient):
    def get_auth_token(self) -> str:
        return None  # вот тут уже подозрительно
А дальше кто-то пишет код, который работает с клиентом:
def test_send_request(client: BaseApiClient, url: str):
  url = "http://some-api.com/endpoint"
    return client.send_request(url)  
С AuthClient все ок. С NoAuthClient словим баг: {"Authorization": None }. Почему? Потому, что поведение наследника не соответствует ожиданиям. ✅ Как правильно: Если NoAuthClient не поддерживает аутентификацию, не нужно заставлять его реализовывать метод, который делает вид, что всё ок. Лучше изменить архитектуру: - вынести токен в отдельный класс (AuthProvider) - если часть клиентов не поддерживает аутентификацию, вынесем эту логику в отдельный класс/интерфейс:
class AuthProvider(ABC):
    @abstractmethod
    def get_auth_token(self) -> str:
        pass

class Auth(AuthProvider):
    def get_auth_token(self) -> str:
        return "Bearer token"  # Корректный токен

class BaseApiClient:
    def send_request(
      self, 
      url: str, 
      headers: Optional[dict] = None
    ) -> requests.Response:
        return requests.get(url, headers=headers)

class AuthApiClient(BaseApiClient):
    def __init__(self, auth: AuthProvider):
        self.auth = auth

    def send_request(self, url: str, **kwargs) -> requests.Response:
        token = self.auth.get_auth_token()
        headers = kwargs.get("headers", {})
        headers["Authorization"] = token
        return super().send_request(url, headers=headers)
Теперь клиент отработает без ошибок.
# и этот клиент
client = AuthApiClient(RealAuth())

# и этот клиент отработает
client = BaseApiClient()


def test_send_request(client: BaseApiClient, url: str):
  url = "http://some-api.com/endpoint"
    return client.send_request(url)  
Вывод: Соблюдение LSP: 🔹 Делает поведение предсказуемым 🔹 Спасает от скрытых багов 🔹 Позволяет переиспользовать код без костылей ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

📚 Новый учебный проект: Awesome Tests Project Как преподаватель API тестирования часто сталкиваюсь с вопросом: "Как правильн
📚 Новый учебный проект: Awesome Tests Project Как преподаватель API тестирования часто сталкиваюсь с вопросом: "Как правильно структурировать большой тестовый проект?" Создал open-source пример того, как я вижу масштабируемую архитектуру интеграционных тестов: 🎯 Особенности: • Планируется поддержка множества технологий (HTTP, gRPC, DB, Redis, Kafka), на текущий момент можно увидеть только HTTP, остальное в планах. • Четкое разделение фреймворка и тестов • Переиспользуемые компоненты • Готовность к росту команды и проекта • В проекте я использую собственные библиотеки Проект больше основан как монорезозиторий для всего app, сделано это для того, чтобы в одном проекте соединить все базовые технологии. В идеальном мире под каждый сервис должен быть свой проект. 💻 Технологии: Python 3.11+, Httpx, Pytest, Pydantic, Poetry + собственные библиотеки для генерации кода Проект создан для изучения и как reference implementation. Все исходники открыты, документация внутри. 🔗 https://github.com/ValeriyMenshikov/awesome-tests-project Сохраняйте в закладки и ставьте звездочку! ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы