Хабрахабр

[Из песочницы] Смок-тестирование релиз-кандидата автотестами за 15 минут

Меня зовут Лилия, я QA Lead в одном из проектов финансовой группы БКС (сервис по подбору выгодных для клиента предложений из ряда кредитных продуктов), и сегодня я расскажу, как мы автоматизировали смок-тестирование, с какими проблемами столкнулись и какой стек технологий используем.

Поэтому решили автоматизировать сначала смок-тест, а затем уже расширять его до автоматического проведения регрессионного тестирования. Сначала мы решили автоматизировать регресс-тестирование, но время шло, функциональность менялась и мы поняли, что довольно много времени тратится на поддержку уже написанных автотестов. проект продолжал расти и обрастать дополнительными функциями. Перед отделом тестирования была поставлена задача в максимально сжатые сроки произвести автоматизацию смок-тестирования, т.к.

Что такое смок-тестирование

Смок-тестирование, как его еще называют «дымовое тестирование» – быстрая проверка наиболее критичной функциональности.

На нашем проекте:

  • Регистрация/авторизация.
  • Вход.
  • Заполнение анкеты.
  • Витрина предложений.
  • Отправка заявки/переход по ссылке на сайт партнера.
  • Обратная связь.
  • Блокировка.

Стек технологий для написания автотестов

Автотесты мы пишем на вот таком стеке: Java + Selenium + Cucumber + отчеты в Allure2.

image

BDD Автотесты для смок-тестирования

1. Фича файл с расширением .feature с описанием сценариев тестов на языке Gerkin.

Пример:

Функция: Проверка профиля, личного кабинета и заявок @all Сценарий: Проверка блоков на странице профиля Дано Перейти на страницу Главная в приложении Когда Главная: Нажимаю на ссылка Войти И Вход: Ввожу в поле Телефон значение ********** И Вход: Нажимаю на кнопка Получить код И Вход: Ввожу в поле Код подтверждения значение **** И Главная: Навожу курсор на элемент ссылка Меню пользователя И Главная: Нажимаю на ссылка Профиль Тогда Происходит переход на страницу Профиль Тогда Профиль: Отображается элемент заголовок Регистрационные данные Тогда Профиль: Отображается элемент заголовок Паспортные данные Тогда Профиль: Отображается элемент заголовок Адрес регистрации Тогда Профиль: Отображается элемент заголовок Адрес проживания Тогда Профиль: Отображается элемент заголовок Сведения о трудоустройстве

2. Шаги steps. В нем находятся классы, в которых описаны действия с элементами на странице и проверки этих элементов.

Пример:

@When("^Нажимаю клавишу (.*)") public void pressKey(String key) @When("^(.*): Нажимаю на (.*)") public void press(String pageTitle, String elementName) { waitUtils.waitElementToBeClickable(getWebElementOnWebPageWithWaiter(elementName, pageTitle)).click(); } @When("^(.*): Ставлю отметку на (.*)") public void checkCheckbox(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); if (!webElementUtils.isCheckboxSelected(element)) { element.click(); } } @When("^(.*): Снимаю отметку с (.*)") public void uncheckCheckbox(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); if (webElementUtils.isCheckboxSelected(element)) { element.click(); } } @And("^(.*): Стираем значение в (.*)$") public void erase(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); webElementUtils.clearElement(element); } @And("^(.*): Ввожу в (.*) значение (.*)$") public void enterValue(String pageTitle, String elementName, String text) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); webElementUtils.fillElementWithText(element, expressionUtils.parseString(text)); } @And("^(.*): в (.*) выбрать (.*)$") public void selectValue(String pageTitle, String dropdownListName, String value) { WebElement element = getWebElementOnWebPageWithWaiter(dropdownListName, pageTitle); webElementUtils.selectValueFromCombobox(element, value); } @Then("^(.*): в (.*) отсутствует текст$") public void elementDoesNotContainAnyText(String pageTitle, String elementName) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); assertEquals("", webElementUtils.getTextFromWebElement(element).trim()); } @Then("^(.*): ползунок (.*) находится в положении (.*)$") public void checkSliderPosition(String pageTitle, String elementName, String expectedPosition) { WebElement element = getWebElementOnWebPageWithWaiter(elementName, pageTitle); String sliderTrackPosition = StringUtils.substringBetween(element.findElement(By.cssSelector(".rc-slider-track")).getAttribute("style"), "width: ", ";"); String sliderHandlePosition = StringUtils.substringBetween(element.findElement(By.cssSelector(".rc-slider-handle")).getAttribute("style"), "left: ", ";"); assertEquals(expectedPosition, sliderTrackPosition); assertEquals(expectedPosition, sliderHandlePosition); } @Then("^(.*): Отображается компонент (.*)$") public void checkComponentIsDisplayed(String pageTitle, String component) { WebElement element = getWebElementOnWebPageWithWaiter(component, component); assertTrue(webElementUtils.isElementVisible(element)); } @When("^(.*): Загружаю файл (.+) в (.*)$") public void loadFileInField(String pageTitle, String fileName, String elementName) { WebElement element = getWebElementOnWebPage(elementName, pageTitle); File file = new File(Objects.requireNonNull(getClass().getClassLoader().getResource(fileName)).getFile()); element.sendKeys(file.getAbsolutePath()); } @Then("^(.+): У элемента (.+) атрибут (.+) имеет значение (.+)$") public void checkAttributeInElement(String pageTitle, String elementName, String attributeName, String expectedValue) { WebElement element = getWebElementOnWebPage(elementName, pageTitle); String attribute = webElementUtils.getAttribute(element, attributeName); String message = String.format("Атрибут '%s' у элемента '%s' на странице '%s' не соответствует ожидаемому значению.\n" + "Ожидаемое значение: '%s'.\nФактическое значение: '%s'.\n", attributeName, elementName, pageTitle, expectedValue, attribute); assertEquals(message, expectedValue, attribute); } @Then("^(.+): У элемента (.+) значение (.+)/$") public void checkValueTag(String pageTitle, String tagName, String expectedValue) { WebElement title = webDriver.findElement(By.tagName(tagName)); assertEquals(expectedValue, title.getAttribute("innerHTML").trim()); }
}

3. Работа с локаторами на страницах (паттерн PageObject)

Пример:

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import ru.bcs.creditmarkt.acceptance.pageobject.annotation.PageObject;
import ru.yandex.qatools.htmlelements.annotations.Name;
@PageObject(title = "Вход", path = "/entry/login")
public class LoginPage extends WebPage { @Name("ссылка Регистрация") @FindBy(xpath = "//a[text()='Регистрация']") private WebElement registrationLink; @Name("ссылка Вход") @FindBy(xpath = "//a[text()='Вход']") private WebElement loginLink; @Name("поле Телефон") @FindBy(css = "#phone") private WebElement phoneInput; @Name("кнопка Получить код") @FindBy(css = "button[type=submit]") private WebElement receiveCodeButton; @Name("поле Код подтверждения") @FindBy(css = "input#sms") private WebElement smsInput; @Name("чекбокс Согласен с условиями обработки персональных данных") @FindBy(css = "button#personalAgreement") private WebElement personalAgreementCheckbox; @Name("иконка Чат-бот") @FindBy(css = "div.wa-userpic") private WebElement chatBotIcon;
}

4. Отчет в Allure2

image

Настройка CI

Пока мы писали автотесты, у финансовой группы БКС появился Selenoid, и мы смогли настроить запуск тестов в pipline GitLab

Организация написания автотестов для разных стендов

У нас есть несколько стендов, на которых и происходит разработка, отладка, приемка, а еще есть очень много feature-стендов, где мы тестируем новые функции, разрабатываемые распределенными командами.

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

Итого

Сейчас в нашем проекте при публикации релиза на приемочный стенд за 15 минут в автоматическом режиме выполняется полный набор смок-тестов. В зависимости от полученных результатов команда тестирования принимает решение о приемке релиз-кандидата в тестирование для регрессионного тестирования.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть