Валерий | AQA Engineer | Автотестирование на Python | REST, gRPC, GraphQL
1.51K subscribers
164 photos
152 videos
1 file
177 links
Сделаю из тебя крутого AQA инженера на Python.

• Преподаю лучшие тренинги по автоматизации тестирования API
• Senior Python developer | AQA lead, 7 лет в IT
Download Telegram
“Если оно ходит как утка… 🦆” — питон не требует паспорта.

А вы знали, что Python поддерживает несколько видов типизации? 🤔

Например:
- 🦆 
Утиная
- 🦢 Гусиная
- 📜 Статическая утиная типизация
- 🔍 Статическая типизация

В этом посте поговорим про ту типизацию, которая изначально была в Python — Утиную.

Одно время я все никак не мог понять, что это такое. Если вы уже в теме — отлично! Если нет — сейчас расскажу.

Python — язык про поведение, а не про формальности. 

Здесь не так важно, от какого класса ты наследуешься.
Важно, что ты умеешь делать!


Пример:
Представь, тебе нужна "последовательность": список, массив, колода карт — не суть.

Python не будет проверять, наследуешься ли ты от `list` или `collections.abc.Sequence`.

Он просто попробует вызвать:

- __len__()
- __getitem__()

Если получилось — значит, ты "последовательность".

class FrenchDeck:  
def __init__(self):
self._cards = []

def __len__(self):
return len(self._cards)

def __getitem__(self, pos):
return self._cards[pos]



🔎 
Обратите внимание:  этот класс ни от кого не наследуется!

Но его можно:
- перебирать в цикле,
- брать срезы,
- передавать в `sorted()`, `random.choice()` и т.д.

Потому что он ведёт себя как список!

То есть тебе просто нужно реализовать нужные методы — и этого достаточно.

🦆 Что такое утиная типизация?

“Если что-то ходит как утка, крякает как утка — значит, это утка.”

Такой подход даёт гибкость:
- Можно писать адаптивный код без лишней иерархии.
- Главное — понимать, какие "протоколы поведения" ждёт от тебя Python.

Хочешь разбираться в таких концепциях глубже?
Учись читать поведение, а не только сигнатуры!

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩77🔥7👍53🆒1
Гусиная типизация — когда утки 🦆 недостаточно
(а интерфейс всё-таки нужен)

В Python есть утиная типизация — “если выглядит как утка и крякает как утка — это утка”.
Это удобно. Но не всегда безопасно.

Название «гусиная типизация» возникло как противопоставление «утиной»: если утиная типизация в Python ориентируется на поведение объекта (если у него есть нужные методы — значит, подходит), то гусиная делает акцент на происхождение — как в биологии, где гусей и уток раньше классифицировали по внешнему сходству, но позже стали объединять по общим предкам (кладистика). Аналогично в программировании: два класса могут иметь одинаковые методы (например, draw()), но с разным смыслом — и потому они не обязательно взаимозаменяемы. Гусиная типизация требует явного указания интерфейса через абстрактные базовые классы (ABC) — чтобы быть уверенным, что объекты действительно «родом» от нужного интерфейса, а не просто «выглядят похоже».


Иногда нужно чётко сказать:
“Я реализую этот интерфейс” — и получить защиту на уровне кода.

Вот тут появляется гусиная типизация 🦢.

Что это такое?
Гусиная типизация — это подход к проверке типов во время выполнения, основанный на использовании абстрактных базовых классов (ABC).


Да, в Python нет ключевого слова interface, но есть модуль abc, который позволяет создать интерфейс через абстрактный класс.

Пример:
from abc import ABC, abstractmethod

class MessageSender(ABC):
@abstractmethod
def send(self, message: str) -> None:
pass

class TelegramSender(MessageSender):
def send(self, message: str) -> None:
print(f"Отправлено в ТГ: {message}")

class EmailSender:
def send(self, message: str) -> None:
print(f"Письмо: {message}")


