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 511
مشترکین
-124 ساعت
+57 روز
+830 روز
آرشیو پست ها
Привет, друзья! Вчера на вебинаре прошли весь путь – от базовых вещей до архитектуры полноценного фреймворка. Написали достат
Привет, друзья! Вчера на вебинаре прошли весь путь – от базовых вещей до архитектуры полноценного фреймворка. Написали достаточно кода, чтобы понять, как выглядит по-настоящему сильное решение. Я не люблю воду на вебинарах, поэтому сделал его максимально прикладным и техническим – только практика, только хардкор. Что выяснили: - На написание одного хорошего автотеста (с учетом опыта) уходит ~1,5 часа - Но это без учета сопровождения – а там могут быть бесконечные правки и доработки - С правильными инструментами тот же тест пишется за 5 минут (да, в 18 раз быстрее!) 90 минут против 5 – и это без учета времени на настройку линтеров, CI/CD и прочей инфраструктуры. Это не просто экономия времени – это возможность: ✅ Развиваться вместо бесконечного фикса багов ✅ Делать сложные задачи легко ✅ Стать настоящим Senior’ом, а не просто "поставить галочку" в резюме Пока другие крутят "опыт" и продают вымышленные успехи, вы сможете: 🔹 Писать чисто, быстро и профессионально 🔹 Работать с реальной технической базой (а не поверхностными знаниями) 🔹 Сократить не только свои трудозатраты, но и бюджет компании Мои тренинги я считаю лучшими на рынке – и это не просто слова. Многие студенты после них растут в 2-3 раза быстрее коллег. Хочешь так же? Присоединяйся – научу! Старт уже в понедельник 7 апреля! А если пропустил вебинар – обязательно посмотри запись, пока она доступна. Это сильный рывок даже для тех, кто уже в теме. P.S. Разница в 18 раз – это не магия. Это знание того, как делать правильно. Если хочешь таких же результатов – пиши, расскажу подробнее. 💪 Описание всех тренингов можно найти тут

Как развернуть автоматизацию тестирования API за неделю? Уже завтра стартует вебинар "ОТ ТЕСТОВ К ИНСТРУМЕНТАМ"! 🚀 📅 Когда:
Как развернуть автоматизацию тестирования API за неделю? Уже завтра стартует вебинар "ОТ ТЕСТОВ К ИНСТРУМЕНТАМ"! 🚀 📅 Когда: 03.04.2025 20:00 - 22:00 📍 Куда вступать: группа Плюс будет маленький бонус тем, кто досидит до конца! 👀 Поэтому, если ты еще не вступил в группу, советую это сделать. А пока расскажу, как моя жена развернула автоматизацию на проекте за неделю. У нас семья айтишников, и было бы глупо полагать, что она не имеет свободного доступа к моим курсам. Я не люблю помогать))) Это высказывание не совсем вяжется с тем, что происходит на самом деле. Моя телега обычно трещит от вопросов, и я всегда отвечаю. Просто я не люблю быть чатом GPT и просто говорить, как тут сделать. Я всегда вместо "рыбы" пытаюсь дать "удочку". Почему? Да потому, что я очень ленив. Мне проще один раз научить человека, чем он будет приходить миллион раз с типовыми вопросами. Примерно так же было, когда с таким же запросом ко мне пришла моя жена. Как мне развернуть автоматизацию у себя на проекте? Я сказал: "Вот курс — смотри." Наверное, можно было сесть, все показать и рассказать, но зачем, если я уже снял видео? )) Для нее это был жуткий марафон. С утра до ночи она сидела и все пробовала. И вот спустя неделю у нее уже работает pipeline, прикручен Allure, логи, степы, уведомления о прохождении сыпятся в телегу, и при падении могут тэгать нужных людей. Как вы думаете, это быстро, учитывая, что человек до этого ни разу не писал код? 🤔 ЭТО ПИЗДЕЦ КАК БЫСТРО! 💥 А схема получилась проста: большую часть времени занимает написание клиентов, поэтому она их просто генерирует, а дальше заполнение сценария не сложнее, чем выполнять то же самое в Swagger или Postman. Получился такой флоу: генерирует клиент -> делает фикстуру -> пишет тест. К концу второй недели она уже покрыла 90% сервиса смоками88 автотестов, и это не статус-код 200, а реальные бизнесовые проверки с хождением по разным сервисам. Есть ли тут подвох? Да, есть. Эти инструменты я даю только на ступени professional. Можно будет остановиться только на их использовании, и это уже ооооочень сильно сократит время. Но главная фишка этого обучения не в этом, а в том, что я буду давать именно удочку. Мы сами научимся писать генераторы кода, чтобы вы могли писать свой кастом под свой проект или дорабатывать инструмент при переходе на другой проект. Вчера я тестировал инструмент, который будет итогом обучения professional, и это очень круто! 😍 Я думаю, вам понравится тоже. Об этом и многом другом мы поговорим уже завтра. А пока ступай в группу вебинара, если этого еще не сделал! 😊

