Einführung in das Testen mit Arquillian

Einführung in das Testen mit Arquillian

1. Überblick

Arquillian ist ein containerunabhängiges Integrationstest-Framework für Java EE. Durch die Verwendung von Arquillian wird der Verwaltungsaufwand für Container, Bereitstellungen, Framework-Initialisierungen usw. minimiert.

Wir können uns darauf konzentrieren, tatsächliche Tests zu schreiben und nicht die Testumgebung zu booten.

2. Kernkonzepte

2.1. Bereitstellungsarchive

Es gibt eine einfache Möglichkeit, unsere Anwendung zu testen, wenn sie in einem Container ausgeführt wird.

Erstens bietet die KlasseShrinkWrapeine API zum Erstellen von bereitstellbaren*.jar,*.war,- und*.ear-Dateien.

Anschließend können wir mit Arquillian die Testbereitstellung mithilfe der Annotation@Deploymentkonfigurieren - für eine Methode, die das ObjektShrinkWrapzurückgibt.

2.2. Behälter

Arquillian unterscheidet drei verschiedene Arten von Behältern:

  • Ferngetestet mit einem Fernprotokoll wie JMX

  • Verwaltet - Remote-Container, aber ihr Lebenszyklus wird von Arquillian verwaltet

  • Eingebettet - lokale Container, in denen Tests unter Verwendung lokaler Protokolle durchgeführt werden

Wir können Container auch nach ihren Fähigkeiten klassifizieren:

  • Java EE-Anwendungen, die auf einem Anwendungsserver wie Glassfish oder JBoss bereitgestellt werden

  • Servlet-Container, die auf Tomcat oder Jetty bereitgestellt werden

  • Einzelcontainer

  • OSGI-Container

Es überprüft den Laufzeitklassenpfad und wählt automatisch den verfügbaren Container aus.

2.3. Testanreicherung

Arquillian bereichert Tests, indem es z. die Abhängigkeitsinjektion, damit wir unsere Tests leicht schreiben können.

Wir können Abhängigkeiten mit@Inject einfügen, Ressourcen mit@Resource einfügen, EJB-Session-Beans mit@EJB, usw.

2.4. Mehrere Testläufer

Mit der Annotation können mehrere Bereitstellungen erstellt werden:

@Deployment(name="myname" order = 1)

Wobei der Name der Name der Bereitstellungsdatei und der Parameter order die Ausführungsreihenfolge der Bereitstellung ist, sodass wir jetzt Tests für mehrere Bereitstellungen gleichzeitig mit der Anmerkung ausführen können:

@Test @OperateOnDeployment("myname")

Der Vorher-Test wird für den Bereitstellungscontainer vonmynamein der in der Annotation von@Deploymentdefinierten Reihenfolge ausgeführt.

2.5. Arquillian Extensions

Arquillian bietet mehrere Erweiterungen an, falls unsere Testanforderungen nicht durch die Kernlaufzeit abgedeckt werden. Wir haben Persistenz, Transaktionen, Client / Server, REST-Erweiterungen usw.

Wir können diese Erweiterungen aktivieren, indem wir den Konfigurationsdateien von Maven oder Gradle entsprechende Abhängigkeiten hinzufügen.

Häufig verwendete Erweiterungen sind Drone, Graphene und Selen.

3. Maven-Abhängigkeiten und Setup

Fügen wir unsererpom.xml-Datei die folgende Abhängigkeit hinzu:


    org.jboss.arquillian
    arquillian-bom
    1.1.13.Final
    import
    pom


    org.glassfish.main.extras
    glassfish-embedded-all
    4.1.2
    test


    org.jboss.arquillian.container
    arquillian-glassfish-embedded-3.1
    1.0.0.Final
    test

Die neueste Version der Abhängigkeiten finden Sie hier:arquillian-bom,org.glassfish.main.extras,org.jboss.arquillian.container.

4. Einfacher Test

4.1. Erstellen Sie eine Komponente

Beginnen wir mit einer einfachen Komponente. Wir haben hier keine fortgeschrittene Logik aufgenommen, um uns auf die Tests konzentrieren zu können:

public class Component {
    public void sendMessage(PrintStream to, String msg) {
        to.println(message(msg));
    }

    public String message(String msg) {
        return "Message, " + msg;
    }
}

Mit Arquillian möchten wir testen, ob sich diese Klasse korrekt verhält, wenn sie als CDI-Bean aufgerufen wird.

4.2. Schreiben Sie unseren ersten Arquillian-Test

Zunächst müssen wir festlegen, dass unsere Testklasse mit dem Framework-spezifischen Runner ausgeführt werden soll:

@RunWith(Arquillian.class)

Wenn wir unsere Tests in einem Container ausführen möchten, müssen wir die Annotation@Deploymentverwenden.

Arquillian verwendet nicht den gesamten Klassenpfad, um das Testarchiv zu isolieren. Stattdessen wird die KlasseShrinkWrapverwendet, dh eine Java-API zum Erstellen von Archiven. Wenn wir das zu testende Archiv erstellen, geben wir an, welche Dateien in den Klassenpfad aufgenommen werden sollen, um den Test zu verwenden. Während der Bereitstellung isoliertShrinkWrap nur die für den Test erforderlichen Klassen.