Теперь можно сделать проверку:
isinstance(TelegramSender(), MessageSender)  # True
isinstance(EmailSender(), MessageSender) # False


Хотя EmailSender реализует метод send, он не унаследован от MessageSender.
Python этого не “засчитает” — и это отличие от утиной типизации.

Для чего это нужно?
- Когда важно явно указать, что ты реализуешь интерфейс
- Когда нужна статическая проверка типов (например, через mypy)
- Когда hasattr() уже не спасает и хочется чёткости и надёжности

Коротко:
- Утиная типизация — поведение важнее наследования
- Гусиная типизация — поведение + явная декларация через ABC
- Поддерживается isinstance(), issubclass() и статическими анализаторами

В Python можно писать и гибко, и строго — выбор за тобой.

Понимание обеих моделей делает твой код читаемым, надёжным и масштабируемым.

В глоссарии Python есть статья посвященная абстрактным базовым классам.

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩80👍5🔥4
Статическая утиная типизация — когда нужно понять, что это утка, ещё до запуска.

Мы уже с вами узнали:
• Утиная типизация — “если выглядит как утка и крякает как утка — это утка”
• Гусиная типизация — “эта утка официально записана в реестре как утка” (через ABC)

Теперь познакомимся с третьим подходом — статической утиной типизацией через Protocol.

Что это такое
Protocol из модуля typing позволяет описать интерфейс по ожидаемому поведению — без наследования.
Если у объекта есть нужные методы — он считается совместимым.

from typing import Protocol

class Writer(Protocol):
def write(self, data: str) -> None: ...

class FileWriter:
def write(self, data: str) -> None:
print(f"Пишу: {data}")

def save(w: Writer, msg: str):
w.write(msg)

save(FileWriter(), "Привет!")


Обрати внимание: FileWriter не наследует Writer, но типовые анализаторы (mypy, pyright) поймут — всё ок.
Потому что поведение совпадает.


Зачем это нужно
• Статическая проверка интерфейсов до запуска
• Без isinstance() и жёсткой иерархии
• Отлично подходит для тестов, моков
• Совместим с mypy, Pyright, Pylance и другими инструментами
• С полной свободой: хочешь — наследуй, хочешь — просто реализуй нужные методы


Утиная типизация была про “смотрим, что умеет объект”.
Статическая утиная — про “давайте это ещё и проверим заранее”.

✔️ Коротко:
• Protocol — это интерфейс без наследования
• Работает по принципу “если поведение совпадает — значит, подходит”
• Используется для статической проверки типов
• Совместим с mypy, Pyright и другими анализаторами

Можем ли мы проверить, что утка это утка используя протокол в рантайме?
Да например так:
from typing import Protocol, runtime_checkable

@runtime_checkable
class Writer(Protocol):
def write(self, data: str) -> None: ...

class FileWriter:
def write(self, data: str) -> None:
print("Пишу:", data)

fw = FileWriter()

print(isinstance(fw, Writer)) # True


🧠 Статическая утиная типизация помогает писать гибкий, но при этом безопасный код.
Это некий баланс между свободой и контролем.


Более подробно про протоколы можно почитать тут.

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩573👍2
Впереди выходные, почему бы не уделить это время тюнингу своего гитхаб аккаунта)

💻 Как оформить GitHub-профиль, чтобы он работал на вас.

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

🔹 Привлечь внимание рекрутеров и заказчиков
🔹 Выделиться среди других кандидатов
🔹 Показывает, что вы заботитесь о деталях и уважаете своих коллег по цеху
🔹 Да и в целом даже самому приятно смотреть на красивый профиль.

📌 Что можно сделать:
– Создать README для профиля с краткой информацией о себе
– Выделить ключевые проекты и красиво их оформить
– Добавить бейджи, статистику и немного стиля
– Подчеркнуть свою активность, навыки и интересы

Сделать это довольно просто, достаточно просто создать репозиторий с названием своего GH профиля и положить туда README.

👀 Нашёл пару отличных гайдов, которые помогут навести порядок и сделать профиль действительно заметным:

📄 Как информативно оформить профиль на GitHub?
📄 Оформляем README-файл профиля на GitHub

Но сильно не увлекайтесь, слишком много свистелок перделок тоже не есть хорошо))

Если давно хотели прокачать свой профиль, но откладывали — самое время ✌️
А если уже что-то сделали — кидайте ссылки, интересно посмотреть!

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩85🔥63
Статическая типизация в Python — когда уткам уже не доверяешь 🧊

Python — язык с динамической природой.
Но что, если хочется надёжности уже до запуска?

Добро пожаловать в мир статической типизации.
Без уток, без гусей — просто строгая проверка типов.

🧐 Что это вообще?

Статическая типизация — это когда ты явно указываешь типы переменных, аргументов и возвращаемых значений, а специальные инструменты (например, mypy) проверяют это до выполнения кода.
def greet(name: str) -> str:
return f"Привет, {name}"

greet("Питон") # Всё хорошо
greet(123) # mypy тут же даст ошибку

Python по-прежнему выполнит код, даже если ты передашь int, но анализатор заранее скажет: «что-то не так».

На этом примере особо не почувствуешь плюсов. Но если ты работаешь с большим количеством DTO, например pydantic модели, запросов и ответов или у тебя большой проект, когда ты не знаешь ожидаемых типов становится очень тяжело программировать. Среда разработки подсказывает хуже.
В общем сейчас я рекомендую всем по возможности проставлять аннотации.

📌 Как это работает?
• Используется синтаксис аннотаций (x: int, -> str)
• Проверка идёт снаружи, через инструменты (mypy, pyright, IDE)
• Ошибки ловятся ещё до запуска (в идеале — на этапе CI)

⚖️ Зачем это нужно?
• Уменьшить баги, так как python при запуске не выбрасывает ошибки при расхождении типов.
• Упростить навигацию по коду (IDE покажет сигнатуры, автокомплит и т.п.)
• Улучшить читаемость: ты сразу видишь, что принимает и возвращает функция
• Повысить доверие к чужому коду: «ничего не сломаю, если передам вот это»

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

🔥 Советы:
• Начинай с простого: добавляй типы в публичные функции
• Используй mypy — он легко интегрируется в проекты
• Не бойся писать Optional, Union, TypedDict, Literal — они реально спасают

✔️ Коротко:
• Python остаётся динамическим, но может быть типизированным
• Статическая типизация помогает ловить ошибки до запуска
• Ты не обязан, но ты можешь — и это делает код сильнее

🎯 Итог:
Утиная типизация даёт свободу.
Гусиная — структуру.
Статическая — уверенность.

А вместе они дают тебе гибкий, читаемый и защищённый код.

Про модуль typing и type hints можно почитать в официальной доке.

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩51👍2🔥21
🎓 Мою библиотеку выбрали для академического исследования в США

На днях мне написал Samuel Flint, исследователь из Университета Небраски–Линкольн (США), с предложением поучаствовать в их научной работе. Они с Dr. Robert Dyer изучают, как разработчики добавляют и убирают аннотации типов в динамических языках, вроде Python.

📌 В рамках исследования они отбирают репозитории, где используются или развиваются практики типизации, и… мой проект pbreflect попал в выборку.

Что именно за исследование?