Принцип YAGNI (You Ain’t Gonna Need It) — «Тебе это не понадобится» Часто на картинках с DRY и KISS мелькает еще один важный
Принцип YAGNI (You Ain’t Gonna Need It) — «Тебе это не понадобится» Часто на картинках с DRY и KISS мелькает еще один важный принцип — YAGNI. Он гласит: не добавляй функциональность, которая может понадобиться в будущем, но не нужна прямо сейчас. Основные идеи YAGNI: 1️⃣ Не реализуй то, что не требуется сейчас — если нет конкретного ТЗ, не пиши код «на всякий случай». 2️⃣ Избегай ненужной сложности — лишний код усложняет поддержку и тестирование. 3️⃣ Оптимизируй только при необходимости — преждевременная оптимизация может навредить. 4️⃣ Экономи время и ресурсы — меньше лишнего кода = чище и понятнее архитектура. Примеры нарушения YAGNI: - Абстрактная архитектура «на будущее», которая никогда не пригодится. - Параметры в функции, которые пока не используются. - Сложная система логирования для одноразового скрипта. Хороший принцип… но я его нарушаю в автотестах😅 Вот как и почему: 🔹 Генерация клиентов Если писать клиенты вручную, логично описать только нужный контроллер для нужного API сервиса. Но я давно использую сгенерированные клиенты — и если генерировать, то все сразу. 🔹 Версии API (V1, V2, OLD и т. д.) Контроллеры в разных версиях API могут называться одинаково, и появляются фикстуры вроде old_controller_api, v2_controller_api и т. п. Проще сразу сделать фасад, который объединит API (контроллеры) одного сервиса, где через точку можно доставать нужный, вместо того чтобы путаться в версиях контроллеров. 🔹 Обёртки над методами Контракты меняются, и если не подготовиться, придётся переписывать все тесты, а не один метод-абстракцию. Поэтому я довольно часто добавляю еще один класс, в виде наследника от API клиента, в котором упрощаю интерфейс тестируемого метода. Да, это усложняет проект, но зато даёт архитектуру, которую легко поддерживать годами. А если все это генерировать это вовсе сводит трудозатраты к минимуму, задавая чёткие рамки проекта. Вывод: YAGNI — хорошее правило, но иногда его можно нарушать осознанно. Главное — понимать, зачем. ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

В посте выше в комментариях верное отметили, что говоря про DRY, нужно не забывать про KISS. Принцип KISS (Keep It Simple, St
В посте выше в комментариях верное отметили, что говоря про DRY, нужно не забывать про KISS. Принцип KISS (Keep It Simple, Stupid) — один из ключевых в разработке. Его суть проста: чем проще ваш код, тем легче его поддерживать, масштабировать и понимать (вам и другим разработчикам). Почему KISS важен? 1️⃣  Меньше багов — сложный код = больше ошибок. 2️⃣ Лучше читаемость — коллеги (и будущий вы) скажут спасибо. 3️⃣ Быстрее разработка — не нужно изобретать велосипед. Я точно знаю, что есть проекты написанные мной еще 4 года назад, которые работают и поддерживаются по сей день. Все потому, что были написаны очень просто и понятно, как молоток. Как применять KISS? ✔️ Дробите задачи — одна функция = одна ответственность. ✔️ Избегайте "умного" кода — если решение требует сложных объяснений, возможно, есть вариант проще. ✔️ Рефакторите — если код стал запутанным, упрощайте без жалости. ✔️ Используйте проверенные паттерны — но не усложняйте там, где можно без них.
"Совершенство достигнуто не тогда, когда нечего добавить, а когда нечего убрать."
Ваш код должен решать задачу, а не демонстрировать интеллект. Старайтесь писать проще! ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

✨ Принцип DRY (Don't Repeat Yourself) Это один из основных принципов программирования, который утверждает, что "не следует по
Принцип DRY (Don't Repeat Yourself) Это один из основных принципов программирования, который утверждает, что "не следует повторять себя". Он призывает избегать дублирования кода и данных, что помогает упростить проектирование, повысить качество кода и снизить вероятность ошибок. Основные идеи DRY: 1️⃣ Устранение дублирования Если код или логика повторяются — выноси их в отдельный модуль, функцию или класс. Так любые изменения потребуют правки только в одном месте. 2️⃣ Упрощение поддержки Меньше дублирования → проще тестировать и обновлять код. Никаких "а не забыл ли я поправить это в другом файле?" 3️⃣ Улучшение читаемости Чистый и структурированный код легче понимать и поддерживать. 💡 Как применять DRY? Используй функции, классы, библиотеки и паттерны проектирования, чтобы избежать повторений. 🎯 Как мы применяем DRY с учениками? ✔️ Логгирующий клиент — один класс для всех логов, а не копипаста в каждом тесте 📋. ✔️ Хелперы и врапперы  — позволяет зашить логику проверок, разметки и другие полезные действия в одном месте, тем самым появляется как бы "авторазметка" и "автопроверки", так как использование методов из классов уже содержит все необходимое. ✔️ Декораторы  — позволяет добавлять новый функционал к уже существующим методам, всего одной строчкой. ✔️ Фасады — позволяют определить одну входную точку в нужный клиент, вместо написания большого количества очень похожих фикстур. ✔️ Используем наследование и другие возможности языка, для уменьшения дублирования кода. Использование этих подходов позволяет здорово улучшить поддерживаемость, стабильность и чистоту кода нашего фреймворка. ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

🚀 От тестов к инструментам: как сеньеры создают фреймворки за пару кликов Привет, коллега! 👋 Если ты хоть раз задумывался,
🚀 От тестов к инструментам: как сеньеры создают фреймворки за пару кликов Привет, коллега! 👋 Если ты хоть раз задумывался, почему одни пишут тесты часами, а другие — за пару минут, то этот вебинар для тебя! Я расскажу: ✅ Как джуны, мидлы и сеньеры подходят к автоматизации — и почему это выглядит как "слоумо" vs "вау, как он это сделал?". ✅ Как сеньеры создают целые фреймворки в пару кликов, пока остальные пишут сотни строк кода? ✅ Как перейти от написания тестов к созданию инструментов, которые делают всю работу за тебя? 💡 Секретный ингредиент: Я покажу, как с помощью одного инструмента можно генерировать целые фреймворки автотестирования, которые экономят часы, дни и даже недели работы. Минимум воды максимум пользы, мы будем заниматься лайфкодингом. 📅 Дата и время вебинара: 03.04.2025, 20-00 по МСК 📍 Где: В этой группе (обязательно подпишись, чтобы не пропустить!) 👉 Почему стоит присоединиться? - Новичок? Узнаешь подходы к автоматизации и построению фреймворка. - Имеешь опыт? Узнаешь, как выйти на новый уровень в автоматизации. - Поймешь, как писать не просто тесты, а инструменты, которые делают тебя незаменимым. - Получишь эксклюзивный анонс моего нового курса PROFESSIONAL, где я научу тебя не только писать тесты, но и создавать инструменты автоматизации. 🔥 Вау-эффект гарантирован! Не упусти шанс узнать, как сделать свою работу проще, быстрее и круче. 👇 Что делать сейчас? 1. Подпишись на эту группу . И этот канал. 2. Расскажи друзьям — пусть тоже прокачают свои навыки. 3. Жди анонса вебинара и готовь вопросы! Ссылка на группу: Webinar: От тестов к инструментам Ну и немного обо мне) Сейчас: старший разработчик - Python платформы OzonTech В прошлом: Ведущий инженер по автоматизации тестирования OzonTech Ну, и просто хороший человек) До встречи на вебинаре! 🚀

Стандартная метафора «переменные – это ящики» ведет к непониманию ссылочных переменных в объектно-ориентированных языках. Пер
Стандартная метафора «переменные – это ящики» ведет к непониманию ссылочных переменных в объектно-ориентированных языках. Переменные в Python похожи на ссылочные переменные, поэтому лучше представлять их как этикетки, приклеенные к объектам. Следующий пример поможет понять, почему.
>>> a = [1, 2, 3]
>>> b = a 
>>> a.append(4)
>>> b 
>>> [1, 2, 3, 4]
1. Создать список [1, 2, 3] и связать с ним переменную a 2. Связать переменную b с тем же значением, на которое ссылается a. 3. Изменить список, на который ссылается a, добавив в конец еще один элемент. 4. Можно наблюдать, как это отразилось на переменной b. 5. Если считать b ящиком, в котором хранилась копия списка [1, 2, 3] из ящика a, то такое поведение бессмысленно. Таким образом, предложение b = a не копирует содержимое ящика a в ящик b, а наклеивает метку b на объект, уже имеющий метку a. Для правильного понимания присваивания в Python всегда сначала читайте правую часть, ту, где объект создается или извлекается. Уже после этого переменная в левой части связывается с объектом – как приклеенная к нему этикетка. А о ящиках забудьте. Поскольку переменные – это просто этикетки, ничто не мешает наклеить на объект несколько этикеток. В этом случае образуются псевдонимы. Тем самым оператор is проверяет, что разные этикетки наклеены на один и тот же ящик. А оператор == проверяет, что разные ящики имеют одинаковое содержимое. ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

Чем отличается оператор "is" от оператора "==" ?
Anonymous voting

Ответ на задачу выше. 🔍 Проблема в том, что все экземпляры Bus, конструктору которых не был явно передан список пассажиров,
Ответ на задачу выше. 🔍 Проблема в том, что все экземпляры Bus, конструктору которых не был явно передан список пассажиров, разделяют один и тот же список по умолчанию. Это тонкая ошибка. Из примера видно, что когда объект Bus инициализируется списком пассажиров, он работает правильно. ✅ Странности начинаются, когда Bus вначале пуст, потому что в этом случае self.passengers оказывается псевдонимом значения по умолчанию для параметра passengers. Беда в том, что любое значение по умолчанию вычисляется в момент определения функции, т. е. обычно на этапе загрузки модуля, после чего значения по умолчанию становятся атрибутами объекта-функции. Так что если значение по умолчанию – изменяемый объект и вы его изменили, то изменение отразится и на всех последующих вызовах функции. ⚠️ Если после выполнения кода из примера проинспектировать объект Bus.__init__, то мы обнаружим имена в его атрибуте __defaults__:
dir(Bus.__init__)
# ['__annotations__', '__call__', ..., '__defaults__', ...]  


Bus.__init__.__defaults__
# (['Vasiliy', 'Julia'],)  
Наконец, можно убедиться, что bus2.passengers – псевдоним первого элемента атрибута:
Bus.__init__.__defaults__[0] is bus2.passengers  # True
Описанная проблема и есть причина того, почему для параметров, принимающих изменяемые значения, часто по умолчанию задается значение None. ❗️ Например:
class Bus:  
    def __init__(self, passengers=None):
        if passengers is None:
            # Создаем новый пустой список 
            self.passengers = []  
        else:
            # Связываем копию  
            self.passengers = list(passengers)  
В примере init проверяет, верно ли, что аргумент passengers совпадает с None, и, если это так, присваивает атрибуту self.passengers вновь созданный пустой список. Если passengers не совпадает с None, то правильное решение заключается в том, чтобы связать копию этого атрибута с self.passengers. Но при написании функции, принимающей изменяемый параметр, нужно тщательно обдумать, ожидает ли вызывающая сторона, что переданный аргумент может быть изменен. 🤔 ——————————- 📱 TG-сообщество 📱 Обучение 📱 Отзывы

Привет давайте еще одну задачку) Какой правильный ответ из скрина выше?
Anonymous voting

