[JAVA] Test API automatique avec Selenium + REST-Assured

Lors du développement d'une API Web, vous pouvez utiliser divers outils UnitTest pour automatiser le test si vous testez l'API seule, mais c'est un peu un problème si vous devez interagir avec le site Web. Un exemple est celui de l'écriture d'un traitement d'API nécessitant une authentification telle que OAuth. S'il est construit avec SPA etc. et qu'il ne fonctionne pas comme prévu sauf s'il est affiché sur le navigateur, il est absolument nécessaire d'y accéder via le navigateur.

Cette fois, j'ai essayé d'automatiser le test en utilisant ** Selenium ** pour le test automatique du Web et ** REST-Assured ** pour le test de l'API, je vais donc le résumer brièvement.

Tools Selenium https://github.com/SeleniumHQ/selenium Inutile de dire que c'est un outil de test Web bien connu. Il existe également une API Java, vous pouvez donc travailler directement à partir de Java.

REST-Assured https://github.com/rest-assured/rest-assured Une bibliothèque qui vous permet d'écrire des tests d'API REST dans un style de chaîne de méthodes.

Vous trouverez ci-dessous un exemple de README.

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

Le format est de passer des paramètres avec ** given () **, de spécifier l'API à appeler avec ** when () ** et de décrire les conditions attendues avec ** then () **.

Sample Écrivons un test d'API qui suppose une connexion Web dans le scénario suivant.

chromedriver Pour exécuter Web Test sur Selenium, vous avez besoin d'un navigateur et d'un pilote correspondant.

Puisque nous utilisons Chrome comme navigateur ici, le pilote téléchargera également le chromedriver. Vous pouvez télécharger le pilote pour chaque système d'exploitation à partir du site suivant.

https://chromedriver.chromium.org/downloads

Veuillez noter que le chromedriver que vous utilisez doit correspondre à votre version du navigateur Chrome. (Si la version de Chrome est 81. *, chromedriver doit être la même version)

build.gradle Réglez le sélénium et soyez rassuré. Dans la version utilisée cette fois, la goyave définie comme dépendances du sélénium semble être ancienne, je l'ai donc exclue à la main et j'ai utilisé n'importe quelle version de goyave.

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 En supposant l'environnement suivant, écrivons un test automatisé de la connexion à l'appel d'API. Les domaines, etc. sont temporaires et n'existent pas réellement.

{
  "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");
    }
}

spécification du pilote

Spécifiez chromedriver pour la propriété système.

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

spécification de l'option sélénium

Spécifiez le mode sans tête à utiliser lors des tests.

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

Saisie des informations dans le formulaire de connexion

Utilisez la méthode ** sendKeys ** lors de la saisie d'informations dans le formulaire de saisie.

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();

Acquisition d'informations sur les cookies

Obtenez des informations de session à partir d'un cookie appelé session.

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

Créer une spécification de demande garantie REST

Il existe de nombreuses façons d'écrire des tests REST-Assured, mais il est pratique de créer une RequestSpecification si vous souhaitez effectuer un traitement commun pour plusieurs API.

Voici un exemple d'envoi permanent d'un cookie nommé session lors d'une demande à l'API sous ** https: /api.moaikids.com **.

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

API Test Faites une demande à ** / api / check ** et évaluez les éléments suivants:

--Le code d'état 200 est renvoyé par la réponse. --Il y a un élément appelé "status" dans le JSON du corps de réponse

    @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 Lorsque vous exécutez le cas de test ci-dessus, Selenium démarre et le processus est exécuté à l'aide du navigateur.

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 h 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.)

Si les conditions spécifiées par then () ou assert ** sont effacées, le test sera OK, et si le résultat est différent du résultat attendu, une erreur se produira. Vous trouverez ci-dessous le cas où je m'attendais au code d'état 200, mais j'ai renvoyé 403.

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

Au lieu de résumer

En combinant Selenium et REST-Assured, il était relativement facile d'écrire un test automatique même pour un traitement qui suppose l'utilisation d'un navigateur tel que Web Login.

Un navigateur est nécessaire pour l'exécution, donc lors de l'exécution avec CI etc., il est nécessaire de concevoir comme mettre un navigateur dans l'environnement d'exécution.

Recommended Posts

Test API automatique avec Selenium + REST-Assured
Test de l'API REST avec REST Assured
Test avec com.google.testing.compile
Tester l'API Web avec junit
Utiliser l'API Bulk avec RestHighLevelClient
Mettre à jour git lab-runner avec la mise à jour automatique d'Ubuntu
Rationalisez les tests Java avec Spock
Lier l'API avec Spring + Vue.js
Que choisissent les ingénieurs Java pour le «test automatique» de leurs navigateurs? Sélénium? Séléniure? Geb?