Проект называется “Understanding Developers’ Addition and Removal of Type Annotations” (IRB#23988).
Они анализируют реальные изменения в open-source-проектах, чтобы понять, зачем и когда программисты используют type hints — и как это влияет на читаемость, сопровождение и качество кода.

Исследование одобрено этическим комитетом (IRB), бот TypeChangeBot будет отслеживать изменения, связанные с типами, и приглашать коммитеров поучаствовать в опросе. Подробнее: https://cse-rdyer-05.unl.edu/tcbot

Кто они такие?
• Dr. Robert Dyer — профессор Computer Science, автор десятков статей по empirical software engineering, участник топовых конференций вроде ICSE и MSR.
Примеры:
• Understanding Kotlin Type Usage
• How developers use Python type annotations
• Samuel Flint — его аспирант и соавтор, активно занимается разработкой tooling-а для анализа кода на Python и Kotlin.

Почему мне это приятно?

Во-первых, моя библиотека попала в поле зрения международных исследователей — а значит, там есть что-то интересное с точки зрения инженерии.
Во-вторых, такие штуки — хороший сигнал: когда твой код достаточно читаем, открыт и “type-aware”, чтобы его использовать в научной работе.

Ну и, если честно, просто круто, что твой проект не просто валяется на GitHub, а живёт своей жизнью и попадает в научные pdf’ки 😄

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
💩77🔥577👍4🆒2
This media is not supported in your browser
VIEW IN TELEGRAM
Сегодня тестировал библиотеку одного из моих учеников @AndreiDudin с курса Professional.

Записал видео - инструмент автоматизирует настройку линтеров, прекоммит-хуков, генерацию проекта и клиентов к сервисам.

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

Проект позволяет автоматизировать ту самую часть которая занимает самую большую часть времени.
И выполняет те вещи, которые обычно приходится делать вручную:

Ставит линтеры и настраивает их по единому стандарту

Настраивает прекоммит-хуки (чтобы не было “залетело в мастер без форматирования”)

Генерирует проектную структуру и клиентов для общения между сервисами

Это уже не просто «учебный проект», это прорыв, ближе к SDET и разработке тулов.

@AndreiDudin один из тех кто пинал меня с этой ступенью и приобрел курс еще до официального старта.
За что ему спасибо.

Горжусь и надеюсь, что это только начало — дальше будет ещё круче 💪

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩87🔥28
В эти выходные у меня первый выпускник с курса Professional 🥳
Естественно, я радуюсь, как и любой преподаватель)

отзыв на курс по API Professional
Необычный курс. На нем вы не будете писать автотесты) Курс немного про другое: как выстраивать фреймворк, в котором потом будут писаться тесты . И упростить/ускорить развертывание фреймворка с нуля и его интеграцию в CI

Архитектура, полезные либы, линтеры, форматтеры, генераторы кода и подобные вещи. То, что полезно, но приходится собирать из разных мест.

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

Курс рекомендую, очень полезен 👍

Отзыв

Что важно отметить, в курсе действительно собрано очень большое количество информации.

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

Один раз напилив инструмент, мы забываем про проблемы:

- Стандартизации структуры проекта (мы генерируем структуру пакетов проекта)

- Поддержки API клиентов в актуальном состоянии (мы генерируем клиенты и встраиваем их в фреймворк)

- Настройки пайплайнов (мы пишем common pipeline и интегрируем его в шаблоны проекта)

- Написания smoke тестов (мы генерируем код автотестоа)

- Поддержка качества кода (мы настраиваем линтеры, пайплайн и прекоммит хуки)

и многое другое.

Ну, а что касается проблем винды они решаемы, ведь я всегда на связи) ✔️

Я уже открыл запись на следующий поток, который стартует 4 августа.
Хотите не просто писать автотесты, а разрабатывать инструменты, перейти на другой уровень профессионализма, сэкономить часы а может даже и недели времени на разработку автотестов себе или вашей компании жду на тренинге)

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

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩73👍92
This media is not supported in your browser
VIEW IN TELEGRAM
Последнее время моей любимой соцсетью стал LinkedIn.

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

Куча постов в стиле: из-за нейросетей нас всех уволят.
Потом такая же куча постов: да нихрена эти нейросети без человека не могут.

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

Примерно такая же ситуация была, когда я вкатывался в IT, в 2018 году. Я начал вести аккаунт про тестирование в запрещенной социальной сети, у меня в подписчиках было три калеки. Я понял, что нельзяграм - это место еды, жоп, сисек и красивой жизни.

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

Сейчас я всё больше думаю о том, как делать контент, который не только интересен, но и полезен. Хочется писать что-то сложное, чтобы и самому развиваться, и другим помогать. Без хайповых заголовков, без "холиваров ради охватов", а с акцентом на реальную инженерию и глубокие технические темы.

