Валерий | AQA Engineer | Автотестирование на Python | REST, gRPC, GraphQL
Ir al canal en Telegram
Сделаю из тебя крутого AQA инженера на Python. • Преподаю лучшие тренинги по автоматизации тестирования API • Senior Python developer | AQA lead, 7 лет в IT
Mostrar más1 511
Suscriptores
-124 horas
+47 días
+830 días
Archivo de publicaciones
🌟 Учись у лучших и становись экспертом в автоматизации тестирования! 🌟
Ты уже имеешь опыт в тестировании, но чувствуешь, что не хватает знаний для уверенной работы с фреймворками и решениями? Хочешь прокачать свои навыки до уровня разработчика и научиться создавать автотесты для REST API?
Курс "Advanced" — это идеальное решение для тебя! 🎯
🔍 Что тебя ждет:
- Уникальное учебное приложение на основе микросервисов для практики интеграционных тестов
- Обучение ряду паттернов проектирования для эффективной автоматизации
- Углубление технической компетенции с акцентом на реальную разработку
- Умение находить и устранять неисправности веб-приложений
- Мощный, но простой инструмент для написания автотестов на Python
- Практика, практика и еще раз практика! Мы будем изучать только самое необходимое для достижения результатов.
💡 Специальное предложение! Только до 28 сентября у тебя есть возможность получить 15% скидку на курс по промокоду
ADVANCED28. Не упусти свой шанс стать настоящим мастером автоматизации!
🌐 Узнай все подробности и запишись на курс уже сейчас! Это твой шанс начать новую главу в карьере тестировщика! ⏳
🚀 Будь на шаг впереди — стань экспертом в автоматизации!
Старт обучения уже 7 октября.
Поэтому тем, кто подписан на канал и хочет получить скидку за свою скорость велкам.
https://it-wizard.pro/rest_api_advancedЧасть 3
Топики в Apache Kafka - это основной механизм организации и хранения потоковых данных.
Топик представляет собой категорию или канал, в который продюсеры публикуют сообщения и из которого консумеры эти сообщения читают.
1. Множество топиков: В Kafka можно создать и использовать множество топиков. Каждый топик может содержать любое количество сообщений.
2. Разделение данных: Каждый топик разделен на одну или несколько партиций. Партиция - это логическое упорядоченное хранилище сообщений внутри темы, и они служат единицей распределения и параллелизма внутри Kafka.
3. Репликация партиций: Каждая партиция может иметь несколько реплик, что обеспечивает отказоустойчивость и надежность сообщений. Реплики хранят данные в реальном времени и позволяют автоматически восстановиться в случае сбоев или отказов.
4. Ключи и значения сообщений: Каждое сообщение в Kafka состоит из ключа и значения. Ключ является опциональным и может использоваться для определения партиции, в которую будет записано сообщение. Значение сообщения содержит фактическую информацию и данные.
5. Ретенция данных: В Kafka можно настроить период хранения данных (retention period), в течение которого сообщения сохраняются в топике. Это позволяет создавать системы хранения данных с определенным временным окном и обеспечивает возможность воспроизведения и повторного чтения сообщений.
6. Гибкая масштабируемость: Топики в Kafka позволяют гибко масштабировать систему как по объему данных, так и по уровню производительности, позволяя добавлять и удалять партиции и реплики по мере необходимости.
Топики являются центральным элементом в архитектуре Kafka, предоставляя средства для организации и хранения потоковых данных. Они обеспечивают гибкость, масштабируемость и отказоустойчивость для обработки потоков данных в реальном времени.
Как у меня на работе используются топики?
Есть топик выдачи заказов назовем его giveout_topic.
В giveout_topic около 20 партиций, грубо говорят это значит, что выдача заказов может осуществляться параллельно в 20 потоков и есть консумер группа где каждый консумер в группе может слушать несколько партиций и производит выдачу по системе. Это позволяет отпустить клиента с заказом и в фоне накапливать очередь, тем самым в моменте снимая нагрузку с базы данных, в которой хранятся статусы заказов. Управляя количеством партиций можно так же снижать нагрузку на БД, уменьшая грубо говоря количество потоков. При изменении количества партиций происходит ребалансировка, но об этом в следующем посте.
Работа с Kafka в автотестах.
Часть 2.
В этом посте более подробно поговорим про продюсеры и консумеры.
1. Продюсеры:
- Продюсеры в Kafka отвечают за запись (публикацию) сообщений в топики Kafka.
- Они отправляют сообщения в топики, используя Kafka Producer API именно его используют сервисы для публикации сообщений.
- Продюсеры могут публиковать сообщения в один или несколько топиков.
- При публикации сообщения продюсер может указать ключ и значение сообщения.
- Также продюсеры могут выбирать, в какую партицию записывать сообщение, или позволить Kafka сделать это за них, используя ключ сообщения.
2. Консумеры:
- Консумеры являются компонентами, которые читают (подписываются на) сообщения из одного или нескольких топиков Kafka, это позволяет одни и те же сообщения использовать разными консумерами для разных целей, разными сервисами.
- Они используют Kafka Consumer API для чтения сообщений.
- Часто консумеры работают в группах, чтобы обрабатывать сообщения параллельно и добиться высокой пропускной способности.
- Каждый консумер, присоединяющийся к группе, получает подмножество партиций каждого топика, и каждая партиция обрабатывается только одним консумером внутри группы.
- У каждого топика может быть несколько консумер групп, например, у разных команд могут быть свои консумер группы для чтения сообщений в своих целях.
- Консумеры могут обрабатывать сообщения в реальном времени или сохранять их для будущей обработки.
3. Схемы ключей и значений сообщений:
- В Kafka каждое сообщение состоит из ключа и значения.
- Ключ сообщения опционален и используется для определения партиции, в которую будет записано сообщение.
- Ключи сообщений позволяют группировать и сортировать данные, а также обеспечивают определенное распределение нагрузки между партициями.
- Значение сообщения содержит основную информацию и данные.
4. Отложенная доставка и гарантии доставки:
- Kafka поддерживает отложенную доставку сообщений, что означает, что они сохраняются в буфере и отправляются позже.
- При записи сообщений Kafka может предложить несколько гарантий доставки: "at-least-once" и "exactly-once".
- Гарантия "at-least-once" гарантирует, что сообщение будет доставлено по крайней мере одному потребителю, но возможно дублирование сообщений.
- Гарантия "exactly-once" обеспечивает точность доставки сообщений без дублирования. Она включает двухфазный коммит для записи и подтверждения сообщений.
5. Управление потоками данных:
- Kafka также позволяет создавать кортежи и агрегировать потоки данных в потоковую обработку (stream processing).
- Это позволяет разделять и обрабатывать данные в реальном времени, применять функции, анализировать потоки событий и трансформировать данные.
Работа с Kafka в автотестах.
Часть 1.
Довольно часто ставится задача автоматизировать сценарий, где флоу предполагает отправку сообщений сервисами в топик, которые впоследствии обрабатываются какой-то джобой, а дальше данные из топика направляются либо в другой сервис, либо в базу данных, а иногда и туда, и туда.
Kafka позволяет организовать очередь, то есть создать пул сообщений, которые затем обрабатываются в несколько потоков. Представьте, что на госуслугах, когда вы оформляете, например, заграничный паспорт, вы собираете документы и отправляете их в топик. На месте вам выдают паспорт, вы уходите счастливым домой, а все непосредственное оформление и проводка по системам происходят уже в фоновом для вас режиме и не сильно вас волнуют.
Таким образом, довольно часто Kafka используется в таком контексте для улучшения пользовательского опыта.
А теперь теория.
Основными компонентами в архитектуре Kafka являются брокеры, топики, партиции и продюссеры/консумеры.
1. Брокеры:
- Брокер в Kafka является основным серверным компонентом, который отвечает за обработку и хранение сообщений.
- Множество брокеров объединяются в кластер, который обеспечивает отказоустойчивость и масштабируемость системы.
- Каждый брокер в кластере отвечает за некоторое количество топиков и их партиций.
2. Топики:
- В Kafka данные организуются в топики, которые представляют собой логические единицы для категоризации и потоковой обработки данных.
- Топики могут быть разделены на несколько партиций, что позволяет обрабатывать данные в параллельном режиме и обеспечивать высокую пропускную способность.
- Каждая партиция в топике - это упорядоченная последовательность записей.
3. Партиции:
- Партиции являются физическими единицами данных в Kafka, которые распределяются между несколькими брокерами в кластере.
- Каждая партиция содержит уникальный набор сообщений, которые упорядочены в рамках этой партиции.
- Разбиение данных на партиции позволяет обрабатывать и хранить большие объемы данных и обеспечивает линейное масштабирование.
4. Продюсеры и консумеры Kafka:
- Продюсеры - это компоненты, которые записывают (публикуют) сообщения в топики Kafka.
- Консумеры - это компоненты, которые читают (подписываются на) сообщения из указанных топиков и обрабатывают их.
- Каждый продюсер и консумер может работать со множеством топиков и партиций.
5. ZooKeeper:
- ZooKeeper используется в кластере Kafka для управления конфигурацией, координации и обнаружения брокеров.
- Он отслеживает состояние и метаданные кластера Kafka и помогает в решении проблем с отказами и переключениями лидеров.
Также следует упомянуть, что Kafka предоставляет механизмы по обеспечению гарантий доставки сообщений, такие как отложенная доставка и гарантии "at-least-once" и "exactly-once". Эти функции позволяют обеспечивать надежность и целостность данных.
Всем привет, cегодня мы отмечаем особый день — День программиста! 🎉
Раз вы в этом канале значит вам интересна автоматизация, а процесс автоматизации тестирования это процесс написание программного кода))
Многие автоматизаторы полностью переходят в разработку, и это подчеркивает, что они по своей сути тоже программисты!
Так что, поздравляю вас с Днем программиста!
Пусть ваш код всегда выполняется с первого раза, а баги исчезают до их появления!
А для тех, кто только начинает свой путь в автоматизации — помните, что вы на верном пути!
Каждый ваш тест — это шаг к качественному продукту, а каждый сэкономленный час благодаря автоматизации — это возможность уделить внимание новым вызовам.
С праздником, друзья! Пусть код всегда будет чистым, а разработки — удачными!
Как вы знаете, в качестве разработчика большую часть своего времени я занимаюсь функционалом для генерации интеграционных автотестов. Тем не менее, мне интересно наблюдать, что разработчики мыслят совершенно иначе. Когда я говорю, что мне действительно нужно взаимодействовать с сервисом и изменять или создавать данные, мне отвечают, что это небезопасно. Я же говорю: "Так мы всегда так делаем." Или когда я показываю структуру фреймворка и набор классов, которые хочу генерировать, мне говорят, что это сложно и что можно сделать маленькие клиенты.
Я обратил внимание, что часто, когда дело касается тестов, разработчики мыслят атомарными сущностями, отдельными классами и методами. В то время как я, как автоматизатор, при тестировании мыслю системами и интеграциями. Когда пишешь интеграционные тесты, нельзя ограничиваться только набором базовых маленьких клиентов; без нескольких уровней абстракции тесты рискуют превратиться в огромные портянки. Когда они предлагают некоторые системы просто мокировать, мне важно понимать, что в системе действительно присутствует настоящая сущность.
Но что мне определенно нравится, так это то, что доверяют моему опыту и говорят делать так, как я считаю нужным.
Возможно, это связано с тем, что мы все-таки команда платформы, и чем более базовые вещи мы предоставляем, тем большее количество людей сможет применять их под свои нужды. В то время как я хочу предоставить не просто атомарные библиотеки и их инициализацию, а сразу шаблон фреймворка и целую структуру.
В общем, MVP я уже реализовал, а то, получит ли это развитие в рамках Ozon, зависит от минидемо, которое будет завтра. Если необходимости в этом не будет, то, как и раньше, каждая команда тестировщиков будет изобретать и поддерживать свои "велосипеды". Если после демо будет положительный отклик, то платформенный фреймворк может обрасти достаточно большим функционалом для тестировщиков.
В общем, завтра увидим.
Всем привет!
Я работал в тестировании более 6 лет и считаю, что профессия "тестировщик" до сих пор недооценена.
В то время как фронтенд-разработчики отвечали только за свою часть и не очень понимали, что происходит на бэкенде и в базе данных, бэкендеры, в свою очередь, не знали, что происходит на фронте. Я же знал всё! У меня были доступы почти ко всем системам; я мог привести нужные сущности в нужное состояние из другой системы.
Наша экспертиза не может быть исключительно точечной в разработке, но она очень широка. Мы как швейцарский нож: знаем, как работает различный бэк, REST, gRPC, GraphQL, знаем языки программирования, понимаем бизнес, работаем с различными базами данных, пишем автотесты, настраиваем CI/CD, и мне кажется, это далеко не полный перечень того, что спрашивают на собеседованиях. Возможно, когда-то тестировщик действительно был просто обезьянкой, нажимающей на кнопки, как обычный пользователь, но сейчас это инженер с весьма обширными знаниями.
В общем, тестировщики, вы крутые! Поздравляю нас с этим замечательным днем — Днем тестировщика!
Прихранил тут шпаргалку по git, думаю будет некоторым полезна))
Хотя если честно я почти все делаю через IDE.
Сегодня без умностей)) Всех с пятницей)
Очень интересная статья на тему построение интеграционных Е2Е тестов.
Большая часть действий перекликается с тем, что я выполнял и строил на своем проекте( создание пакетов для каждого сервиса, обертки над requests, логи и тп.)
Рекомендую к прочтению.
+1
Еще один хороший отзыв о курсе Starter))
Первый курс, который я записал, это “Автоматизация тестирования REST и gRPC API”. Несмотря на то что курс был записан практически на коленке, он был создан именно так, как я сам пишу автотесты, то есть почти с места в карьер. Там нет воды — от слова совсем, минимум теории и максимум прикладного материала. Мы охватили всё: REST, базы данных, gRPC, репортинг и многое другое — всё это вместилось в 7 недель. У курса были очень хорошие и даже восторженные отзывы.
Но, как говорится, не без нюансов. Курс собирал в себе инженеров от Junior до Senior уровня. Из-за этого был большой разбег в опытности студентов, и в среднем из 10-15 человек до конца доходили всего 1-3 человека.
Я постарался извлечь весь опыт предыдущих потоков, и всё-таки разбил курс на части. Я добавил теории, но сделал это очень емко, чтобы даже у опытных участников не забиралось их драгоценное время. А те, кто только начинает свой путь, могли освоить все тонкости.
Так у меня появились уже две ступени:
1. Starter — для совсем начинающих, кто только погружается в основы программирования.
2. Advanced — для продолжающих и людей с опытом до 3 лет. Конечно, три года опыта могут быть разными, но, имея большой опыт проведения собеседований, я понимаю, что многие кандидаты ни разу не поднимали фреймворк с нуля и, например, лишь дополняли текущий проект, что оставляет множество пробелов в знаниях.
3. Professional — эта ступень, скорее, для участников Advanced, так как многие к этому уровню уже знают о кодогенерации, линтерах, умеют собирать пакеты и могут поднять сервис на FastAPI. Эта ступень пока находится в разработке.
Многие могут сказать что маркетинг, но мне удалось увеличить доходимость ступени Advanced до 80% и это было одной из самых важных задач.
Некоторые боялись, но даже после курса Starter смогли закончить Advanced и научиться поднимать автоматизацию с нуля на своем проекте а где-то даже улучшить свой проект внедрив новые полученные знания.
В среднем я записываю один курс за год, и мне кажется, что многие мои бывшие студенты уже вырастают из этих ступеней, хотя появляются новые подписчики которые пока находятся на начальных уровнях.
Обучение ступени Advanced уже идет второй день, и в отличие от него, ступень Starter доступна в любое время.
Вы можете изучить её, чтобы подготовиться к следующему потоку.
Я знаю, что среди моих подписчиков есть те, кто регулярно читает мои посты, поэтому подарю промокод на скидку 40% на курс Starter.
ПРОМОКОД:
START0309
ДЕЙСТВУЕТ ДО 06.09.2024!!!Зачем использовать DTO и Pydantic модели в автотестах?
В LinkedIn один из подписчиков спросил, почему все юзают модели в автотестах и просил поделиться каким-то докладом, который скажет почему это хорошо, так как у него на этот счет другое мнение. Ссылки на доклад у меня конечно же нет, но есть опыт и свое мнение, которое было получено эмпирическим путем.
Одним из важных аспектов написания автотестов является правильное управление данными, с которыми тесты работают. В этом контексте использование DTO (Data Transfer Objects) и Pydantic моделей предоставляет множество преимуществ по сравнению с использованием обычных словарей. Давайте рассмотрим, почему стоит включить их в свой фреймворк тестирования.
1. Ясность и структура
DTO и Pydantic модели предлагают явную структуру для данных. Вместо работы с неявным набором ключей и значений в словаре вы определяете четкие классы с атрибутами. Это повышает читаемость и понимание кода, так как другие разработчики (или вы сами через некоторое время) смогут быстро понять, какие данные ожидать.
from pydantic import BaseModel
class UserDTO(BaseModel):
id: int
name: str
email: str
user = UserDTO(id=1, name="Alice", email="alice@example.com")
2. Проверка данных
Pydantic автоматически проверяет данные на соответствие определенным типам и ограничениям. Это позволяет ловить ошибки на этапе их возникновения, минимизируя возможность получения неверных данных в тестах. Например, если вы попытаетесь создать объект UserDTO с некорректными данными, Pydantic сразу сообщит о проблеме, что значительно упростит отладку. Это может возникнуть если без вашего ведома поменяют контракты.
try:
user = UserDTO(id=1, name="Alice", email="not-an-email")
except ValueError as e:
print(e) # Уведомление о ошибке валидации email
3. Поддержка сложных типов данных
Pydantic поддерживает вложенные модели и комплексные типы данных, что делает его идеальным для работы с более сложными структурами. Если в вашем приложении есть сложные объекты или ассоциации, использование Pydantic позволит легко управлять ими и поддерживать чистоту кода. Использование простых словарей может привести к большому количеству кода и ошибок, их неудобно писать используя все эти апострофы и тп.
from typing import List
class AddressDTO(BaseModel):
city: str
street: str
class UserDTO(BaseModel):
id: int
name: str
addresses: List[AddressDTO]
user = UserDTO(
id=1,
name="Alice",
addresses=[AddressDTO(city="New York", street="5th Avenue")]
)
4. Легкость в поддержке и рефакторинге
Явная схема данных, предоставляемая DTO и Pydantic, облегчает рефакторинг. Когда вы изменяете структуру данных, изменения в моделях сразу же отразятся в тестах. Это снижает риск возникновения несоответствий между использованием данных в коде и их тестировании.
5. Улучшенная интеграция с типами
Используя Pydantic, вы получаете преимущества статической типизации, что помогает вашему IDE и инструментам анализа кода лучше понимать ваш код. Это может значительно повысить продуктивность разработки и качество кода.
Заключение
В общем, использование DTO и Pydantic моделей в автотестах предоставляет множество преимуществ, включая ясность, валидацию данных, поддержку сложных структур и улучшенную поддержку при рефакторинге а так же подсказки IDE. Не стоит недооценивать важность правильного подхода к управлению данными в тестах, и выбор Pydantic может стать отличным шагом к созданию более надежного и поддерживаемого кода.
В общем это мое мнение. А вы используете DTO подход в автотестах или словари?
DTO - 🔥 Словари - 👍+2
Это мои мучения и попытки.
Ну и мой итоговый рабочий тест.
В этом коде используются два вида мокирования: Mock и patch.
Mock - это класс из библиотеки unittest.mock, который позволяет создавать мок-объекты.
Мок-объект - это объект, который имитирует поведение другого объекта, но не имеет его реальной функциональности.
В этом коде, mock_config - это мок-объект, который имитирует конфигурацию.
Он создается с помощью Mock() и имеет атрибут http, который является списком мок-объектов.
patch - это декоратор из библиотеки unittest.mock, который позволяет заменить определенный объект или функцию на мок-объект во время выполнения теста.
В этом коде,
@patch.object(HTTPHelpersGenerator, "_config", new_callable=Mock)заменяет атрибут _config класса HTTPHelpersGenerator на мок-объект. Это означает, что когда в коде используется HTTPHelpersGenerator._config, на самом деле будет использован мок-объект. Аналогично,
@patch("pypl_generators.qa.helpers_codegen.HelpersGenerator")
заменяет класс HelpersGenerator на мок-объект.
Как это работает:
Когда тест test_helpers_generate запускается, он использует мок-объекты, созданные с помощью Mock и patch.
В частности:
mock_config - это мок-объект, который имитирует конфигурацию.
mock_helpers_generator - это мок-объект, который имитирует класс HelpersGenerator.
HTTPHelpersGenerator._config - это мок-объект, который имитирует атрибут _config класса HTTPHelpersGenerator.
Когда в тесте используется generator.generate(), на самом деле будет вызван метод generate() мок-объекта mock_helpers_generator.
Аналогично, когда в тесте используется mock_config.http, на самом деле будет использован атрибут http мок-объекта mock_config.
Это позволяет тестировать поведение кода без необходимости реальной конфигурации и классов.Самое сложное в разработке — это не написание кода, а его отладка.
Как вы знаете, сейчас я разрабатываю фреймворк для автотестирования. В нашем проекте настроено несколько джоб, которые линтят (проверяют) код.
Во-первых, мы используем линтеры для:
- Проверки стиля кода
- Выявления уязвимостей
- И многих других задач
Написать код недостаточно, его еще надо протестировать. Поэтому мы должны создать unit-тесты, и у нас установлен порог покрытия: минимум 80%.
Недавно я потратил 2 дня, пытаясь выяснить, почему у меня локально unit-тесты работают, а в Pipeline — нет. Это было довольно напряженно, ведь код написан и рабочий, но я не мог отправить его на код-ревью, пока не пройдут тесты. Один из тестов работал локально, но в пайплайне не запускался. Удалил его — все тесты прошли, но это снизило покрытие, и джоб упал. В общем, замкнутый круг.
Задача заключалась в следующем:
Протестировать все свои генераторы, но если более конкретно, проблема заключалась в том, что нужно было протестировать метод в классе, который использует свойство, унаследованное от родительского класса.
Пока я разбирался, я научился мокать классы и свойства — это было очень полезно! Научился переопределять у класса наследника, класс родитель "на лету".
Но, как всегда, ключевая ошибка была в неожиданном месте 🤬
В итоге оказалось, что я получал текущую директорию, используя
Path("."), вместо Path.cwd(). На первый взгляд, это одно и то же, но в пайплайне, в сочетании с тем генератором кода, который я написал, это сыграло критическую роль.
В конечном итоге:
Я написал тесты, джобы прошли, я выдохнул и многому научился!Привет, давненько не виделись!
Давайте немного отвлечемся от полезностей и расскажу о том, чем сейчас занимаюсь.
Уже вторую неделю я работаю в качестве разработчика Python платформы.
Если честно, пока трудновато. В основном платформа реализована через механизм Dependency Injection (DI).
Помимо этого, инициализация классов сделана через type hints.
Если вы когда-нибудь устанавливали типы данных в Python, то знаете, что это такое.
То есть, если мне необходимо реализовать фасад, который объединяет несколько клиентов, на курсе мы обычно делаем так:
class Facade:
def __init__(self):
self.api1 = Api1Client()
self.api2 = Api2Client()
а здесь учитывая асинхронную парадигму выглядит так:
@dataclasses.dataclass
class Facade(Client):
api1: Api1Client
api2: Api2Client
А инициализация (то есть, создание клиентов) происходит как раз через механизм DI.
Примерно вот так:
@pytest.fixture(scope="session")
async def facade(di) -> Facade:
client = di.resolve(Facade)
async with di:
yield client
а обычно это выглядит так:
@pytest.fixture(scope="session")
async def facade(di) -> Facade:
return Facade()
Чтобы с этим разобраться и понять, как это работает, я потратил довольно много времени.
Потом пытался прикрутить это все на существующий проект автотестов.
Дальше был этап обсуждения и согласования с другими командами тестировщиков на тему перехода на новый фреймворк.
Это вызвало много головной боли, но стоит признать, что доводы были серьезные.
И объективно, еще один фреймворк, на который переписывать все тесты, никто не хочет, но и поддерживать весь тот зоопарк инструментов, который существует в текущий момент, выглядит нереально.
Как итог, мы решили пока оставить то, что работает, а я начал пилить MVP проекта с полной поддержкой существующей платформы.
Это накладывает большие риски, что работа может быть сделана в стол, но и открывает определенные перспективы, ведь часть команд пока не имеет устоявшегося подхода и готовы взять то, что сделаем, главное, чтобы это работало и поддерживалось.
Вот такие дела.
В общем, я взял себе срок 2 недели на реализацию MVP.
Пожелаем мне удачи и посмотрим, что из этого выйдет! 😊Коллеги напомню, что до 25 числа действует скидка 15% на курс "Автоматизация тестирования REST API Advanced".
Промокод есть в этом посте.
P.S Можете попробовать заказать обучение у своего работодателя, у меня уже учились спецы со СБЕР-а, Тинька и др.
Я обещал свое решение задачи, которое было напилено на собесе, так вот оно выглядело так:
def print_window(height, width, word):
print('#' * width)
for i in range(height - 2):
if i == (height - 2) // 2:
print('#' + word.center(width - 2, ' ') + '#')
continue
print('#' + (' ' * (width - 2)) + '#')
print('#' * width)
- Первым делом мы печатаем верхнюю границу рамки нужной ширины.
- Далее в цикле печатаем боковые границы нужной высоты минус 2, потому что верхнюю мы уже напечатали, а нижнюю напечатаем в конце.
- Условием if определяем середину рамки. Если нашли, то печатаем слово, центрируя его с учетом правой и левой границ, то есть минус 2.
- Печатаем нижнюю границу.
Кидайте в тред задачки которые были у вас на собесах)Всем привет, в своем чате выпускников нашел задачу с собеса в 2ГИС.
Звучит она так:
Написать реализацию функции, которая задает рамку заданной ширины и высоты, и в центре нее размещает слово.
Требований к красоте кода и производительности нет, главное решение, на задачу отводится 20 минут:
def print_window(height, width, word):
# Здесь реализация
print_window(height=5, width=18, word='hello world!')
# Вывод функции:
##################
# #
# hello world! #
# #
##################
Пишите свои решения если есть, только без чатов жопати))
Я завтра пришлю свое)👇Самые важные, на мой взгляд, паттерны, которые следует изучить для автоматизации тестирования API, это PROXY, FACADE, DECORATOR, SINGLETON.
⠀
Proxy - позволяет добавлять функционал к объекту, не изменяя сам объект. Это полезно при расширении функционала классов клиентов.
⠀
Facade - позволяет объединить логику нескольких классов, делая композицию более удобной и обеспечивая более удобный доступ к вложенным классам.
⠀
Decorator - позволяет динамически изменять поведение объектов, что удобно, например, для реализации авторизации или повторной отправки запросов.
⠀
Singleton - удобно использовать для экономии ресурсов, например, если в ваших автотестах используется подключение к базе данных. Вместо открытия нового соединения для каждого теста, используя синглтон, можно проверять наличие уже открытого соединения и повторно использовать его. Таким образом, можно быть уверенным, что если вы забыли закрыть соединение, ресурсы не будут истощены, а будет использовано уже существующее соединение.
⠀
Я записал бесплатный видеоурок, в котором рассказываю об основных паттернах в контексте автоматизации тестирования API.
⠀
Пиши в бот @it_wizard_bot слово
паттерны и он отправит инструкцию как получить доступ к уроку)Repost from Библиотека программиста
+1
🆙 Python укрепляет позиции в индексе TIOBE
Вероятно, Python станет самым популярным языком программирования в истории, — написал генеральный директор TIOBE Software Пол Янсен в ежемесячном выпуске индекса. Популярность Python выросла с 16,12% в июле до 18,04% в августе — очень значительный скачок за такой короткий период, — и теперь «Питон» опережает второй язык в списке, C++, на рекордные 8%. Янсен отметил, что лидерство Python неоспоримо, и добавил, что его единственными возможными конкурентами в будущем могут стать только Rust и Kotlin. Они стремительно приближаются к топ-10, и все же на достижение сопоставимых с Python позиций у них уйдет несколько лет. Rust сейчас занимает 14-е место, а Kotlin — 18-е. Популярность Kotlin значительно выросла за год — в августе 2023 года он был на скромном 27-м месте. P. S. Go тоже набирает обороты! TIOBE — тот самый рейтинг, к которому все относятся скептически. Если верить опросу Stack Overflow, Go — на 13-м месте, Rust — на 14-м, Kotlin — на 15-м.
¡Ya disponible! Investigación de Telegram 2025 — los principales insights del año 