Что выведет интерпретатор, выбери правильный ответ?
Anonymous voting

def func(x, y=[]): y.append(y) return y print(func(1)) print(func(2)) Что выведет код?
Anonymous voting

Ребят спасибо большое, что забустили канал, даже не ожидал такой поддержки, это позволило чуть причесать канал, еще два голос
Ребят спасибо большое, что забустили канал, даже не ожидал такой поддержки, это позволило чуть причесать канал, еще два голоса и даже можно будет устанавливать свои собственные обои. Но не буду уж наглеть вы и так накинули очень много, еще раз спасибо большое. Ну а пока давайте поговорим, почему в срезы и диапазоны не включается последний элемент? Принятое в Python соглашение не включать последний элемент в срезы(slice) и диапазоны(range) соответствует индексации с нуля, принятой в Python, C и многих других языках. Приведем несколько полезных следствий из этого соглашения. - В математике и теории множеств удобно работать с индексами, начинающимися с нуля, так как это упрощает ссылки на позиции в последовательности. - Легко понять, какова длина среза или диапазона, если задана только конечная позиция: и range(3), и my_list[:3] содержат три элемента. -  Легко вычислить длину среза или диапазона, если заданы начальная и конечная позиции, достаточно вычислить их разность stop - start. -  Легко разбить последовательность на две непересекающиеся части по любому индексу x: нужно просто взять my_list[:x] и my_list[x:].
l = [10, 20, 30, 40, 50, 60]
l[:2] # [10, 20]
l[2:] # [30, 40, 50, 60]
Эти четыре пункта помогают лучше понять, почему в Python и многих других языках удобнее не включать последний элемент в срезы и диапазоны. Это соглашение делает работу с последовательностями более интуитивной и позволяет избежать множества потенциальных ошибок. TG-сообщество | Обучение | Отзывы