Я могу назвать только двух человек, которые себе не изменяют и за которыми слежу очень давно - это Надя и Артем. И один аккаунт, который мне очень нравится, можно сказать, даже немного завидую - это Егор Векслер (его можете очень просто найти). У него и классная подача, и отменный юмор.

А что касается моего контента - он не про то, как "в два клика сделать какую-нибудь херню нейросеткой", а про техническое погружение в некоторых случаях даже фундаментальные вещи про которые все чаще забывают. У меня довольно сухая информация и если вы здесь я рад, что вам интересны темы, связанные с инженерией, тестированием, автоматизацией, и техническими подходами. Возможно, именно такие люди и помогут мне вернуть веру в ценность технического контента и профессионального комьюнити))

И да, что думаете насчет дублирования контента в разные соцсети? Стоит ли пробовать технические посты в нельзяграм и линк или это совсем не туда?

Ну и поделись, ссылонькой на канал если среди знакомых есть кто пришел в IT не только чтобы зарабатывать 300К\наносек "генерируя код нейросеткой", но и потому что ему реально интересно развиваться в IT-шке.

Ну или может просто причина в том, что я пишу неинтересное говно))

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩56👍126
Как вы помните, ранее я проводил опрос о том, какая тема автоматизации тестирования вам была бы интересна.

Ну так вот, вы просили — брокеры сообщений, значит, будут брокеры сообщений!

Кодовая база уже написана, презентации готовы на 40%.

Что будет интересного? Мы будем работать с Kafka и RabbitMQ.

Курс будет независим от ступеней Professional и Advanced, это значит, что он будет максимально емким: никаких Allure, настроек CI и прочего — только брокеры сообщений.

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

Поэтому рекомендую подтянуть навыки в Python и готовиться к новой ступени!

Курс будет помечен маркировкой Professional, потому что темы сложные.

В конце мы напишем интеграционный сценарий проверки flow регистрации, почти со всеми промежуточными этапами. Flow можно будет посмотреть на этой UML-диаграмме.

В общем, готовьтесь будет интересно!

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
💩72🔥12👍3
Ложное качество кода

Сейчас многие начали слишком сильно полагаться на нейросети.
Я стал замечать это даже по работам своих студентов.

Сегодня можно просто попросить ИИ:
Сделай мне проект — и он сгенерирует структуру, классы, папочки, комментарии.
На вид — реально как магия. Почти имба.

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

Например, у меня есть библиотека, о которой я уже упоминал — restcodegen.
Даже если подробно расписать промт, ИИ начинает генерировать лавину кода —
и в какой-то момент даже я уже не понимаю, что и зачем там сделано. Класс на 500-600 строк может разбить на 3-4 файла где в каждом по 500-600 строк!!!

Иногда нейросеть скатывается в оверинжиниринг:
- Создаёт десятки протоколов и абстрактных классов
- Распиливает методы до супер-атомарного состояния
- Пишет публичный метод, который вызывает точно такой же приватный — и ты сидишь и думаешь: зачем?

Для кого-то это может выглядеть как «код сеньора».
Но по факту — это просто усложнение ради усложнения.

Настоящий сеньор знает, когда использовать интерфейсы и паттерны, а когда — просто обычную функцию.

Тем не менее, ИИ — это очень мощный инструмент.
Игнорировать его в 2025 — всё равно что отвергать IDE и писать в блокноте.
Но, как и с любой мощной штукой, важно уметь правильно применять.

Мои рекомендации по использованию ИИ в разработке:
Решайте задачи атомарно.
Каждый шаг — с фиксацией в git.
Если пустить нейросеть в код без контроля — она может перелопатить всё, и предыдущие промты окажутся бесполезны.

Формулируйте чёткую задачу.
Опишите:
— в чём проблема
— какой способ решения вам ближе
— что должно быть на входе и выходе

