Beispiel: Unit-Test der Webschicht mit Maven und Arquillian Drone


Inhalt:

Arquillian Drone
Änderungen am Servlet
Code des Tests
Ausführen des Tests
Ausführen mit Java 17
Typ des verwendeten Browsers


Für WildFly 26: hier wird ein Unit-Test für ein EAR-Projekt, bestehend aus EJB-Projekt und Web-Projekt, unter Verwendung des Arquillian-Framework, mittels Maven erstellt und deployed.

Dieses Beispiel basiert komplett auf dem Beispiel Unit-Test mit Maven und Arquillian und erweitert es nur um einen Unit-Test der Webschicht.

Hier gibt es das gepackte Eclipse-Projekt zum Download: StatelessMaven.zip. Die Importanleitung findet man im Stateless Session Bean und Maven-Beispiel.


Arquillian Drone

Arquillian Drone (http://arquillian.org/arquillian-extension-drone/) ist eine Arquillian-Komponente, die für den Test von Webanwendungen genutzt werden kann: sie erlaubt es, innerhalb des Tests Webseiten aufzurufen, Formulare auszufüllen und abzusenden und HTML-Rückgaben des Servers auszuwerten und zu prüfen.
Arquillian Drone bildet eine Kapsel um den Selenium WebDriver (https://www.seleniumhq.org/). Dieser bildet eine API, um diverse Browser zu steuern, indem Aufrufe über die Automationsschnittstelle des jeweiligen Browsers geleitet werden.
Doku von Arquillian Drone: https://arquillian.org/arquillian-extension-drone/
Doku des Selenium WebDriver: https://www.seleniumhq.org/docs/03_webdriver.jsp

Änderungen am Servlet

Damit die vom GeometricModelServlet berechneten Werte ausgewertet werden können, werden die beiden Ergebnisse "Oberfläche" und "Volumen" in span-Tags geklammert und diesen wird ein Name (oder alternativ eine ID) gegeben:
 
        printWriter.write("Volume = <span name=\"volume\">" + dblVolume + "</span>, Surface = <span name=\"surface\">" + dblSurface + "</span>\r\n" + "<br><br><br>\r\n");

Code des Tests

Analog zum Beispiel "Unit-Test mit Maven und Arquillian" wird hier ein Integrationstest verwendet. D.h. im Webprojekt wird im Unterverzeichnis "src\test" die Klasse de.hsrm.cs.javaee8.statelessmaven.web.test.ServletIT (der Zusatz "IT" markiert sie als Integrationstest) zugefügt:
Testklasse

Sie hat diesen Code:
package de.hsrm.cs.javaee8.statelessmaven.web.test;

import java.net.URL;

import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

@RunWith(Arquillian.class)
@RunAsClient
public class ServletIT
{
    @Deployment
    public static Archive<?> getEarArchive()
    {
       ...
    }

    @Drone
    private WebDriver browser;
    
    @ArquillianResource()
    private URL deploymentUrl;

    @Test
    public final void browserTest() throws Exception
    {
        System.out.println("Testing client website ... " + deploymentUrl);
        
        //Zur Startseite navigieren:
        browser.get(deploymentUrl.toString() + "servlet/GeometricModelServlet");
        
        //Formular ausfüllen:
        browser.findElement(By.name("a")).sendKeys("7");
        browser.findElement(By.name("b")).sendKeys("8");
        browser.findElement(By.name("c")).sendKeys("9");
        //Formular abschicken:
        browser.findElement(By.name("submit")).click();

        //Ergebnisse auswerten:
        String volume = browser.findElement(By.name("volume")).getText();
        Assert.assertEquals("504.0", volume);
        
        String surface = browser.findElement(By.name("surface")).getText();
        Assert.assertEquals("382.0", surface);
    }
}

Im Detail:

Fürs Compilieren des Code müssen in "pom.xml" von "StatelessMaven-web" folgende Änderungen durchgeführt werden:
Im Element "dependencies" wird die "arquillian-drone-webdriver-depchain" zugefügt:

	<dependencies>
		...
		<dependency>
			<groupId>org.jboss.arquillian.extension</groupId>
			<artifactId>arquillian-drone-webdriver-depchain</artifactId>
			<type>pom</type>
			<scope>test</scope>
		</dependency>
	</dependencies>
Dies lädt bei WildFly 26 die Version 2.5.2.


Der Wert "test" des Elements "scope" bedeutet, dass diese Abhängigkeit nur zur Compilierung und Ausführung von Testklassen zur Verfügung steht, aber nicht im regulären Code der Anwendung.

Wichtig: danach im Contextmenü "Maven" => "Update Project" aufrufen!

In meinem Beispiel wird über die WildFly-BOM (https://repo.maven.apache.org/maven2/org/wildfly/bom/wildfly-jakartaee8-with-tools/26.0.0.Final/wildfly-jakartaee8-with-tools-26.0.0.Final.pom) schon die entsprechende Abhängigkeit bereitgestellt. Wäre das nicht der Fall, müsste man im Element "dependencyManagement" die "Bill of Materials" von Drone zufügen, hier in der Version "2.5.2" - man sollte darauf achten dass sie zu der Arquillian-Version kompatibel ist:
	<dependencyManagement>
		<dependencies>
			...
			
			<dependency>
				<groupId>org.jboss.arquillian.extension</groupId>
				<artifactId>arquillian-drone-bom</artifactId>
				<version>2.5.2</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
        
		</dependencies>
	</dependencyManagement>



Ausführen des Tests

Siehe Beispiel Unit-Test mit Maven und Arquillian.
Da ich hier zwei Integrationstests habe, wird die EAR-Datei zweimal auf den WildFly-Server deployed und wieder entfernt.


Ausführen mit Java 17

Auch hier sei auf das Beispiel Unit-Test mit Maven und Arquillian verwiesen.


Typ des verwendeten Browsers

Der Selenium WebDriver verwendet in der Defaulteinstellung HtmlUnit (http://htmlunit.sourceforge.net/) - ein "Browser" ohne GUI, wie man an der Logausgabe bei der Testausführung sieht:
Jan. 16, 2022 12:23:49 NACHM. org.jboss.arquillian.drone.webdriver.factory.AbstractWebDriverFactory createConfiguration
INFO: Property "browser" was not specified, using default value of htmlunit

In der Datei "arquillian.xml" kann man auf einen anderen Browser umschalten:

<arquillian ...>
	<extension qualifier="webdriver">
		<property name="browser">firefox</property>
	</extension>
</arquillian ...>
Im Beispiel wird Firefox verwendet. Bei Ausführung des Tests sieht man in der Konsole, dass ein "geckodriver" heruntergeladen und entpackt wird:
Drone: downloading geckodriver-v0.23.0-win64.zip from https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-win64.zip to C:\Users\USERHOME\.arquillian\drone\firefox\v0.23.0\geckodriver-v0.23.0-win64.zip 
................................................................................
Okt 15, 2018 8:46:12 PM org.jboss.arquillian.drone.webdriver.binary.BinaryFilesUtils extract
INFORMATION: Extracting zip file: C:\Users\USERHOME\.arquillian\drone\firefox\v0.23.0\geckodriver-v0.23.0-win64.zip to C:\Temp\workspace\StatelessMaven\StatelessMaven-web\target\drone\1458a83f4cb051132fe9a91f30770162

Stand 16.01.2023
Historie:
18.10.2018: erstellt
07.01.2019: Update auf WildFly 15
16.02.2019: diverse Plugins aktualisiert
25.01.2020: Projekt auf Basis des Archetype "wildfly-jakartaee-ear-archetype" erstellt - dadurch weniger Nacharbeiten an "pom.xml" nötig, Profile "arq-managed" startet jetzt Server aus "JBOSS_HOME"-Variable, WildFly 18
16.01.2022: WildFly 26, Links aktualisiert
16.01.2023: Hinweis zu Fehler bei Java 17