https://t.me/boost/AQA_Engineer Ребят проголосуйте за канал кому не впадлу)

Структуры данных - Множества В прошлых постах мы говорили о последовательностях , кортежах и очередях, их видах, словарях (di
Структуры данных - Множества В прошлых постах мы говорили о последовательностях , кортежах и очередях, их видах, словарях (dict) и их вариациях. Множества — это сравнительно недавнее добавление к Python, которое использует не так уж много разработчиков. Тип set и его неизменяемый вариант frozenset впервые появились в модуле в Python 2.3, а в Python 2.6 стали встроенными типами. 🔹 Что такое множество? Это набор уникальных объектов. Один из основных способов применения множеств — устранение дубликатов:
l = ['spam', 'spam', 'eggs', 'spam', 'bacon', 'eggs']
set(l)  # {'eggs', 'spam', 'bacon'}
Обратите внимание, что элементы множества должны быть хешируемыми. Сам тип set не является хешируемым, поэтому множества не могут быть вложенными. Однако frozenset хешируемый, и его объекты могут быть элементами set. 🔹 Операции с множествами Типы множеств предоставляют множество операций, включая инфиксные операции: - a | b — объединение - a & b — пересечение - a - b — разность Умелое использование этих операций позволяет существенно уменьшить как объем кода, так и время его выполнения, улучшая читаемость и понятность. 💡 Пример: У нас есть большой набор почтовых адресов (haystack) и меньший набор адресов (needles). Нам нужно подсчитать, сколько раз элементы needles встречаются в haystack. С помощью операции пересечения это делается одной строкой:
found = len(needles & haystack)
А без оператора пересечения пришлось бы написать так:
found = 0  
for n in needles:
    if n in haystack: 
        found += 1
🔹 Некоторые особенности множеств: Типы set и frozenset реализованы с помощью хеш-таблиц. Отсюда вытекает ряд следствий. - Элементы множества должны быть хешируемыми объектами. - Проверка на членство производится очень эффективно. Множество может содержать миллионы элементов, но для нахождения элемента нужно только вычислить его хеш-код и получить по нему смещение относительно начала хеш-таблицы; возможно, еще придется выполнить несколько попыток, чтобы добраться до нужного элемента или убедиться, что его не существует. - Множествам присущи большие накладные расходы на хранение в памяти по сравнению с низкоуровневым массивом указателей на элементы, что было бы компактнее, но резко замедлило бы поиск, если число элементов в множестве сколько-нибудь велико. - Порядок элементов зависит от порядка вставки, но опираться на эту зависимость не рекомендуется, т. к. это ненадежно. Если два элемента различны, но имеют одинаковый хеш-код, то их взаимное расположение зависит от того, какой элемент был добавлен первым. - Добавление элементов в множество может изменить порядок уже присутствующих в нем элементов. Это связано с тем, что эффективность алгоритма падает, когда хеш-таблица заполнена на две трети или более, поэтому Python приходится увеличивать размер таблицы по мере ее роста, что влечет за собой перемещение в памяти. Когда такое происходит, элементы вставляются заново, и их относительный порядок может измениться. TG-сообщество | Обучение | Отзывы

Дорогие девушки! С Международным женским днем вас! В этот прекрасный день хочется пожелать вам, чтобы ваша жизнь была такой же гладкой, как безошибочный сценарий тестирования, а задачи были решаемыми, как баги под капотом. Пусть ваша отладка будет не только в коде, но и в жизни! Пусть все ваши изысканные тест-кейсы завершаются без критических ошибок, а цель всегда будет достигнута — с первого прогона! Пусть каждое утро начинается с яркой идеи и чашечки бодрящего кофе, а каждый ваш день будет наполнен теплом и радостью, как идеальное пользовательское время! Желаю вам креативного подхода к решению задач и здоровья, чтобы справляться с любыми трудностями! Пусть вашей жизни будет столько же сладостей, сколько багов в коде, а улыбок — больше, чем нереализованных требований! С восьмым марта! Вы — лучшие! 💐