[JAVA] Automatischer API-Test mit Selen + REST-Assured

Bei der Entwicklung einer Web-API können Sie verschiedene UnitTest-Tools verwenden, um den Test zu automatisieren, wenn Sie die API alleine testen. Es ist jedoch ein Problem, wenn Sie mit der Website interagieren müssen. Ein Beispiel ist das Schreiben einer API-Verarbeitung, für die eine Authentifizierung erforderlich ist, z. B. OAuth. Wenn es mit SPA usw. erstellt wurde und nicht wie vorgesehen funktioniert, es sei denn, es wird im Browser angezeigt, ist es unbedingt erforderlich, über den Browser darauf zuzugreifen.

Dieses Mal habe ich versucht, den Test mit ** Selen ** für den automatischen Test des Webs und ** REST-Assured ** für den Test der API zu automatisieren, daher werde ich ihn kurz zusammenfassen.

Tools Selenium https://github.com/SeleniumHQ/selenium Es ist unnötig zu erwähnen, dass es sich um ein bekanntes Web-Test-Tool handelt. Es gibt auch eine Java-API, sodass Sie direkt von Java aus arbeiten können.

REST-Assured https://github.com/rest-assured/rest-assured Eine Bibliothek, mit der Sie REST-API-Tests in einem Methodenkettenstil schreiben können.

Unten finden Sie ein Beispiel aus README.

given().
    param("key1", "value1").
    param("key2", "value2").
when().
    post("/somewhere").
then().
    body(containsString("OK"));

Das Format besteht darin, Parameter mit ** Given () ** zu übergeben, die API anzugeben, die mit ** when () ** aufgerufen werden soll, und die erwarteten Bedingungen mit ** then () ** zu beschreiben.

Sample Schreiben wir einen API-Test, der im folgenden Szenario die Webanmeldung voraussetzt.

chromedriver Um Web Test auf Selenium auszuführen, benötigen Sie einen Browser und einen entsprechenden Treiber.

Da wir hier Chrome als Browser verwenden, lädt der Treiber auch den Chromedriver herunter. Sie können den Treiber für jedes Betriebssystem von der folgenden Site herunterladen.

https://chromedriver.chromium.org/downloads

Bitte beachten Sie, dass der von Ihnen verwendete Chromedriver mit Ihrer Version des Chrome-Browsers übereinstimmen muss. (Wenn die Chrome-Version 81 ist. *, Muss der Chromedriver dieselbe Version haben.)

build.gradle Selen einstellen und sicher sein. In der diesmal verwendeten Version scheint die als Abhängigkeit von Selen eingestellte Guave alt zu sein, daher habe ich sie von Hand ausgeschlossen und jede Version der Guave verwendet.

ref. https://stackoverflow.com/questions/50267144/chrome-options-selenium-3-10-nosuchmethoderror-com-google-common-collect-im

            // selenium
            dependencySet(group: 'org.seleniumhq.selenium', version: "3.141.59") {
                entry ('selenium-java') {
                    exclude group: "com.google.guava", name: "guava"
                }
                entry ('selenium-support') {
                    exclude group: "com.google.guava", name: "guava"
                }
                entry ('selenium-chrome-driver'){
                    exclude group: "com.google.guava", name: "guava"
                }
            }
            dependency "com.google.guava:guava:29.0-jre"

            // rest-assured
            dependency "com.jayway.restassured:rest-assured:2.9.0"

Tset class Nehmen wir unter der folgenden Umgebung einen automatisierten Test von der Anmeldung bis zum API-Aufruf an. Domains etc. sind temporär und existieren eigentlich nicht.

{
  "status": "ok"
}

SampleTest

package webtest;

import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.response.Response;
import com.jayway.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import static com.jayway.restassured.RestAssured.given;
import static com.jayway.restassured.path.json.JsonPath.from;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

class SampleTest {
    private RequestSpecification spec;
    private String session;

    @BeforeEach
    void setup() {
        System.setProperty("webdriver.chrome.driver", "./src/test/resources/chrome/chromedriver");
        ChromeOptions options = new ChromeOptions().addArguments("--headless");
        WebDriver driver = new ChromeDriver(options);

        driver.get("https://wwww.moaikids.com/login");
        driver.findElement(By.name("username")).sendKeys("username");
        driver.findElement(By.name("password")).sendKeys("password");
        WebElement element = driver.findElement(By.className("login"));
        element.submit();
        Cookie cookie = driver.manage().getCookieNamed("session");

        session = cookie.getValue();
        driver.close();

        RequestSpecBuilder build = new RequestSpecBuilder();
        build.setBaseUri("https://api.moaikids.com")
                .addCookie("session", session);
        spec = build.build();
    }