Задавайте сигнатуры и контракты.
Чем яснее ожидания — тем точнее результат.
Описывайте, какие типы, поля, методы хотите видеть.

Показывайте примеры и паттерны, которые хотите использовать.
ИИ очень хорошо работает по аналогии — покажите, что вам нравится, и он постарается повторить стиль.

ИИ — это очень крутой помощник, который позволяет делать многое, не заглядывая лишний раз в документацию.

Но он не заменяет понимание!!!

Он усиливает тех, кто и так понимает, что делает.

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Про Kafka я уже писал.

Давайте теперь поговорим про RabbitMQ 🐰

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

Основные понятия, которые нужно знать:
Publisher — публикует сообщения в Rabbit.
Если сравнивать с Kafka — это producer. То есть сущность, которая шлёт сообщения в обменник.

Exchange — обменник.
Это точка входа всех сообщений в RabbitMQ.
Publisher публикует в exchange, а он уже раскидывает сообщения по очередям с помощью routing_key.

Binding — связь между exchange и queue.
Через неё мы указываем: какая очередь получает какие сообщения от какого обменника.

Queue — очередь.
Здесь лежат сообщения, которые ждут обработки.

Message — сообщение. Атомарная единица данных.
Consumer — подписывается на очередь и получает сообщения от Rabbit.


Что важно помнить при тестировании

Когда сообщение обработано (т.е. закоммичено), оно пропадает из очереди.
И если вы тестируете прямо на боевой очереди, есть риск:

• либо “украсть” сообщение у продового консюмера (если закоммитите его раньше)
• либо просто не увидеть его, потому что прод его уже съел

Что делать ✔️

Создаём свою тестовую очередь и роутим в неё те же сообщения, что и в боевую.
Так можно тестировать спокойно, не мешая логике основного приложения.

Об этом я подробно расскажу на курсе.

Что ещё важно знать

Типы обменников.
Но это — в следующем посте 😉

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Привет!
Дошло время поговорить про типы обменников (Exchange) в RabbitMQ 🐰

Зачем вообще это нужно знать?

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

Cначала надо рассказать про такое понятие как Routing Key.
В RabbitMQ - это строка, которая используется для маршрутизации сообщений от обменника (exchange) к очередям (queues) на основе правил, заданных типом обменника и настройками binding.

Простыми словами:
- Это как "адрес" или "тег" сообщения, который помогает обменнику решить, в какую очередь его отправить.
- Работает в связке с binding (привязкой очереди к обменнику), где указывается, какие routing key очередь принимает.

Теперь можно и про обменики.

1. Fanout
Публикует сообщения во все очереди, которые связаны с этим обменником через binding.
Игнорирует любые настройки binding (routing key или заголовки).
Все очереди получат одно и то же сообщение — никаких фильтров.

2. Direct
Публикует сообщения только в те очереди, у которых routing key в binding полностью совпадает с routing key сообщения.
То есть тут уже появляются строгие правила фильтрации.

3. Topic
Похож на Direct, но поддерживает wildcard’ы * и # в routing key.

Примеры:
• # — означает «все сообщения», фактически как в Fanout.
• *.created — сообщения, где routing key заканчивается на .created.

Это что-то типа простых регулярных выражений для фильтрации сообщений.

4. Headers
Тут вообще не используется routing key.
Роутинг идёт по заголовкам сообщений и правилам в binding.

В binding настраиваются:
• ожидаемые заголовки
• параметр x-match:
• x-match=any — хотя бы один заголовок должен совпасть
• x-match=all — должны совпасть все заголовки


В общем, это важно:
- чтобы настроить себе тестовую очередь и не своровать сообщения у прода
- или если просто хотите «послушать» сообщения из какого-нибудь топика

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
1
This media is not supported in your browser
VIEW IN TELEGRAM
Довольно часто можно услышать, что код автотестов должен быть простым, как молоток.
Несмотря на то, что язык — это всего лишь инструмент, который помогает ускорить работу тестировщика, и вроде бы можно написать что-то из говна и палок «лишь бы работало», всё-таки лучше думать немного наперёд.

