Заміна UI авторизації на API для автотестів

На мою думку, одним з найбільших викликів в автоматизованому тестуванні є забезпечити його надійність. У питанні покращення показників надійності гарно себе зарекомендував підхід використання API інтерфейсу замість UI.

У статті ми докладно розберемо механізм заміни UI авторизації на API. Існує багато видів аутентифікації — Basic, Digest, Form, OAuth 1 and OAuth 2. Для прикладу, я пропоную розглянути одну з найпростіших, а саме — Form. Основною метою статті є показати підхід при впровадженні API авторизації для UI тестів. Тести та імплементацію будемо писати на джаві. З іструментів будемо використовувати — Chrome DevTools.

В якості об’єктів тестування використаємо Kanboard та DVWA. Це open source продукти з відкритою ліцензією, які досить просто розгорнути локально. За посиланнями можна прочитати більше про ці продукти і ознайомитися з інструкціями їх розгортки.

Проект створюємо за допомогою maven та додаємо testng, selenide, rest-assured, json-path, jsoup, maven-compiler-plugin та maven-surefire-plugin. Проект можна переглянути за посиланням.

Логинимся в Kanboard в браузері Chrome з відкритою вкладкою Network Chrome DevTools.

Проаналізувавши DevTools, ми можемо дізнатися алгоритм авторизації. Для авторизації здійснюється два запити: GET з двома query параметрами та POST з парою логін/пароль та csrf токеном. Перший запит необхідний, щоб отримати KB_SID cookie. Другий — для KB_RM cookie. Встановивши обидва цих значення у WebDriver, ми отримаємо доступ до головної сторінки.

Перший запит у RestAssured буде виглядати наступним чином:

Response response01 = given()
       .queryParam("controller", "AuthController")
       .queryParam("action", "login")
       .when()
       .get(BASE_URL);

З нього ми отримуємо KB_SID cookie

String cookieKBSID = response01.getCookie("KB_SID");

CSRF токен знаходиться у домі HTML сторінки, яку ми можемо бачити в тілі респонсу.

Отримати його нам допоможе бібліотека jsoup, яка дозволяє розділяти документ на елементи. Пошук здійснюється схожим способом, як і Web елементи.

String cSRFToken = Jsoup.parseBodyFragment(response01.body().asString())
       .getElementsByAttributeValue("name", "csrf_token").attr("value");

Другий запит у RestAssured буде виглядати наступним чином

Response response02 = RestAssured.given()
.config(RestAssured.config().encoderConfig(EncoderConfig.encoderConfig()
.encodeContentTypeAs("x-www-form-urlencoded", ContentType.URLENC)))
       .contentType("application/x-www-form-urlencoded; charset=UTF-8")
       .formParam("remember_me", "1")
       .formParam("username", "admin")
       .formParam("password", "admin")
       .formParam("csrf_token", cSRFToken)
       .queryParam("controller", "AuthController")
       .queryParam("action", "check")
       .cookie("KB_SID", cookieKBSID)
       .when()
       .post(BASE_URL);

Тут варто зауважити, що запит необхідно правильно заенкодити (encoderConfig, encodeContentTypeAs). З нього ми отримуємо KB_RM cookie.

String setCookieHeaderValue = response02.header("Set-Cookie");

Тепер, коли ми отримали всі необхідні елементи, нам залишається тільки відкрити потрібну сторінку з заповненими полями cookie.

WebDriverRunner.getWebDriver()
       .manage().addCookie(new Cookie("KB_SID", cookieKBSID));
WebDriverRunner.getWebDriver()
       .manage().addCookie(new Cookie("KB_RM", cookieKBRM));
Selenide.open(url);

Для DVWA все відбувається майже так само, тільки токен матиме іншу назву, детальніше можна переглянути на gitlab. Зрозуміло, що для інших видів аутентифікації, кількість запитів і їх складність буде більшою. Проте базовий принцип залишається незмінним — проаналізувати алгоритм і відтворити за допомогою RestAssured.

Дякую за увагу і сподіваюся, що ця стаття була корисною для Вас.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось5
До обраногоВ обраному4
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Так же, как и без этого ) Зачем логиниться в каждом тесте? Достаточно 1 теста на логин, а в остальных логиниться через апишку для экономии времени. Так же и дальше — можно перейти сразу на вторую страницу по урле. Главное при этом не забыть оставить хотя бы по одному тесту, который проверит навигацию. Ещё большой плюс такого подхода — если ломался переход со страницы 1 на страницу 2, то упадёт 1 полный тест, который проходится по этим переходам, а остальные тесты на странице 2 будут работать.

У питанні покращення показників

Покращення — воно таке. Пиши вже assert(true), головне ж показники

Главное — спокойный сон команды. Если тесты ранятся 6 часов и часто половина падает, то сна не будет. Если такой подход оставляет прежнее покрытие, но при этом снижает время ранов и количество упавших тестов, то при чём здесь assert(true) ?

Если такой подход оставляет прежнее покрытие

Так здесь же и собака порылась. Берётся на веру, то бишь assert (true), что такой подход оставляет прежнее покрытие.

Разумеется, API для тестов это хорошо. Ровно до тех пор, пока кто-то не очень доброжелательный это API нащупает и DDOS по нему проведёт. Не то чтоб проблема нерешаема, просто её решение требует время-денег, и обычно оказывается что на безопасность там положено с прибором.

Я думал уже все давно так делают)

Я теж колись думав що спеціалісти від Skype вже відмовились, jQuery тільки в закинутих проектах, а в аутсорсі все покривають тестами

Підписатись на коментарі