    @Test
    void ok__check() {
        Response response = given().spec(spec).get("/api/check");
        response.then().statusCode(200);
        String json = response.asString();
        System.out.println(json);

        assertNotNull(from(json).get("status"));
        assertEquals(from(json).get("status"), "ok");
    }
}

Treiberspezifikation

Geben Sie chromedriver als Systemeigenschaft an.

System.setProperty("webdriver.chrome.driver", "./src/test/resources/chrome/chromedriver");

Spezifikation der Selenoption

Geben Sie den Headless-Modus für Tests an.

ChromeOptions options = new ChromeOptions().addArguments("--headless");
WebDriver driver = new ChromeDriver(options);

Eingabe von Informationen in das Anmeldeformular

Verwenden Sie die ** sendKeys ** -Methode, wenn Sie Informationen in das Eingabeformular eingeben.

driver.get("https://wwww.moaikids.com/login");
driver.findElement(By.name("username")).sendKeys("username");
driver.findElement(By.name("password")).sendKeys("password");
driver.findElement(By.className("login")).submit();

Erfassung von Cookie-Informationen

Abrufen von Sitzungsinformationen aus einem Cookie namens Sitzung.

Cookie cookie = driver.manage().getCookieNamed("session");
session = cookie.getValue();

Erstellen Sie eine REST-versicherte RequestSpecification

Es gibt viele Möglichkeiten, REST-versicherte Tests zu schreiben. Es ist jedoch praktisch, eine RequestSpecification zu erstellen, wenn Sie eine gemeinsame Verarbeitung für mehrere APIs durchführen möchten.

Das folgende Beispiel zeigt, wie immer ein Cookie mit dem Namen session gesendet wird, wenn eine Anfrage an eine API unter ** https: /api.moaikids.com ** gestellt wird.

RequestSpecBuilder build = new RequestSpecBuilder();
build.setBaseUri("https://api.moaikids.com")
            .addCookie("session", session);
spec = build.build();

API Test Stellen Sie eine Anfrage an ** / api / check ** und bewerten Sie Folgendes:

    @Test
    void ok__check() {
        Response response = given().spec(spec).get("/api/check");
        response.then().statusCode(200);
        String json = response.asString();
        System.out.println(json);

        assertNotNull(from(json).get("status"));
        assertEquals(from(json).get("status"), "ok");
    }

Running Wenn Sie den obigen Testfall ausführen, wird Selenium gestartet und der Prozess wird über den Browser ausgeführt.

Starting ChromeDriver 81.0.4044.69 (6813546031a4bc83f717a2ef7cd4ac6ec1199132-refs/branch-heads/4044@{#776}) on port 19278
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
[1588734871.003][WARNING]: FromSockAddr failed on netmask
06. Mai, 2020 12:14:31 Uhr org.openqa.selenium.remote.ProtocolHandshake createSession
Information: Detected dialect: W3C
[1588734871.624][SEVERE]: Timed out receiving message from renderer: 0.100
[1588734871.726][SEVERE]: Timed out receiving message from renderer: 0.100

(snip.)

Wenn die durch then () oder assert ** angegebenen Bedingungen gelöscht sind, ist der Test in Ordnung, und wenn das Ergebnis vom beabsichtigten Ergebnis abweicht, tritt ein Fehler auf. Das Folgende ist ein Fall, in dem ich den Statuscode 200 erwartet, aber 403 zurückgegeben habe.

java.lang.AssertionError: 1 expectation failed.
Expected status code <200> doesn't match actual status code <403>.

Anstatt zusammenzufassen

Durch die Kombination von Selenium und REST-Assured war es relativ einfach, einen automatischen Test zu schreiben, selbst für die Verarbeitung, bei der ein Browser wie Web Login verwendet wird.

Für die Ausführung ist ein Browser erforderlich. Wenn Sie also mit CI usw. ausführen, müssen Sie beispielsweise einen Browser in die Ausführungsumgebung einfügen.

Recommended Posts

Automatischer API-Test mit Selen + REST-Assured
REST-API-Test mit REST Assured
Testen mit com.google.testing.compile
Testen Sie die Web-API mit junit
Verwenden Sie die Bulk-API mit RestHighLevelClient
Aktualisieren Sie den Git Lab-Runner mit dem automatischen Ubuntu-Update
Optimieren Sie Java-Tests mit Spock
API mit Spring + Vue.js verknüpfen
Was wählen Java-Ingenieure für das "automatische Testen" ihrer Browser? Selen? Selenid? Geb?