Как я без опыта разработки написал первые автотесты на Kotlin за месяц. allure.. allure. appium.. allure. appium. gherkin.. allure. appium. gherkin. junit5.. allure. appium. gherkin. junit5. Kotlin.. allure. appium. gherkin. junit5. Kotlin. автоматизация тестирования.. allure. appium. gherkin. junit5. Kotlin. автоматизация тестирования. Блог компании Домклик.. allure. appium. gherkin. junit5. Kotlin. автоматизация тестирования. Блог компании Домклик. сбер.. allure. appium. gherkin. junit5. Kotlin. автоматизация тестирования. Блог компании Домклик. сбер. тестирование.. allure. appium. gherkin. junit5. Kotlin. автоматизация тестирования. Блог компании Домклик. сбер. тестирование. Тестирование IT-систем.. allure. appium. gherkin. junit5. Kotlin. автоматизация тестирования. Блог компании Домклик. сбер. тестирование. Тестирование IT-систем. Тестирование мобильных приложений.

Сегодня я часто встречаю тестировщиков, которые работают исключительно вручную и пока не представляют, как писать автотесты. Раньше я был таким же. Но времена меняются — нейросети проникают во все сферы, и подход «я только мануальщик» постепенно устаревает. Если ты QA и до сих пор не приступил к автоматизации, самое время задуматься об этом, пока за тебя не задумались другие. Особенно актуально это для тех, кто работает в Сбере: у тебя под рукой те же самые инструменты, которыми пользуюсь я. Банк их одобряет и активно развивает, чтобы ускорить и улучшить качество работы. Надеюсь, мой опыт вдохновит кого-то попробовать сделать то же самое.

Как я без опыта разработки написал первые автотесты на Kotlin за месяц - 1

Я работаю в Сбере и Домклике, занимаюсь тестированием. Никто меня не учил кодить — максимум, что я знал, это базовые вещи на Python, и то не очень хорошо. Но за месяц я освоил внутренний Autotest Framework — платформу для автоматизации как бэкенда, так и фронтенда, — погрузился в основы Java и Kotlin и написал первые 12 автотестов. Благодаря им время критического регресса сократилось с часа до десяти минут.

В этой статье я расскажу, как мне это удалось, что помогло и с какими трудностями я столкнулся.

С чего я начинал

Продукт я знаю хорошо, ручные тесты пишу легко, с аналитикой на «ты», и в проект погружён по самые уши. Ранее я уже писал автотесты для фронта на регрессе iOS и Android — на Gherkin, в формате Given-When-Then, где сценарии расписаны простым и понятным языком, без необходимости читать код.

Однако бэкенд-автотестирование для меня было белым пятном. Кодовую базу я знал на уровне «видел», а паттерны на Java и Kotlin были для меня совершенно новыми.

Как это выглядело на мобильных автотестах

Для мобильных приложений я использую Appium. Он подключается к приложению и выдаёт JSON-дерево экрана — по сути, карту всех элементов интерфейса. Из этого JSON я вытаскивал локаторы нужных кнопок, полей и чекбоксов. Сейчас, думаю, есть агенты, которые помогают выгружать полный список корректных локаторов из JSON-дампа экрана.

Для наглядности приведу упрощённый пример, как это может выглядеть в коде (это не реальный проект, а просто иллюстрация на примере условного лендинга по ипотеке с кнопкой заявки и блоком преимуществ, чтобы БЕЗА не докопалась и не повесила на меня курс по кибербезопасности на восемь часов):

import io.appium.java_client.AppiumBy
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver

class MortgageLandingScreen(private val driver: WebDriver) {
 
     private val applyButton = AppiumBy.accessibilityId("apply_button")
     private val heroImage = AppiumBy.accessibilityId("hero_house_crane_image")
     private val benefitFastApproval = AppiumBy.accessibilityId("benefit_fast_approval")
     private val benefitOnline = AppiumBy.accessibilityId("benefit_online_submission")
     private val benefitFullDealOnline = AppiumBy.accessibilityId("benefit_full_deal_online")

     fun isHeroImageVisible(): Boolean =
         driver.findElement(heroImage).isDisplayed()
 
     fun getBenefitText(locator: By): String =
         driver.findElement(locator).text
 
     fun tapApplyButton() {
         driver.findElement(applyButton).click()
     }
 }

А сценарий на Gherkin поверх этого класса мог бы выглядеть так:

Feature: Лендинг ипотеки

  Scenario: Пользователь видит ключевые преимущества и подаёт заявку
    Given пользователь открыл лендинг ипотеки
    When экран полностью загрузился
    Then приветственная картинка с домом и краном отображается
    And отображается преимущество "Одобрим заявку за 2 минуты"
    And отображается преимущество "Не нужно идти в банк — всё онлайн"
    And отображается преимущество "Все этапы сделки проходят онлайн"
    When пользователь нажимает кнопку "Подать заявку"
    Then открывается форма подачи заявки

Далее локаторы и действия с элементами я распределял по отдельным классам — по одному классу на каждый экран. Это называется Page Object Model: все локаторы и методы работы с экраном сосредоточены в одном месте, а тест просто вызывает их, без копипасты поиска элементов по всему коду.

Как я без опыта разработки написал первые автотесты на Kotlin за месяц - 2

Сценарии написаны на Gherkin, а внутри шагов вызываются методы из классов Page Object. Такие тесты я запускаю в мобильном регрессе, и даже без глубокого знания кода в них легко разобраться — всё понятно и прозрачно.

Ещё один проверенный способ — сравнение с эталонными скриншотами. Логика проста: один раз делаем скриншот экрана, который считаем правильным, и сохраняем его как эталон. При каждом следующем прогоне регресса автотест снимает актуальный скриншот и сравнивает его с эталоном пиксель в пиксель. Этот метод даёт максимально точный результат по вёрстке — сразу видно, если текст съехал, элемент пропал или что-то сместилось. Такие проблемы при обычной проверке локаторов можно и не заметить.

В основном мы использовали Accessibility ID — он быстрый и относительно надёжный. От XPath отказались сознательно: он слишком хрупкий и ломается при малейших изменениях в разметке. Но и с Accessibility ID не всё было гладко: не у всех элементов он был прописан, у некоторых был только Class Name, а списки Appium вообще не особо любит определять. В таких случаях приходилось искать элемент по тексту на кнопке или придумывать другие обходные решения под конкретную ситуацию.

Отдельная сложность — различия между iOS и Android. Казалось бы, с бэка на оба экрана приходит одинаковый JSON, но фронтенд-команды iOS и Android верстали и рисовали интерфейсы по-разному. Из-за этого один и тот же тест нельзя было просто перенести с одной платформы на другую — приходилось заново искать локаторы и переписывать сценарии под каждую платформу.

И ещё классика: при рефакторинге разработчики меняли экраны без какой-либо документации, и локаторы, на которые опирались тесты, внезапно переставали работать.

Как выглядят бэкенд-тесты на Autotest Framework

Для бэкенд-тестов я использую ATF — внутреннюю разработку Сбера, которую в перспективе планируют внедрить во всём банке. Вот пара примеров из моих тестов.

package com.example.qa.mortgage;

import com.example.qa.config.RestEnvironmentConfig;
import com.example.qa.flow.FlowBuilder;
import com.example.qa.flow.steps.SessionRestMortgageSteps;
import com.example.qa.session.ClientAlias;
import com.example.qa.session.DeviceAlias;
import com.example.qa.session.SessionType;
import com.example.qa.session.TestSession;
import io.qameta.allure.Epic;
import io.qameta.allure.Issue;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

@Epic("critical_regression")
@Tag("applicant_eligibility")
@DisplayName("Ипотечная заявка: минимальные требования к клиенту")
public class MortgageApplicantAgeEligibilityTest {

