ESPNWho's on the CFP bubble? Did Week 8 burst the Big 12's two-bid dreams?Bollywood HungamaAli Abbas Zafar wraps up shooting for Ahaan Panday-Sharvari starrer Beparwah; says returning to YRF feels like “coming back home”Daily MaverickWINNING: Anna Trapido is Food Writer of the YearThe Jerusalem PostIsraeli Hollywood star Gal Gadot votes in 26th Israeli Knesset electionsPunchFRSC sends 19,560 number plates to FCT after delay complaintsUN NewsKenya: 20 Ebola contacts released from quarantineInquirerEstrada’s camp refutes Bonoan’s P7-B insertion claim anewThe Straits TimesDinner will never be Over at competitive eater Zermatt Neo’s new restaurantCapital FMFormer Kiambu governor Waititu, co-accused plead for leniency in sentencingZDF heuteEntdecken Sie das ZDF-NachrichtenstudioGhaflaRuto Breaks Ground on KSh70 Billion Cement Plant in KituiBBC NewsUK and EU officials to discuss freedom of movement
The Daily Newsstand · Free, Always
Tuesday, October 27, 2026

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

Translate

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

Я работаю в Сбере и Домклике, занимаюсь тестированием. Никто меня не учил кодить — максимум, что я знал, это базовые вещи на 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: все локаторы и методы работы с экраном сосредоточены в одном месте, а тест просто вызывает их, без копипасты поиска элементов по всему коду.

Сценарии написаны на 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, что‑то не работало как надо, но в итоге тест «позеленел», и в консоли появился нужный ответ. Это ощущение — «всё работает, я действительно это сделал» — дало огромный заряд энергии и мотивацию двигаться дальше.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.