Сейчас, работая в платформенной команде, я вижу много кода: приходят ML, разработчики и тестировщики. И да — они пишут рабочий код, но встречаются такие простыни и лапша, в которой тяжело разобраться.

При этом есть две крайности:
Одни скатываются в оверинжиниринг, другие, наоборот, пишут слишком просто.
В обоих случаях код потом сложно поддерживать.

Пара рекомендаций. Мы с вами уже смотрели принципы SOLID, и их нужно применять при написании автотестов. Потому что код тестов — это такой же промышленный код, только для другой области, и он должен быть максимально качественным.

1. Не лепите всё в один класс.
Техническая часть для отправки запросов должна быть отдельно, API-клиенты — отдельно, классы-помощники делите по бизнес-доменам.
Это позволит меньше лезть в техническую реализацию, а разделение по доменам поможет легче ориентироваться в коде.

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

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

4. Держите в голове вопрос: «А что будет, если изменится бэкенд?»
Сможете ли вы без боли пересадить ваш фреймворк на новый движок?

5. Опишите правила поддержки фреймворка.
Что и где писать, где хранить — единые правила помогают держать код в чистоте.
Если подход один, то и автоматизировать конвертацию методов или функций потом проще.

6. ЕЩЕ РАЗ! Используйте внедрение зависимостей! НЕ ДЕЛАЙТЕ ИНСТАНСЫ нужных классов в коде без острой необходимости, это очень тяжело потом рефачить и тестировать. Используйте фикстуры, это сделает код более прозрачным и понятным.

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

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

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Лонгрид.

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

Представьте, что вы пишете автотесты, и любой клиент, который вам нужен, можно получить, просто проставив декоратор.

Например:
@nuke_test
async def test_something(client: MyClient):
await client.do_something()

То есть вам даже не нужно писать фикстуру, вы можете сделать любой класс-хелпер.
Просто поставить аннотацию, и он будет работать, не надо никаких инстансов — всё работает.

Даже если ваш клиент имеет кучу зависимостей типа:
class MyClient(Client):
api1: Api1
api2: Api2
api3: Api3
...
apiN: ApiN

Вам эти зависимости не нужно передавать — тест будет работать так же просто, как в первом примере.

Потому что у нашей платформы написан свой DI и определённый механизм, который скрыто для пользователя создаёт все зависимости.

Круто? Очень круто.

Удобно? Безумно удобно, интерфейс предельно простой.

Работает ли это на практике?

Не у всех. Почему? Потому что огромные ошибки проектирования тестов, оверинжиниринг, наследование не там, где нужно, нарушение принципов программирования.

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

Например:
from lib import clients

@dataclass
class BaseOrder:
id: int

class Order(BaseOrder):
@staticmethod
def do_something():
clients.do_something()

def test_order():
Order(id=1).do_something()

Что здесь не так?
1. Нарушение принципа SRP (Single Responsibility Principle)

Почему это плохо:
• Order должен представлять бизнес-сущность заказа.
• Но он также знает о том, как вызывать внешние сервисы.
• Это два разных уровня ответственности.

А что если завтра clients.do_something() изменит сигнатуру? Потребует аутентификацию? Появится новый клиент? Вам придётся менять модель Order.

Что хорошего?
Код простой — да. Но он не расширяемый. Попробуйте написать тест с моком или заменить clients на другую реализацию.

2. Нарушение принципа DIP (Dependency Inversion Principle)
from lib import clients — жёсткая зависимость

Почему это плохо:
• Order зависит от конкретной реализации, а не от абстракции.
• Невозможно заменить clients на другую реализацию без изменения Order.
• Нарушается принцип «зависеть от абстракций, а не от конкретики».

А что если понадобится другой clients для тестов?
А если clients переедет в другой модуль?
А если нужно будет добавить логирование или метрики вокруг вызовов?

3. Сильная связность

Почему это плохо:
• Order не может существовать без clients.
• clients нельзя заменить или замокать.
• Тестирование возможно только с реальным clients.