     @Test
     @DisplayName("QA-101. Клиент младше 18 лет")
     @Issue("QA-101")
     @TestSession(
             client = ClientAlias.UNDER_18,
             device = DeviceAlias.IPHONE_TEST,
             type = SessionType.MOBILE)
     void underageApplicantIsBlockedTest() {

         FlowBuilder.getSessionRestMortgageFlowSteps()
                 .step("Запрос деталей заявки клиентом младше 18 лет",
                         SessionRestMortgageSteps::getApplicationDetail)
                 .step("Проверка отказа по возрастному критерию",
                         SessionRestMortgageSteps::getApplicationDetailUnderageRejection)
                 .run();
     }
 }

Здесь проверяется, что система корректно блокирует подачу ипотечной заявки клиентом младше 18 лет: тест создаёт нужную сессию, инициирует процесс подачи заявки от лица такого клиента и сверяет ответ с ожидаемым — отказом по возрасту.

Зачем это понадобилось

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

Классика автоматизации: одно и то же действие по десять раз без сюрпризов. Всё это я и решил перенести в автотесты.

Что реально помогло

Чужие проекты и готовые примеры как шаблон

Главная хитрость — я не стал учить Java и Kotlin с нуля по учебникам, это был бы путь самурая. Вместо этого взял за основу проекты соседних команд и базовые примеры из репозитория. Это стало моей болванкой, черновиком. Разбирал по кусочкам методом «ткнул, посмотрел, что отвалилось», так постепенно освоил базовые методы и потом уже начал собирать свои проверки.

Курсы

Самыми сложными для меня оказались паттерны разработки. В этом помогли внутренние курсы Сбера — особенно классный курс в Буткемп-учебнике для автоматизаторов. Если ты устраивался в Сбер, то наверняка уже проходил обучение на этой платформе. Темы там поданы в игровой форме — удобно и понятно. Кроме того, можно познакомиться с коллегами из разных регионов, которые уже прошли курс и готовы проверять твои решения.

ИИ‑помощники

Без искусственного интеллекта (ИИ) процесс занял бы гораздо больше времени. Я активно использовал Claude, а также внутренние инструменты — GigaChat и GigaCode. Они помогали разбираться в чужом коде, который я видел впервые, и быстро находить ошибки.

Первая победа

Особенно мне запомнился момент, когда первый автотест, наконец, прошёл, и я увидел заветный статус — PASSED. Были проблемы с просмотром в GigaIDE, что‑то не работало как надо, но в итоге тест «позеленел», и в консоли появился нужный ответ. Это ощущение — «всё работает, я действительно это сделал» — дало огромный заряд энергии и мотивацию двигаться дальше.

Как я без опыта разработки написал первые автотесты на Kotlin за месяц - 3

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

Что я автоматизировал

За месяц я написал 12 крупных тестов, которые покрывают платформенные проверки, ранее выполнявшиеся вручную:

  1. Журналирование

  2. Мониторинг

  3. События аудита

  4. Выставление технических перерывов

  5. Проверки клиентов на минимальные требования

Время прохождения этих проверок на регрессе сократилось с часа до десяти минут.

Главная сложность

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

Что бы я сказал себе три месяца назад (и тебе, если ты тоже не знаешь, с чего начать)

  1. Не бойся отсутствия опыта в разработке: понимание продукта и ручного тестирования — уже половина успеха в автотестах

  2. Бери за основу рабочие проекты соседних команд и разбирай их по частям, не пытайся понять всё сразу

  3. Начинай с самых рутинных проверок, где багов почти нет, но времени уходит много

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

Что делать дальше

До конца года я планирую автоматизировать около 30% рутинного, не критического регресса, чтобы не тратить время и силы команды на то, что можно поручить машине. В дальнейшем намерен расширять базу автотестов проекта.

Если кто не понял, это автор мема: «У вас был какой‑то план?» — «У меня был какой‑то план, и я его придерживался».

Если кто не понял, это автор мема: «У вас был какой‑то план?» — «У меня был какой‑то план, и я его придерживался».

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

Отдельная линия — e2e: стыковать бэкенд с фронтендом в единый сценарий. Такие проверки редко меняются от релиза к релизу и почти не падают, но запускать их вручную — серьёзная трата ресурсов команды. Поэтому e2e сейчас в приоритете.

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

Автор: provorkin

Источник