Mit der Methodeaddclass()können wir alle erforderlichen Klassen angeben und eine leere Manifestressource hinzufügen.

JavaArchive.class erstellt ein Modell-Webarchiv mit dem Namentest.war,. Diese Datei wird im Container bereitgestellt und dann von Arquillian zur Durchführung von Tests verwendet:

@Deployment
public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class)
      .addClass(Component.class)
      .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}

Dann spritzen wir unser Bauteil in den Test:

@Inject
private Component component;

Schließlich führen wir unseren Test durch:

assertEquals("Message, MESSAGE",component.message(("MESSAGE")));

component.sendMessage(System.out, "MESSAGE");

5. Testen von Enterprise Java Beans

5.1. Enterprise Java Bean

Mit Arquillian können wir die Abhängigkeitsinjektion einer Enterprise Java Bean testen. Dazu erstellen wir eine Klasse, die eine Methode zum Konvertieren von Wörtern in Kleinbuchstaben enthält:

public class ConvertToLowerCase {
    public String convert(String word){
        return word.toLowerCase();
    }
}

Mit dieser Klasse erstellen wir eine zustandslose Klasse zum Aufrufen der zuvor erstellten Methode:

@Stateless
public class CapsConvertor {
    public ConvertToLowerCase getLowerCase(){
        return new ConvertToLowerCase();
    }
}

Die KlasseCapsConvertorwird in eine Service-Bean eingefügt:

@Stateless
public class CapsService {

    @Inject
    private CapsConvertor capsConvertor;

    public String getConvertedCaps(final String word){
        return capsConvertor.getLowerCase().convert(word);
    }
}

5.2. Testen Sie die Enterprise Java Bean

Jetzt können wir Arquillian verwenden, um unser Unternehmen Java Bean zu testen und dieCapsService zu injizieren:

@Inject
private CapsService capsService;

@Test
public void givenWord_WhenUppercase_ThenLowercase(){
    assertTrue("capitalize".equals(capsService.getConvertedCaps("CAPITALIZE")));
    assertEquals("capitalize", capsService.getConvertedCaps("CAPITALIZE"));
}

MitShrinkWrap, stellen wir sicher, dass alle Klassen korrekt verdrahtet sind:

@Deployment
public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class)
      .addClasses(CapsService.class, CapsConvertor.class, ConvertToLowerCase.class)
      .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}

6. JPA testen

6.1. Beharrlichkeit

Wir können auch Arquillian verwenden, um die Persistenz zu testen. Zuerst werden wir unsere Entität erstellen:

@Entity
public class Car {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    private String name;

    // getters and setters
}

Wir haben eine Tabelle mit Autonamen.

Dann werden wir unser EJB erstellen, um grundlegende Operationen an unseren Daten durchzuführen:

@Stateless
public class CarEJB {

    @PersistenceContext(unitName = "defaultPersistenceUnit")
    private EntityManager em;

    public Car saveCar(Car car) {
        em.persist(car);
        return car;
    }

    public List findAllCars() {
    Query query
      = em.createQuery("SELECT b FROM Car b ORDER BY b.name ASC");
    List entries = query.getResultList();

    return entries == null ? new ArrayList<>() : entries;

    public void deleteCar(Car car) {
        car = em.merge(car);
        em.remove(car);
    }
}

MitsaveCar können wir die Autonamen in der Datenbank speichern, wir können alle Autos mitfindAllCars, speichern und wir können auch ein Auto mitdeleteCar aus der Datenbank löschen.

6.2. Testen Sie die Persistenz mit Arquillian

Jetzt können wir einige grundlegende Tests mit Arquillian durchführen.

Zuerst addieren wir unsere Klassen zu unserenShrinkWrap:

.addClasses(Car.class, CarEJB.class)
.addAsResource("META-INF/persistence.xml")

Dann erstellen wir unseren Test:

@Test
public void testCars() {
    assertTrue(carEJB.findAllCars().isEmpty());
    Car c1 = new Car();
    c1.setName("Impala");
    Car c2 = new Car();
    c2.setName("Lincoln");
    carEJB.saveCar(c1);
    carEJB.saveCar(c2);

    assertEquals(2, carEJB.findAllCars().size());

    carEJB.deleteCar(c1);

    assertEquals(1, carEJB.findAllCars().size());
}

In diesem Test erstellen wir zunächst vier Auto-Instanzen und überprüfen, ob die Anzahl der Zeilen in der Datenbank dieselbe ist, die wir erstellt haben.

8. Fazit

In diesem Tutorial werden wir:

  • Arquillian Kernkonzepte eingeführt

  • eine Komponente in den Arquillian-Test injiziert

  • ein EJB getestet

  • getestete Persistenz

  • führte den Arquillian-Test mit Maven durch

Den Code finden Sie im Artikelover on Github.