Куда опять пропал Дима?
После Сибирь.JS уехал в отпуск на Алтай и накопил целую кучу новостей и мыслей, которыми и начинаю делиться прямо сейчас. И начну с подкаста, который мы записали прямо во время Codefest 2024 с ребятами из Т-банк (да-да, чуть было не написал Тинькофф🥲)
🎙 О чем болтали?
— Выясняли, как работают QA в Dodo Engineering и можно ли поймать баги прямо в пиццерии.
— Обсуждали, на что ориентироваться, чтобы нанять правильного кандидата и какие книжки нужно читать, чтобы понравиться директору по качеству 😁.
— Узнаем, в какой день пиццерии испытывают самую высокую нагрузку и как выход на зарубежный рынок влияет на тестирование.
Слушайте на любимых платформах:
Яндекс.Музыка
Apple Podcasts
Youtube
Остальные платформы
После Сибирь.JS уехал в отпуск на Алтай и накопил целую кучу новостей и мыслей, которыми и начинаю делиться прямо сейчас. И начну с подкаста, который мы записали прямо во время Codefest 2024 с ребятами из Т-банк (да-да, чуть было не написал Тинькофф🥲)
— Выясняли, как работают QA в Dodo Engineering и можно ли поймать баги прямо в пиццерии.
— Обсуждали, на что ориентироваться, чтобы нанять правильного кандидата и какие книжки нужно читать, чтобы понравиться директору по качеству 😁.
— Узнаем, в какой день пиццерии испытывают самую высокую нагрузку и как выход на зарубежный рынок влияет на тестирование.
Слушайте на любимых платформах:
Яндекс.Музыка
Apple Podcasts
Youtube
Остальные платформы
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥29❤3🥰2
#patterns #automation
О неправильном понимании Принципа единственной ответственности (Single-responsibility principle) применительно к PageObject.
На днях один из моих студентов задал вопрос:
Казалось бы, простой вопрос с простым ответом🙂
И далее:
И вот тут я понял, что надо писать пост.
Всем мы на подсознательном или осознанном уровне понимаем, что такое Single responsibility. Это - максимально упрощая - когда класс
На чем базируется это с технической точки зрения в ООП?
На инкапсулированных зависимостях
и вот этот
Важно тут то, что наш
А теперь к PageObject🙂:
Что он инкапсулирует? Элементы на странице. У этих элементов есть метод
Я не понимаю, как использование
И то, и другое - это работа со страницей авторизации. И это и есть одна ответственность класса LoginPage.
Пока в ваших PageObjecta-х инкапсулированы только элементы страницы, вы не нарушите никаких Solid-ов.
Добавляйте методы с ассертами и проверками в свои PageObject-ы на здоровье, если хотите - не добавляйте, создавайте AssertObject-ы, но во всех этих случаях - не слушайте псевдоумные рассуждения про SOLID применительно к данному случаю.
О неправильном понимании Принципа единственной ответственности (Single-responsibility principle) применительно к PageObject.
На днях один из моих студентов задал вопрос:
Добавили в РО вместе с остальными шагами. Насколько правильно шаги с ассертом объединять в одном РО?
Вот в РО на авторизацию. У меня есть и шаг заполнения полей с кликом и проверка результата. На работе настучали по рукам, чтобы проверка была не в РО, а именно в тесте
Казалось бы, простой вопрос с простым ответом🙂
И далее:
Я после своего вопроса решил сам исследовать проблему. В некоторых "умных книжках", сказали, что нельзя использовать ассерты. Так как разделяют на: "методы для взаимодействия с элементами страницы" и "методы для проверки состояния элементов страницы". Это, как я понимаю, ведет к нарушению принципа SOLID по единой ответственности и поэтому нельзя.
И вот тут я понял, что надо писать пост.
Всем мы на подсознательном или осознанном уровне понимаем, что такое Single responsibility. Это - максимально упрощая - когда класс
UserController отвечает за создание и редактирование юзеров, и не отвечает за отправку e-mail-ов с прогнозом погоды. На чем базируется это с технической точки зрения в ООП?
На инкапсулированных зависимостях
UserController-а. Нет, я понимаю что все можно написать на static методах, но все-таки, UserController должен выглядеть примерно так:class UserController {
private final UserRepository userRepository;и вот этот
userRepository - он работает с юзерами в БД (я в курсе, что инжектить репозитории в контроллеры не надо, это просто пример).Важно тут то, что наш
UserController не должен инкапсулировать EmailWeatherNotifier, и чисто технически не должен получить возможность отвечать за что-то не то (нарушать S в слове SOLID).А теперь к PageObject🙂:
class LoginPage {
private final SelenideElement usernameInput = $("#username");
private final SelenideElement passwordInput = $("#password");Что он инкапсулирует? Элементы на странице. У этих элементов есть метод
click(), setValue(...) и, внезапно, shouldBe(...). Я не понимаю, как использование
shouldBe(...) (ассерта) может являться здесь нарушением Single responsibility, а setValue(...) - нет.И то, и другое - это работа со страницей авторизации. И это и есть одна ответственность класса LoginPage.
Пока в ваших PageObjecta-х инкапсулированы только элементы страницы, вы не нарушите никаких Solid-ов.
Добавляйте методы с ассертами и проверками в свои PageObject-ы на здоровье, если хотите - не добавляйте, создавайте AssertObject-ы, но во всех этих случаях - не слушайте псевдоумные рассуждения про SOLID применительно к данному случаю.
Telegram
Simon
You can contact @SemyonPostnikov right away.
👍27❤2
На Сибирь.JS проводил перепись олдфагов в формате 100к1 с вопросом - "Из каких шагов состоит CI с тестами?", задаваемого мной на собесах новичкам в автоматизации после тех или иных курсов. Первые 2 самых популярных ответа видны на фотках, а кто угадает оставшиеся 4?
🔥16😁3
Думаю многие слышали про Spring initializr. Это когда вы можете не думать, какие там плагины, зависимости и т.д. вставить в свой pom.xml (ну или build.gradle), а в режиме "проставить галочки че хочу на выходе" получаете готовый Spring-проект.
К чему это я?
Хочу прорекламировать (бесплатно, конечно🥲) появление такой-же фичи в Allure!
И там-то она ну точно полезна - сколько людей путаются в версиях AspectJ и java, в плагинах и зависимостях Allure и прочем. Единственное, что бы я посоветовал доработать - в генерируемом build.gradle (pom.xml) добавлять exclude junit-а из
Это полезно, потому что при использовании самых последних и свежих JUnit-ов могут возникнуть конфликты, т.к. аллюр может не успевать день-в-день за выходом нового релиза JUnit. Я бы подключал это так:
В общем, сохраняйте ссылку и пользуйтесь Allure start!
К чему это я?
Хочу прорекламировать (бесплатно, конечно🥲) появление такой-же фичи в Allure!
И там-то она ну точно полезна - сколько людей путаются в версиях AspectJ и java, в плагинах и зависимостях Allure и прочем. Единственное, что бы я посоветовал доработать - в генерируемом build.gradle (pom.xml) добавлять exclude junit-а из
testImplementation "io.qameta.allure:allure-junit5"Это полезно, потому что при использовании самых последних и свежих JUnit-ов могут возникнуть конфликты, т.к. аллюр может не успевать день-в-день за выходом нового релиза JUnit. Я бы подключал это так:
testImplementation("io.qameta.allure:allure-junit5:${allureVersion}") {
exclude group: "org.junit.jupiter"
}В общем, сохраняйте ссылку и пользуйтесь Allure start!
Spring Initializr
Initializr generates spring boot project with just what you need to start quickly!
👍23🔥15
Сегодня и завтра я на главном событии года DODO - съезде партнеров. Тут все ключевые лидеры DODO, партнеры, открывшие кто пару, а кто и больше сотни наших ресторанов. Наша цель - Х2 во всем. И качество наших IT-продуктов - ключевая вещь, без которой ничего не будет. Весь первый день я слушал выступления наших топменеджеров, но в мыслях было - а как мы будем делать все это качественно и без багов? Эти мысли сложнее, чем написание тестов, тесткейсов и всего остального. Нам нужен прорыв, нам нужно избавиться от багов на оплате, нам нужно безупречное приложение и безупречная работа бэкофиса. Нам нужен крутой QA, который тоже будет х2 от конкурентов. Это все еще вызов для меня, хотя казалось бы, где еще искать вызовы, когда ты уже 16 лет во всем этом IT.
👍27🔥8❤4
Тот самый лучший, на мой взгляд, Keynote, который я видел на айтишных конфах (а побывал я на многих). Посмотрите, прочувствуйте
YouTube
Александр Кирсанов. Раньше деревья были выше, а IT круче. Или нет?
Как далеко шагнуло программирование, имеет ли смысл сейчас оглядываться на инженеров прошлого века, чтить классику Дядюшки Боба и придерживаться устоявшихся паттернов? Попробуем ответить на эти и другие фундаментально-филосовские вопросы с помощью путешествия…
🔥12👀6💔3👎1😁1
Forwarded from Heisenbug — канал конференции
#видеозаписи
Прошлогодний воркшоп о JUnit Extensions так понравился участникам, что этой весной получил продолжение. А сегодня в рубрике #ТестоваяСреда мы открываем запись этого продолжения, так что теперь все могут посмотреть обе части:
— The Art of JUnit Extensions
— The Art of JUnit Extensions 2
Прошлогодний воркшоп о JUnit Extensions так понравился участникам, что этой весной получил продолжение. А сегодня в рубрике #ТестоваяСреда мы открываем запись этого продолжения, так что теперь все могут посмотреть обе части:
— The Art of JUnit Extensions
— The Art of JUnit Extensions 2
🔥41❤9
💪 Сегодня в 20:00 по МСК приглашаею на открытый урок: "Niffler 2.0".
Это созданный мной и Ириной Стяжкиной (бэк и фронт соответсвенно) учебный проект, в котором есть все, что есть у меня в голове. Хочу поговорить (не очень технически, скорее душевно) про:
✅ Эволюцию Niffler от первой версии до сегодняшнего дня. О чем мы думали, делая этот проект?
✅ О своем взгляде на учебный процесс для синьеров AQA
🔗 Зарегистрируйтесь на этот стрим и мы можем просто пообщаться в конце, на любые темы. А может быть, увидимся на моем авторском курсе, стартующем через 2 дня 😳 Скидка тут, если что
Это созданный мной и Ириной Стяжкиной (бэк и фронт соответсвенно) учебный проект, в котором есть все, что есть у меня в голове. Хочу поговорить (не очень технически, скорее душевно) про:
✅ Эволюцию Niffler от первой версии до сегодняшнего дня. О чем мы думали, делая этот проект?
✅ О своем взгляде на учебный процесс для синьеров AQA
🔗 Зарегистрируйтесь на этот стрим и мы можем просто пообщаться в конце, на любые темы. А может быть, увидимся на моем авторском курсе, стартующем через 2 дня 😳 Скидка тут, если что
GitHub
IrinaStyazhkina - Overview
IrinaStyazhkina has 35 repositories available. Follow their code on GitHub.
🔥23❤3
В конце сентября буду в Москве с докладом про GraphQL, а точнее, про то, как его автотестировать с точки зрения логики на бэке.
Буду рад пообщаться вживую, доклад стоит последним, после него - сплошное after-party 🍻
Буду рад пообщаться вживую, доклад стоит последним, после него - сплошное after-party 🍻
🔥37
Всем, кто хотел со мной пообщаться лично в Питере, go завтра (26.09) на митап Ю.money, где я буду выступать со своим докладом о догмах тестирования
👍8
Forwarded from ЮMoney Tech
Приглашаем на BugsBusters — митап ЮMoney для QA-специалистов 🔥
Встречаемся 26 сентября в 19:00 (мск). Можно прийти в наш офис в Петербурге или подключиться к онлайн-трансляции.
На встрече эксперты ЮMoney и приглашённый спикер расскажут о работе в тестировании.
Темы докладов⤵️
🟣 Кураторство: ключ к успеху сотрудников
🟣 О чём врут тестировщик…ам? Разбираемся в QA-догмах.
🟣 Шкаф моей мечты: собираем коробку с девайсами для тестирования.
Участие бесплатное. Чтобы попасть на митап, нужно зарегистрироваться. Все подробности — на сайте BugsBusters❤️
Встречаемся 26 сентября в 19:00 (мск). Можно прийти в наш офис в Петербурге или подключиться к онлайн-трансляции.
На встрече эксперты ЮMoney и приглашённый спикер расскажут о работе в тестировании.
Темы докладов
Участие бесплатное. Чтобы попасть на митап, нужно зарегистрироваться. Все подробности — на сайте BugsBusters
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17
Итого
- Завтра я в офисе ЮMoney в Питере (б/ц БЕНУА, Пискарёвский проспект, 2 к2 ст1 регистрация тут);
- 28 и 29 сентября я в Моксве, в Loft Hall, Ленинская Слобода, 26 с.15 (регистрация тут);
- 17 и 18 октября опять в Питере на Heisenbug;
- 16 ноября буду с квартирником на Codetalks в Алматы.
После этого, делаю большой перерыв в выступлениях, для себя его называю "до востребования". Мне кажется, что это похоже на потерю мотивации - буду ее искать.
Зато начну чаще писать сюда🥲
- Завтра я в офисе ЮMoney в Питере (б/ц БЕНУА, Пискарёвский проспект, 2 к2 ст1 регистрация тут);
- 28 и 29 сентября я в Моксве, в Loft Hall, Ленинская Слобода, 26 с.15 (регистрация тут);
- 17 и 18 октября опять в Питере на Heisenbug;
- 16 ноября буду с квартирником на Codetalks в Алматы.
После этого, делаю большой перерыв в выступлениях, для себя его называю "до востребования". Мне кажется, что это похоже на потерю мотивации - буду ее искать.
Зато начну чаще писать сюда🥲
events.yoomoney.ru
BugsBusters: митап для QA-специалистов
Узнаем, как тестируют продукты в крупных компаниях
❤🔥13👍9🤝2
Сегодня кратко расскажу про ОКР функции QA на Q4 в Додо. Кратко, потому что хочется только о сути целей, все хей-резалты выписывать не охота.
Приступим?
1) Pizza app: Регресс как Quality Gate
- здесь мы хотим наконец почти полностью уйти от ручных регресс-кейсов, и заниматься полезным исследовательским тестированием. Мы шли к этому около года, к тому что бы автотесты стали по-настоящему хорошими. Выпилили моки, запилили создание прекондишенов, написали немного DSL-a, чуть-чуть вернули моки😁 Но это тема отдельного поста, если будет интерес.
2) DataCreator: Универсальный инструмент для создания тестовых данных
- для решения проблем с тестами и их прекондишенами, нам пришлось написать свой сервис-прослойку, между нашими бэкендами и тестами. Теперь мы хотим, что бы этот сервис начинал быть универсальным инструментом, например manual-тестировщик мог бы насоздавать себе тестовые данные через slack-бота.
3) Drinkit app: 2-х недельный release train
- тут все просто. Наш бизнес кофеен растет, их уже 40, три страны, но в планах США, Сингапур и куча прорывов. Поэтому надо релизтть чаще. Поэтому тут будет куча автоматизации, сейчас регресс состоит из более чем 450 ручных кейсов, это боль. И мы ради этого прямо сейчас нанимаем туда Senior QA Auto. Не реклама вакансии), надеюсь офер будет принят.
4) Pizza app: Увеличение прозрачности по состоянию багов
- продолжаем обвешивать все максимальным числом метрик и глубоко понимать каждое узкое место в качестве нашего главного мобильного приложения. Проект лично ведет наш лидер направления QA Mobile Боря Лысиков (подписывайтесь на его канал, он крут)
5) Pizza app: Увеличение технической экспертизы QA в автоматизации тестирования
- ну тут все понятно 🙂
6) infra: Отказ от дублирующих друг друга библиотек в автотестах
- у нас все ещё остаётся Selenium (хотя мы давно новые вебтесты пишем на Playwright), и ещё есть пару библиотек одного предназначения. Выпилим все дубли, Додо рискует стать первой компанией вообще без Селениума в моей карьере
7) (все) Сервисы критического пути тестируются под нагрузкой
- в нашем контуре нагрузочного тестирования все ещё не хватает пары важных сервисов с прода, а ещё эта парочка возьми да и упади под нагрузкой в день релиза коллабы с Геншен Импакт. Надо срочно исправлять - и, тут и далее, пошли обжективы нашей команды нагрузки.
8) Можем сравнивать 2 прогона нагрузочных тестов
- извечная проблема нагрузочного тестирования, мы написали свой собственный инструмент для сравнения результатов, повод для отдельного поста или доклада. Осталось заставить его работать на полную😁
9) Улучшаем интерфейс запуска тестов
- а тут мы хотим сервис из пункта 8) научить ещё и в расписание запусков и френдли интерфейс для всех разработчиков. В сумме пункты 8 и 9 должны нас приблизить к концепции единая точка входа и выхода для всего нагрузочного тестирования.
____
Ну что, достаточно амбициозно на один квартал ?🤌
Приступим?
1) Pizza app: Регресс как Quality Gate
- здесь мы хотим наконец почти полностью уйти от ручных регресс-кейсов, и заниматься полезным исследовательским тестированием. Мы шли к этому около года, к тому что бы автотесты стали по-настоящему хорошими. Выпилили моки, запилили создание прекондишенов, написали немного DSL-a, чуть-чуть вернули моки😁 Но это тема отдельного поста, если будет интерес.
2) DataCreator: Универсальный инструмент для создания тестовых данных
- для решения проблем с тестами и их прекондишенами, нам пришлось написать свой сервис-прослойку, между нашими бэкендами и тестами. Теперь мы хотим, что бы этот сервис начинал быть универсальным инструментом, например manual-тестировщик мог бы насоздавать себе тестовые данные через slack-бота.
3) Drinkit app: 2-х недельный release train
- тут все просто. Наш бизнес кофеен растет, их уже 40, три страны, но в планах США, Сингапур и куча прорывов. Поэтому надо релизтть чаще. Поэтому тут будет куча автоматизации, сейчас регресс состоит из более чем 450 ручных кейсов, это боль. И мы ради этого прямо сейчас нанимаем туда Senior QA Auto. Не реклама вакансии), надеюсь офер будет принят.
4) Pizza app: Увеличение прозрачности по состоянию багов
- продолжаем обвешивать все максимальным числом метрик и глубоко понимать каждое узкое место в качестве нашего главного мобильного приложения. Проект лично ведет наш лидер направления QA Mobile Боря Лысиков (подписывайтесь на его канал, он крут)
5) Pizza app: Увеличение технической экспертизы QA в автоматизации тестирования
- ну тут все понятно 🙂
6) infra: Отказ от дублирующих друг друга библиотек в автотестах
- у нас все ещё остаётся Selenium (хотя мы давно новые вебтесты пишем на Playwright), и ещё есть пару библиотек одного предназначения. Выпилим все дубли, Додо рискует стать первой компанией вообще без Селениума в моей карьере
7) (все) Сервисы критического пути тестируются под нагрузкой
- в нашем контуре нагрузочного тестирования все ещё не хватает пары важных сервисов с прода, а ещё эта парочка возьми да и упади под нагрузкой в день релиза коллабы с Геншен Импакт. Надо срочно исправлять - и, тут и далее, пошли обжективы нашей команды нагрузки.
8) Можем сравнивать 2 прогона нагрузочных тестов
- извечная проблема нагрузочного тестирования, мы написали свой собственный инструмент для сравнения результатов, повод для отдельного поста или доклада. Осталось заставить его работать на полную😁
9) Улучшаем интерфейс запуска тестов
- а тут мы хотим сервис из пункта 8) научить ещё и в расписание запусков и френдли интерфейс для всех разработчиков. В сумме пункты 8 и 9 должны нас приблизить к концепции единая точка входа и выхода для всего нагрузочного тестирования.
____
Ну что, достаточно амбициозно на один квартал ?🤌
🔥35👍13❤6👏1🍓1🙈1
Максимально свежее и быстрое видео с конференции E-CODE от меня про GraphQL 🚀
А заодно, и код приложения Rangiffler, на котором можно поупражняться в тестировании.
Традиционно благодарю за frontend (React + Apollo) Иру 🤍
Ставьте звездочки, лайки, нам будет приятно, а кому-то из вас, уверен, полезно 🙌
А заодно, и код приложения Rangiffler, на котором можно поупражняться в тестировании.
Традиционно благодарю за frontend (React + Apollo) Иру 🤍
Ставьте звездочки, лайки, нам будет приятно, а кому-то из вас, уверен, полезно 🙌
❤19🔥12👍8🍓1
Что не так в этом отличном коде из документации Playwright ?
Слово
Проблема-то тут фундаментальнее некуда, асинхронное API в библиотеках для тестов нафиг не нужно. Ну, вот просто не нужно, и все тут. Поэтому миллионы строк кода тестов на PW, Webdriver.IO и прочих сайпрессах - извините за выражение - засраны абсолютно ненужным словом
С удовольствием послушал бы мнения в треде ⬇️
Слово
await в начале каждой строки теста.Проблема-то тут фундаментальнее некуда, асинхронное API в библиотеках для тестов нафиг не нужно. Ну, вот просто не нужно, и все тут. Поэтому миллионы строк кода тестов на PW, Webdriver.IO и прочих сайпрессах - извините за выражение - засраны абсолютно ненужным словом
await в начале каждой строки кода. При этом на других ЯП, имеющие вполне себе рабочую модель асинхронного программирования, почему-то хватает ума библиотеки для тестов делать с обычным (синхронным) API. А может я чего-то не понимаю, и есть смысл делать тестовые билиотеки асинхронными и каждую строчку теста начинать с await? С удовольствием послушал бы мнения в треде ⬇️
👍9👎6🔥3🤔1🍓1
Часто на собесах, когда начинаем плыть в ООП🙂, можно услышать фразу от AQA -
То есть, кроме шуток, многие считают что, если в его языке есть ключевое слово
Если кто-то из прочитавших думает примерно так же, то, я предлагаю к прочтению на выходных одну из самых зацепивших меня книг по IT тематике за последние пару лет: LISP Жемчужины программирования.
Эту книге несложно найти, но, мне понадобилось прочитать ее 3 раза, что бы начать понимать. При том, что она написана легким языком и талантливо, это не какой-то фундаментальный и скучный учебник для ВУЗ-ов. Это интересное погружение в вопрос - что же такое на самом деле функциональное программирование.
Всем советую, даже если вы, в итоге, не напишете ни строчки кода на LISP
ну, я скорее про функциональное программирование, мой {ЯП name} - мультипарадигменный!
Я просто вызываю друг за другом функции.
То есть, кроме шуток, многие считают что, если в его языке есть ключевое слово
fun, или function, то, вызов их друг за другом - это функциональное программирование.Если кто-то из прочитавших думает примерно так же, то, я предлагаю к прочтению на выходных одну из самых зацепивших меня книг по IT тематике за последние пару лет: LISP Жемчужины программирования.
Эту книге несложно найти, но, мне понадобилось прочитать ее 3 раза, что бы начать понимать. При том, что она написана легким языком и талантливо, это не какой-то фундаментальный и скучный учебник для ВУЗ-ов. Это интересное погружение в вопрос - что же такое на самом деле функциональное программирование.
Всем советую, даже если вы, в итоге, не напишете ни строчки кода на LISP
🔥20👍8❤4🍓1
Выступил на Heisenbug. В зале было 43 человека. Это меньше, чем на митапе Ю.money. за пару недель до этого 🙃
Вы, конечно, скажите: Дима, у тебя неинтересная тема.
Что ж, возможно это так.
Потом я сходил к Славе Смирнову и Саше Волкову, и там было примерно столько же.
Мой топ докладов:
Саша Волков
Слава Смирнов
И Артем, если вы, как и я, не слышали про Allure 3.
UPD:
Рекомендации от Лени Руденко по крутым докладам, на которых я сам не был:
Про тестирование Helm чартов
Про тестирование математических библиотек
Развлекательный про гейм-дев
Своим поделюсь, как только выложат👌
Вы, конечно, скажите: Дима, у тебя неинтересная тема.
Что ж, возможно это так.
Потом я сходил к Славе Смирнову и Саше Волкову, и там было примерно столько же.
Мой топ докладов:
Саша Волков
Слава Смирнов
И Артем, если вы, как и я, не слышали про Allure 3.
UPD:
Рекомендации от Лени Руденко по крутым докладам, на которых я сам не был:
Про тестирование Helm чартов
Про тестирование математических библиотек
Развлекательный про гейм-дев
Своим поделюсь, как только выложат👌
Heisenbug 2024 Autumn. Конференция по тестированию не только для тестировщиков
Поиграть в игру != протестировать игру | Доклад на Heisenbug 2024 Autumn
Расскажу об основных участниках разработки игр и покажу на примерах, что тестирование необходимо абсолютно каждой команде.
❤28🔥10🍓1