Если clients падает, падают все тесты Order.
Сложно тестировать логику Order изолированно.

4. Использование глобальной переменной, которая хранит все объекты.

Почему это плохо:
• Глобальное состояние может изменяться между тестами.
• Сложно контролировать состояние clients.
• Побочные эффекты между тестами.

Теперь представим, что мы хотим использовать наш подход с декоратором или фикстурой — и не можем.
Нам придётся явно передавать зависимости в каждый инстанс Order, что для тысячи тестов очень тяжело. У нас куча входных точек в каждом тесте.

Захотим немного поменять clients — есть вероятность разломать кучу тестов, потому что они ультра сильно связаны.

Как я считаю, можно было бы сделать правильно:

Сделать OrderHelper:
class OrderHelper:
def __init__(self, client):
self.client = client

def make_order(self, id):
self.client.do_something()

Тем самым мы получаем только ту зависимость, которая нам нужна, и не тащим за собой весь скоуп.

Продолжение следует...
1🔥1
Преимущества:
1. SRP соблюдён — OrderHelper занимается только логикой работы с заказами.
2. DIP соблюдён — зависит от переданного client, а не от конкретной реализации.
3. Слабая связанность — можно подставить любой client.
4. Тестируемость — легко мокать client.

Даже если хочется сделать общий фасад, можно так:
class Facade:
def __init__(self, db, http, grpc):
self.db = db
self.http = http
self.grpc = grpc

class Order:
def __init__(self, facade: Facade):
self.facade = facade

1. Единая точка входа — все зависимости в одном месте.
2. Легко мокать — можно подменить хоть весь facade.
3. Гибкость — можно менять реализацию facade.
4. Контроль — чётко видно, что нужно Order.

Возможно, мой код сложнее.
• Сложнее локально, но проще глобально.
• Попробуйте написать 10 разных тестов для каждого подхода.
• Попробуйте заменить clients на другую реализацию.


Зачем усложнять простую задачу?

Потому, что простая задача завтра станет сложной:
• Добавится логирование.
• Появятся ретраи.
• Метрики.
• Кеширование.
• Новый клиент.


По итогу, что мы имеем:
1. Масштабируемость — подход работает для 1000+ тестов.
2. Поддерживаемость — легко изменять и расширять.
3. Тестируемость — можно тестировать любые сценарии.
4. Переносимость — легко адаптировать под разные фреймворки, менять бэкэнд.
5. Отладка — чётко видно, что происходит, где входная точка и т.д.

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

——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
AQA Engineer | Сообщество инженеров по автоматизации тестирования на Python
Отзыв на курс REST API test automation (Professional) Замечательный курс от Валерия, как логичное продолжение REST API test automation (Advanced) в котором раскрываются лучшие AQA практики с уколном в SDET, с объяснением выбранных подходов (существующих…
Вот и закончился второй поток курса professional.

За это время было пройдено много материала.
Самое крутое, что студент, сразу внедрял полученную информацию у себя на проекте и это круто.

Для него больше нет магии в том как генерировать фреймворки и на одного крутого спеца стало больше.

Так что могу тоже смело рекомендовать человека, если вам нужен крутой инженер)


——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
Всем привет)

У меня пара новостей.

Я снова включил реакции)))

Временно их отключал потому, что нашелся какой-то популярный "засранец" 🤣, который попросил "загавнякать" мне все посты, ну или натравил ботов)

По-итогу пришлось включить немного тоталитаризма и реакции сначала закрыть, теперь я их снова включил, но количество подсократил)

Вторая новость:
Хочу попробовать новый формат публикации постов с кодом.
Делать скринами, чтобы было легче читать с телефона.

Ставьте - 🔥 если понравилось читать скринами.
И ставьте - 👍 если публиковать код текстом.

Ниже продублирую как бы смотрелся пост с текстом, чтобы вы понимали как удобнее.
——————————-

📱 TG-сообщество

📱 Обучение

📱 Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥15🤯2