JSF-Anwendungen testen mit
Arquillian Drone und Arquillian WARP
Arquillian ermöglicht "In-Container"-Tests. Will man JSF-Anwendungen
testen, genügt dies nicht, da ja auch Client-seitige Eingaben und Prüfungen
benötigt werden.
Das Arquillian-Projekt Drone verwendet Selenium, um Client-Eingaben
und Prüfungen zu realisieren. Mit den üblichen Arquillian-Möglichkeiten
hat man damit sowohl den Client als auch den Container im Zugriff.
Das Arquillian-Projekt WARP ermöglicht ebenfalls Client- als auch
Server-seitigen Zugriff. Es befindet sich gerade in der Inkubationsphase
als Arquillian-Teilprojekt. Obwohl noch nicht vollständig, erscheint
ein Blick in die aktuellen Möglichkeiten sinnvoll.
Viele Softwareprojekte starten mittlerweile mit dem Anspruch testgetrieben entwickelt zu werden. Der Anfang gestaltet sich in der Regel einfach und die Entwickler erkennen schnell die Vorzüge von TDD. Leider kommt es in vielen Fällen im Laufe der Zeit dazu, dass die Wartung der Tests mehr und mehr Zeit in Anspruch nimmt. Die Entwickler sind frustriert und TDD wird vom Management als „zu wartungsintensiv“ abgewiesen.
Ziel dieses Vortrags soll es sein, dort einzusteigen wo Tutorials und Einsteigerseminare und -bücher aufhören. Wir wollen dem erfahrenen Entwickler Tools und Vorgehensweisen an die Hand zu geben, um diesem „Wartungsalbtraum“ zu entgehen. Das echte Leben ist komplexer als das Taschenrechnerbeispiel!
CDI (Context Dependency Injection) ermöglicht es dem Entwickler skalierbare und flexible Architekturen aufzubauen die auf einem Java(EE) Server als auch auf dem Desktop laufen. Wie aber sollten DesignPattern aufgebaut werden unter Verwendung von CDI? Was für einen Einfluss hat Java 8 auf die DesignPattern, wie wird es mit der neuen Streams API kombiniert?
Höhepunkt ist die Kombination von klassischen Reflection-Einsatzgebieten wie z.B. dynamic Proxies mit CDI und Cross-Language Injections.
Viele Softwareprojekte starten mittlerweile mit dem Anspruch testgetrieben entwickelt zu werden. Der Anfang gestaltet sich in der Regel einfach und die Entwickler erkennen schnell die Vorzüge von TDD. Leider kommt es in vielen Fällen im Laufe der Zeit dazu, dass die Wartung der Tests mehr und mehr Zeit in Anspruch nimmt. Die Entwickler sind frustriert und TDD wird vom Management als „zu wartungsintensiv“ abgewiesen.
Ziel dieses Vortrags soll es sein, dort einzusteigen wo Tutorials und Einsteigerseminare und -bücher aufhören. Wir wollen dem erfahrenen Entwickler Tools und Vorgehensweisen an die Hand zu geben, um diesem „Wartungsalbtraum“ zu entgehen. Das echte Leben ist komplexer als das Taschenrechnerbeispiel!
CDI (Context Dependency Injection) ermöglicht es dem Entwickler skalierbare und flexible Architekturen aufzubauen die auf einem Java(EE) Server als auch auf dem Desktop laufen. Wie aber sollten DesignPattern aufgebaut werden unter Verwendung von CDI? Was für einen Einfluss hat Java 8 auf die DesignPattern, wie wird es mit der neuen Streams API kombiniert?
Höhepunkt ist die Kombination von klassischen Reflection-Einsatzgebieten wie z.B. dynamic Proxies mit CDI und Cross-Language Injections.
Arquillian (http://jboss.org/arquillian) is a test harness that simplifies integration testing using container managed resources.
ShrinkWrap (http://jboss.org/shrinkwrap) is a fluent Java API for dynamically generating deployable archives.
Arquillian: Helping web developers and QA get alongLukáš Fryč
Modern development practices include testing our Web applications as a fundamental part of the application development lifecycle. Web UIs though can be particularly difficult to test with basic tools. Arquillian is an award-winning integration testing framework and Selenium WebDriver is an outstanding tool for UI test automation. Together they offer a base for high-quality tests.
This session looks to the Arquillian Universe for help. Equipped with the Arquillian extensions - Drone, Graphene and Warp - we will show you tests that cover both client-side (REST) and server-rendered (JSF) web applications. With a single test it is now possible to assert state (both in the server and on the client) at arbitrary points within the request lifecycle!
We will look at current best practices for how to achieve a rapid turnaround when doing test development by minimizing the effort required to write tests, and thereby increase productivity and thus making these tests future-proof. Additionally we will show tools and techniques that provide a separation of concerns between test authors (developers) and test automators (QA). How to execute a single test in both arbitrary server containers as well as arbitrary client browsers. And how it can enable us to run test suites in constrained environments like cloud-based continuous integration providers.
Testgetriebene Entwicklung mit Jasmine und Karma hat sich mittlerweile schon als defacto-Standard etabliert. Routinen ohne Abhängigkeiten lassen sich damit ohne Probleme testen. Die Schwierigkeiten beginnen jedoch schon, wenn es um die Auflösung von Abhängigkeiten geht. In diesem Vortrag werden verschiedene Strategien und Werkzeuge vorgestellt, mit denen Abhängigkeiten zu Objekten und Funktionen oder zum Server abgedeckt werden können. Aber nicht nur Abhängigkeiten stellen Schwierigkeiten bei der testgetriebenen Entwicklung dar, auch der Umgang mit Fixtures ist bei der testgetriebenen Entwicklung mit JavaScript relevant. Abgerundet wird dieser Vortrag mit einigen Best Practices für die testgetriebenen Entwicklung mit JavaScript.
Arquillian (http://jboss.org/arquillian) is a test harness that simplifies integration testing using container managed resources.
ShrinkWrap (http://jboss.org/shrinkwrap) is a fluent Java API for dynamically generating deployable archives.
Arquillian: Helping web developers and QA get alongLukáš Fryč
Modern development practices include testing our Web applications as a fundamental part of the application development lifecycle. Web UIs though can be particularly difficult to test with basic tools. Arquillian is an award-winning integration testing framework and Selenium WebDriver is an outstanding tool for UI test automation. Together they offer a base for high-quality tests.
This session looks to the Arquillian Universe for help. Equipped with the Arquillian extensions - Drone, Graphene and Warp - we will show you tests that cover both client-side (REST) and server-rendered (JSF) web applications. With a single test it is now possible to assert state (both in the server and on the client) at arbitrary points within the request lifecycle!
We will look at current best practices for how to achieve a rapid turnaround when doing test development by minimizing the effort required to write tests, and thereby increase productivity and thus making these tests future-proof. Additionally we will show tools and techniques that provide a separation of concerns between test authors (developers) and test automators (QA). How to execute a single test in both arbitrary server containers as well as arbitrary client browsers. And how it can enable us to run test suites in constrained environments like cloud-based continuous integration providers.
Testgetriebene Entwicklung mit Jasmine und Karma hat sich mittlerweile schon als defacto-Standard etabliert. Routinen ohne Abhängigkeiten lassen sich damit ohne Probleme testen. Die Schwierigkeiten beginnen jedoch schon, wenn es um die Auflösung von Abhängigkeiten geht. In diesem Vortrag werden verschiedene Strategien und Werkzeuge vorgestellt, mit denen Abhängigkeiten zu Objekten und Funktionen oder zum Server abgedeckt werden können. Aber nicht nur Abhängigkeiten stellen Schwierigkeiten bei der testgetriebenen Entwicklung dar, auch der Umgang mit Fixtures ist bei der testgetriebenen Entwicklung mit JavaScript relevant. Abgerundet wird dieser Vortrag mit einigen Best Practices für die testgetriebenen Entwicklung mit JavaScript.
BASTA 2016 - Alternativen zu Visual-Studio-Testtools: Wann lohnt es sich auch...Marc Müller
Mittlerweile haben sich im VS-Umfeld immer mehr Nicht-MSTest-Testframeworks etabliert. Im Vortrag wollen wir auf mögliche Alternativen zu MSTest und Coded UI eingehen (z. B. Selenium, Ranorex, Protractor, …). Es geht dabei um Vor-/Nachteile, sinnvolle Szenarien und wie man es geschickt in die TFS-Werkzeugwelt integriert. Das Ziel ist dabei, das Beste aus beiden Welten zu bekommen.
Der Vortrag zeigt auf, wie Risikominimierung bei Änderungen im Oracle Datenbank-Umfeld betrieben werden kann. Es wird ein allgemeiner Überblick über mögliche Änderungen gegeben, sowie auf das Werkzeug Real Application Testing eingegangen. Zudem werden Stolperfallen und mögliche Probleme aufgezeigt. Diesen Beitrag präsentierte OPITZ CONSULTING Berater Simon Dickmeiß im Rahmen der Special DOAG Interest Group Database am 12. Oktober 2010 in Frankfurt/Kaiserei.
Features einer Applikation werden häufig implementiert, weil die Verantwortlichen vermuten, dass diese Funktionalitäten einen Mehrwert für die Benutzer der Applikation bieten. Je nach Umfang wird mehr oder weniger Geld investiert. Ohne weitere Unterstützung sind und bleiben es jedoch Vermutungen. Eine bessere Lösung bieten hier A/B-Tests. Features werden kostengünstig in einer oder mehreren Varianten umgesetzt und mit einer Kontrollimplementierung verglichen. Die Umsetzung, die sich als die beste herausstellt, wird überarbeitet und bleibt in der Applikation erhalten. Diese Vorgehensweise lässt sich sehr gut in node.js-Applikationen integrieren. Mithilfe von A/B-Tests können Sie Ihre Applikation an den Anforderungen Ihrer Benutzer ausrichten.
Die 2016 gegründete und inzwischen in der Eclipse Foundation beheimatete Initiative MicroProfile ist angetreten, die Lücke zwischen dem Enterprise-Java-Standard (Java EE aka EE4J) und den Praxisanforderungen Microservices-basierter Architekturen zu schließen. Das bestehende Momentum der JEE-Community als Hebel nutzen und organisch um den Bedarf der Microservices-Community ergänzen, so der Plan. Und dieser Plan scheint aufzugehen. In nur wenigen Monaten ist es gelungen, eine Reihe sinnvoller Microservices-relevanter APIs mit bestehenden Java-EE-7/8-APIs zu kombinieren und diese in regelmäßigen MicroProfile-Releases zu veröffentlichen. Egal ob Health Check, Metrics, Fault Tolerance, JWT Propagation, Configuration, Tracing oder Open API, MicroProfile scheint die richtigen Antworten – sprich APIs – im Gepäck zu haben. Die Session zeigt den aktuellen Stand von MicroProfile und demonstriert dessen Mehrwert anhand praktischer Beispiele.
A power workshop during JAX 2007 on advanced techniques of test-driven development. It deals with acceptance tests using FIT as well as with mock objects, GUI testing and Groovy as a testing language for Java.
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...GFU Cyrus AG
Kurzbeschreibung
Softwarequalität ist keine Spracheigenschaft. In jeder noch so guten Programmiersprache kann man schlechte Programme schreiben – sogar in Java. Herr Seekamp, Senior Consultant bei der GEDOPLAN GmbH, macht in diesem Vortrag anhand von Fallbeispielen aus seinen Projekten deutlich, was verständlichen und wartbaren Code ausmacht, welche Regeln man dafür beherzigen sollte und welche Analysewerkzeuge dabei unterstützen können.
Inhalt
Regeln für guten Java-Code
Statische Code-Analyse
Refactoring
Werkzeuge zur Sicherung der Qualität
Was jeder Java-Entwickler über Strings wissen sollteberndmueller
Strings sind wahrscheinlich der am meisten verwendete Datentyp in jeder
Java-Anwendung. Es ist daher nicht überraschend, dass JDK-Ingenieure
versuchen, Strings möglichst gut zu optimieren oder Bücher über
Performanz-Tuning und Testen dem Thema Strings ganze Kapitel widmen.
Jeder Entwickler sollte daher wissen, was Strings sind und wie sie
sinnvoll und effizient eingesetzt werden können.
Dieser Vortrag stellt JDK-Klassen vor, die mit und auf Strings
arbeiten, sowohl auf der API- aber auch auf der
Implementierungsebene. Wir beleuchten internte Strings und die für sie
verwendeten Speicherbereiche, sowie die noch recht unbekannte
"String-Deduplication"-Option des G1-Garbage-Collectors.
Die JSRs 342 (Java EE 7) und 344 (JPA 2.1) definieren Mandantenfähigkeit (multi-tenancy) explizit als eines der Ziele der JSRs. Im Herbst 2012 wurde entschieden, dieses Feature
aus Zeitgründen in die nachfolgenden Spezifikationen zu verschieben.
Muss man deshalb auf Mandantenfähigkeit in der Persistenzschicht verzichten?
Nein! Hibernate, EcliseLink und OpenJPA bieten jeweils proprietäre JPA-Erweiterungen zur Mandantenfähigkeit an, die in diesem Talk vorgestellt werden.
Class Loading ist uns aus dem EE Umfeld ausreichend bekannt - meinen wir.
Dieser Vertrag geht auf die Grundlagen des Class Loading ein und erweitert das W
issen
eines jeden Java-Entwicklers: Wie sieht das Format von Java-Klassen aus? Wie
werden Klassen geladen? Was ist ein Class Loader?
Seit Java 5 steht das Package java.lang.instrument zur
Verfügung, das die Instrumentierung von Klassen zum Ladezeitpunkt erlaubt.
Wir führen in die Möglichkeiten dieses Package ein.
Zum Abschluss zeigen wir, wie bereits geladene Klassen manipuliert werden können
Instrumentierung - Das Werkzeug der Werkzeugmacher - berndmueller
Das Package java.lang.instrument führt das Konzept eines Java-Agenten
ein, der Klassen beim Laden in die VM oder bereits geladenen Klassen
innerhalb der VM ändern kann. Man kann daher mit Standard-Java ohne
zusätzliche Bibliotheken Klassen zur Laufzeit ändern. Die Änderungen
sind beschränkt auf (neue) Methodenrümpfe und Konstanten. Das
Hinzufügen, Löschen oder Umbenennen von Methoden und Variablen
ist nicht erlaubt.
Dieser Vortrag führt die Konzepte der Instrumentierung
ein und zeigt, wie einfach das Ersetzen von Klassen zur
Laufzeit (Hot-Swap) mit Standard-Java ist.
Der Vortrag belegt diese "Einfachheit" durch kleinere Demos. Die
letze Demo zeigt, wie eine JRebel-Light-Variante mit Standard-Java
ohne externe Bibliotheken gebaut werden kann.
Was jeder Java-Entwickler über Strings wissen sollteberndmueller
Strings sind wahrscheinlich der am meisten verwendete Datentyp in jeder
Java-Anwendung. Es ist daher nicht überraschend, dass JDK-Ingenieure
versuchen, Strings möglichst gut zu optimieren oder Bücher über
Performanz-Tuning und Testen dem Thema Strings ganze Kapitel widmen.
Jeder Entwickler sollte daher wissen, was Strings sind und wie sie
sinnvoll und effizient eingesetzt werden können.
Dieser Vortrag stellt JDK-Klassen vor, die mit und auf Strings
arbeiten, sowohl auf der API- aber auch auf der
Implementierungsebene. Wir beleuchten internte Strings und die für sie
verwendeten Speicherbereiche, sowie die noch recht unbekannte
"String-Deduplication"-Option des G1-Garbage-Collectors.
Mit Java 9 ändert sich die interne Repräsentation von Strings.
Wir skizzieren diese Änderungen, die nach außen unsichtbar
bleiben.
6. Arquillian in der Selbstdarstellung
Auszug aus http://www.arquillian.org/
So you can rule your code. Not the bugs.
No more mocks.
No more container lifecycle and deployment hassles.
Just real tests!
Bernd M¨uller, JAX 2014, 15.5.2014 6/61
7. Kurzbeschreibung Arquillian
JBoss’ Test-Framework f¨ur Tests im Container
Dazu JUnit oder TestNG als Test-Runner
Und Test-Enricher, um Tests im Container laufen zu lassen
Und ShrinkWrap als Werkzeug f¨urs Packaging/Deployment
Prinzipieller Ablauf:
Test wird auf Client gepackt
Test und Laufzeiterweiterung wird im Container deployt
Test wird ausgef¨uhrt
Testergebnisse werden an Client zur¨uckgegeben
Test wird undeployt
Aktuell: Arquillian Core Version 1.1.4.Final, 31.3.2014
Bernd M¨uller, JAX 2014, 15.5.2014 7/61
8. Kurzbeschreibung Arquillian
JBoss’ Test-Framework f¨ur Tests im Container
Dazu JUnit oder TestNG als Test-Runner
Und Test-Enricher, um Tests im Container laufen zu lassen
Und ShrinkWrap als Werkzeug f¨urs Packaging/Deployment
Prinzipieller Ablauf:
Test wird auf Client gepackt
Test und Laufzeiterweiterung wird im Container deployt
Test wird ausgef¨uhrt
Testergebnisse werden an Client zur¨uckgegeben
Test wird undeployt
Aktuell: Arquillian Core Version 1.1.4.Final, 31.3.2014
Bernd M¨uller, JAX 2014, 15.5.2014 7/61
9. Kurzbeschreibung Arquillian
JBoss’ Test-Framework f¨ur Tests im Container
Dazu JUnit oder TestNG als Test-Runner
Und Test-Enricher, um Tests im Container laufen zu lassen
Und ShrinkWrap als Werkzeug f¨urs Packaging/Deployment
Prinzipieller Ablauf:
Test wird auf Client gepackt
Test und Laufzeiterweiterung wird im Container deployt
Test wird ausgef¨uhrt
Testergebnisse werden an Client zur¨uckgegeben
Test wird undeployt
Aktuell: Arquillian Core Version 1.1.4.Final, 31.3.2014
Bernd M¨uller, JAX 2014, 15.5.2014 7/61
13. Beispiel: Test-Runner und Deployment
@RunWith(Arquillian.class)
public class CustomerServiceTest {
@Deployment
public static Archive <?> createTestArchive () {
return ShrinkWrap.create(WebArchive.class , "test.war")
.addClasses(Customer.class , CustomerService .class)
.addAsResource("META -INF/persistence.xml")
. addAsWebInfResource (
new File("src/main/webapp/WEB -INF/beans.xml"));
}
...
Bernd M¨uller, JAX 2014, 15.5.2014 9/61
14. Beispiel: Test-Runner und Deployment
@RunWith(Arquillian.class)
public class CustomerServiceTest {
@Deployment
public static Archive <?> createTestArchive () {
return ShrinkWrap.create(WebArchive.class , "test.war")
.addClasses(Customer.class , CustomerService .class)
.addAsResource("META -INF/persistence.xml")
. addAsWebInfResource (
new File("src/main/webapp/WEB -INF/beans.xml"));
}
...
Bernd M¨uller, JAX 2014, 15.5.2014 9/61
15. ShrinkWrap
Werkzeug zur Erstellung/Manipulation von Java-Archiven
(JARs, WARs, EARs)
Fr¨uher eigenst¨andiges JBoss-Projekt, jetzt
Arquillian-Teilprojekt
Fluent-API zum Erstellen eines Archives,
f¨ur sogenannte Micro Deployment,
im Beispiel zwei Klassen und Deployment-Descriptoren
Bernd M¨uller, JAX 2014, 15.5.2014 10/61
21. Beispiel: Zu testende EJB
@Stateless
public class CustomerService {
@PersistenceContext
EntityManager em;
public void persist(Customer customer) {
em.persist(customer );
}
public long getNumberOfCustomers () {
return em. createNamedQuery (
"Customer. getNumberOfCustomers ",
Long.class ). getSingleResult ();
}
}
Bernd M¨uller, JAX 2014, 15.5.2014 12/61
22. Beispiel: Der Test
@RunWith(Arquillian.class)
public class CustomerServiceTest {
@Deployment
public static Archive <?> createTestArchive () { ...}
@Inject
CustomerService customerService ;
@Test
public void testPersist () {
Customer customer = new Customer("Firstname", "Lastname"
assertNull(customer.getId ()); // ueberfluessig
customerService .persist(customer );
assertNotNull(customer.getId ());
}
Bernd M¨uller, JAX 2014, 15.5.2014 13/61
23. Beispiel: Alternativer Test
@Test
public void testPersist2 () {
Customer customer = new Customer("Firstname", "Lastname"
Long before = customerService . getNumberOfCustomers ();
customerService .persist(customer );
Long after= customerService . getNumberOfCustomers ();
assertTrue("Muss ein Customer mehr sein",
before + 1 == after );
}
Bernd M¨uller, JAX 2014, 15.5.2014 14/61
24. Beispiel: 3. Alternative mit Persistenzkontext
@RunWith(Arquillian.class)
public class CustomerServiceTest {
@PersistenceContext
EntityManager em;
@Test
public void testPersist3 () {
Customer customer = new Customer("Firstname", "Lastname"
Long before = em. createNamedQuery (
"Customer. getNumberOfCustomers ", Long.class)
. getSingleResult ();
customerService .persist(customer );
Long after= em. createNamedQuery (
"Customer. getNumberOfCustomers ", Long.class)
. getSingleResult ();
assertTrue("Muss ein Customer mehr sein",
before + 1 == after );
}
25. Beispiel: 3. Alternative mit Persistenzkontext
@RunWith(Arquillian.class)
public class CustomerServiceTest {
@PersistenceContext
EntityManager em;
@Test
public void testPersist3 () {
Customer customer = new Customer("Firstname", "Lastname"
Long before = em. createNamedQuery (
"Customer. getNumberOfCustomers ", Long.class)
. getSingleResult ();
customerService .persist(customer );
Long after= em. createNamedQuery (
"Customer. getNumberOfCustomers ", Long.class)
. getSingleResult ();
assertTrue("Muss ein Customer mehr sein",
before + 1 == after );
}
Existiert, da Test in Container
29. Arquillian Drone
Arquillian-Erweiterung f¨ur funktionale Tests
Basiert auf Selenium
Selenium-Slogan: Selenium automates browsers
WebDriver: M¨oglichkeit zur Browser-Steuerung, u.a. mit Java
API
WebDriver API das einzig neu zu lernende
¨Anderung des prinzipiellen Ablaufs: Tests auf Client
Kombination Client und Server m¨oglich
Version aktuell: 1.3.0.Final
Version 2.0.0.Alpha1 mit ¨uberarbeitetem/entschlacktem API
in Entwicklung (von uns nicht verwendet)
Bernd M¨uller, JAX 2014, 15.5.2014 19/61
30. Die n¨otigen Erweiterungen/¨Anderungen
@RunWith(Arquillian.class)
public class DroneUsedTest {
@ArquillianResource
URL deploymentURL;
@Drone
WebDriver driver;
@Deployment(testable = false)
public static Archive <?> createTestArchive () { ...}
@ArquillianResource: das URL des Deployments
@Drone: das WebDriver oder DefaultSelenium API
Keine Tests im Server
Bernd M¨uller, JAX 2014, 15.5.2014 20/61
31. Die n¨otigen Erweiterungen/¨Anderungen
@RunWith(Arquillian.class)
public class DroneUsedTest {
@ArquillianResource
URL deploymentURL;
@Drone
WebDriver driver;
@Deployment(testable = false)
public static Archive <?> createTestArchive () { ...}
@ArquillianResource: das URL des Deployments
@Drone: das WebDriver oder DefaultSelenium API
Keine Tests im Server
Bernd M¨uller, JAX 2014, 15.5.2014 20/61
32. Die n¨otigen Erweiterungen/¨Anderungen
@RunWith(Arquillian.class)
public class DroneUsedTest {
@ArquillianResource
URL deploymentURL;
@Drone
WebDriver driver;
@Deployment(testable = false)
public static Archive <?> createTestArchive () { ...}
@ArquillianResource: das URL des Deployments
@Drone: das WebDriver oder DefaultSelenium API
Keine Tests im Server
Bernd M¨uller, JAX 2014, 15.5.2014 20/61
33. Die n¨otigen Erweiterungen/¨Anderungen
@RunWith(Arquillian.class)
public class DroneUsedTest {
@ArquillianResource
URL deploymentURL;
@Drone
WebDriver driver;
@Deployment(testable = false)
public static Archive <?> createTestArchive () { ...}
@ArquillianResource: das URL des Deployments
@Drone: das WebDriver oder DefaultSelenium API
Keine Tests im Server
Bernd M¨uller, JAX 2014, 15.5.2014 20/61
34. Falls nicht nur Client-Tests
@RunWith(Arquillian.class)
public class DroneUsedTest {
@Drone
WebDriver driver;
@Deployment
public static Archive <?> createTestArchive () { ... }
@Test
@RunAsClient
@InSequence (1)
public void createCustomer( @ArquillianResource URL url) {
@Test // im Server
@InSequence (2)
public void countCustomers () { ... }
Auch Tests im Server m¨oglich, daher Unterscheidung
Reihenfolge der Tests (Widerspruch zur reinen Lehre?)
35. Falls nicht nur Client-Tests
@RunWith(Arquillian.class)
public class DroneUsedTest {
@Drone
WebDriver driver;
@Deployment
public static Archive <?> createTestArchive () { ... }
@Test
@RunAsClient
@InSequence (1)
public void createCustomer( @ArquillianResource URL url) {
@Test // im Server
@InSequence (2)
public void countCustomers () { ... }
Auch Tests im Server m¨oglich, daher Unterscheidung
Reihenfolge der Tests (Widerspruch zur reinen Lehre?)
36. Falls nicht nur Client-Tests
@RunWith(Arquillian.class)
public class DroneUsedTest {
@Drone
WebDriver driver;
@Deployment
public static Archive <?> createTestArchive () { ... }
@Test
@RunAsClient
@InSequence (1)
public void createCustomer( @ArquillianResource URL url) {
@Test // im Server
@InSequence (2)
public void countCustomers () { ... }
Auch Tests im Server m¨oglich, daher Unterscheidung
Reihenfolge der Tests (Widerspruch zur reinen Lehre?)
37. Versteht Arquillian Maven’s POM ?
Nein, aber ShrinkWrap
Es gibt einen ShrinkWrap-Resolver, der Maven und Gradle
unterst¨utzt
Jetzt Beispiel:
JSF-Seite zur Kundenneuanlage
Navigation zu Kundenanlage-Erfolgreich-Seite, falls kein Fehler
Test, ob Navigation funktioniert
Test, ob Daten im Server
Bernd M¨uller, JAX 2014, 15.5.2014 22/61
38. Versteht Arquillian Maven’s POM ?
Nein, aber ShrinkWrap
Es gibt einen ShrinkWrap-Resolver, der Maven und Gradle
unterst¨utzt
Jetzt Beispiel:
JSF-Seite zur Kundenneuanlage
Navigation zu Kundenanlage-Erfolgreich-Seite, falls kein Fehler
Test, ob Navigation funktioniert
Test, ob Daten im Server
Bernd M¨uller, JAX 2014, 15.5.2014 22/61
39. Das (fast) komplette Beispiel (Teil 1)
@RunWith(Arquillian.class)
public class CreateCustomerTest {
private static final String
WEBAPP_SRC = "src/main/webapp";
@Drone
WebDriver driver;
@Inject
CustomerRepository customerRepository ;
Bernd M¨uller, JAX 2014, 15.5.2014 23/61
42. Das (fast) komplette Beispiel (Teil 4)
@Test // im Server
@InSequence (2)
public void countCustomers () {
assertEquals (1, customerRepository .getCustomers (). size ());
}
Bernd M¨uller, JAX 2014, 15.5.2014 26/61
43. @Drone im Detail
Injection in Klasse
Class-Based Life-Cycle
Analog zu @BeforeClass / @AfterClass
Injection in Methode
Method-based Life-Cycle
Analog zu @Before / @After
Mehrere Injektionen ¨uber Qualifier m¨oglich
Verschiedene Driver: WebDriver, FirefoxDriver, ChromeDriver,
InternetExplorerDriver, SafariDriver
Durch Selenium Unterst¨utzung von XPath-Ausdr¨ucken in
Test-Asserts
Bernd M¨uller, JAX 2014, 15.5.2014 27/61
44. @Drone im Detail
Injection in Klasse
Class-Based Life-Cycle
Analog zu @BeforeClass / @AfterClass
Injection in Methode
Method-based Life-Cycle
Analog zu @Before / @After
Mehrere Injektionen ¨uber Qualifier m¨oglich
Verschiedene Driver: WebDriver, FirefoxDriver, ChromeDriver,
InternetExplorerDriver, SafariDriver
Durch Selenium Unterst¨utzung von XPath-Ausdr¨ucken in
Test-Asserts
Bernd M¨uller, JAX 2014, 15.5.2014 27/61
45. @Drone im Detail
Injection in Klasse
Class-Based Life-Cycle
Analog zu @BeforeClass / @AfterClass
Injection in Methode
Method-based Life-Cycle
Analog zu @Before / @After
Mehrere Injektionen ¨uber Qualifier m¨oglich
Verschiedene Driver: WebDriver, FirefoxDriver, ChromeDriver,
InternetExplorerDriver, SafariDriver
Durch Selenium Unterst¨utzung von XPath-Ausdr¨ucken in
Test-Asserts
Bernd M¨uller, JAX 2014, 15.5.2014 27/61
46. @Drone im Detail
Injection in Klasse
Class-Based Life-Cycle
Analog zu @BeforeClass / @AfterClass
Injection in Methode
Method-based Life-Cycle
Analog zu @Before / @After
Mehrere Injektionen ¨uber Qualifier m¨oglich
Verschiedene Driver: WebDriver, FirefoxDriver, ChromeDriver,
InternetExplorerDriver, SafariDriver
Durch Selenium Unterst¨utzung von XPath-Ausdr¨ucken in
Test-Asserts
Bernd M¨uller, JAX 2014, 15.5.2014 27/61
47. @Drone im Detail
Injection in Klasse
Class-Based Life-Cycle
Analog zu @BeforeClass / @AfterClass
Injection in Methode
Method-based Life-Cycle
Analog zu @Before / @After
Mehrere Injektionen ¨uber Qualifier m¨oglich
Verschiedene Driver: WebDriver, FirefoxDriver, ChromeDriver,
InternetExplorerDriver, SafariDriver
Durch Selenium Unterst¨utzung von XPath-Ausdr¨ucken in
Test-Asserts
Bernd M¨uller, JAX 2014, 15.5.2014 27/61
49. Arquillian Warp
Client-seitige Tests mit Zusicherungen/Pr¨ufung von
Server-seitiger Logik und Zustand
Keine weiteren Bibliotheken, wie etwa Selenium, ben¨otigt
Kein UI ben¨otigt (Headless)
Speziell f¨ur Servlets und Servlet-basierte Systeme gemacht
Im Augenblick nur Servlets direkt und JSF 2 unterst¨utzt
Arquillian Spring Framework Extension enth¨alt Warp Spring
MVC Extension (nicht betrachtet)
Offizieller Nachfolger von JSFUnit
Aktuell: Version 1.0.0.Alpha7, 11.3.2014
Bernd M¨uller, JAX 2014, 15.5.2014 29/61
50. Die prinzipielle Idee hinter WARP
Initiierung eines HTTP-Requests auf Client-Seite z.B. mit
WebDriver
Im selben Request-Zyklus Ausf¨uhren von Server-seitigen Tests
im Container
Dazu:
Initiieren des Request ¨uber Interface Activity
Inspizieren des Server-Zustands ¨uber Klasse Inspection
Aktivity mit perform()-Methode
Inspection mit JUnit/TestNG-Tests zum
”
richtigen“ Zeitpunkt
optional: Gruppieren und Observieren von Requests
Bernd M¨uller, JAX 2014, 15.5.2014 30/61
51. Die n¨otigen Erweiterungen/¨Anderungen
@WarpTest f¨ur Test-Klasse
@RunAsClient f¨ur Test-Klasse
@BeforeServlet, @AfterServlet f¨ur Servlet-Tests
@BeforePhase, @AfterPhase (6 Phasen) f¨ur JSF-Tests
Im Folgenden 3 Beispiele
Existieren die richtigen Beans?
Validierung
Navigation
Bernd M¨uller, JAX 2014, 15.5.2014 31/61
52. Die n¨otigen Erweiterungen/¨Anderungen
@WarpTest f¨ur Test-Klasse
@RunAsClient f¨ur Test-Klasse
@BeforeServlet, @AfterServlet f¨ur Servlet-Tests
@BeforePhase, @AfterPhase (6 Phasen) f¨ur JSF-Tests
Im Folgenden 3 Beispiele
Existieren die richtigen Beans?
Validierung
Navigation
Bernd M¨uller, JAX 2014, 15.5.2014 31/61
53. Die n¨otigen Erweiterungen/¨Anderungen
@WarpTest f¨ur Test-Klasse
@RunAsClient f¨ur Test-Klasse
@BeforeServlet, @AfterServlet f¨ur Servlet-Tests
@BeforePhase, @AfterPhase (6 Phasen) f¨ur JSF-Tests
Im Folgenden 3 Beispiele
Existieren die richtigen Beans?
Validierung
Navigation
Bernd M¨uller, JAX 2014, 15.5.2014 31/61
54. Die n¨otigen Erweiterungen/¨Anderungen
@WarpTest f¨ur Test-Klasse
@RunAsClient f¨ur Test-Klasse
@BeforeServlet, @AfterServlet f¨ur Servlet-Tests
@BeforePhase, @AfterPhase (6 Phasen) f¨ur JSF-Tests
Im Folgenden 3 Beispiele
Existieren die richtigen Beans?
Validierung
Navigation
Bernd M¨uller, JAX 2014, 15.5.2014 31/61
55. 1. Beispiel: Existieren die richtigen Beans?
Weld-Manual: Einloggen ¨uber JSF-View-Bean
Pr¨ufen auf Benutzername/Passwort ¨uber EJB
CDI-produzierte Customer-Instanz im Session-Scope
Die Existenz dieser Instanz soll ¨uberpr¨uft werden
Bernd M¨uller, JAX 2014, 15.5.2014 32/61
60. Struktur zur Verdeutlichung
Warp
.initiate(new Activity () {
...
})
.inspect(new Inspection () {
...
})
Aktivit¨at auf dem Client initiieren
Inspektion auf dem Server ausf¨uhren
Bernd M¨uller, JAX 2014, 15.5.2014 37/61
65. 2. Beispiel: Validierung
Credentials werden falsch eingegeben (zu kurz)
JSF erzeugt in Phase 3 FacesMessage-Instanzen
Pr¨ufen vor und nach Phase 3, ob Messages existieren oder
nicht
Bernd M¨uller, JAX 2014, 15.5.2014 40/61
66. Klasse Credentials
@Named
@RequestScoped
public class Credentials {
@NotNull
@Size(min = 6, max = 30)
private String email;
@NotNull
@Size(min = 6, max = 20)
private String password;
...
Deutsche Fehlermeldung f¨ur @Size: ”muss zwischen 6 ...
Bernd M¨uller, JAX 2014, 15.5.2014 41/61
72. 3. Beispiel: Navigation mit Redirect
Einfache JSF-Seiten mit Navigation und Redirect
Noch nicht erw¨ahntes WARP-Feature: Gruppieren von
Inspektionen auf Server basierend auf Request-Folge
Pr¨ufen der View-Id nach Restore-View-Phase
Bernd M¨uller, JAX 2014, 15.5.2014 46/61
73. JSF-Seiten mit Navigation
redirect-source.xhtml
<h:form id="form">
Seite verwendet #{ redirectSourceBean .name} <br />
<h:commandButton id="redirect"
action=" redirect-target ? faces-redirect=true"
value="Redirect to ’redirect-target .jsf ’" />
</h:form >
redirect-target.xhtml
<h:form id="form">
Seite verwendet #{ redirectTargetBean .name} />
</h:form >
Bernd M¨uller, JAX 2014, 15.5.2014 47/61
79. Auswahl des richtigen Request
Da mehrere Request getriggert werden k¨onnen, muss man den
richtigen (den, den man observieren will) ausw¨ahlen
Dazu das HttpRequestFilter-Interface
Damit spezifiziert man den zu verwendenden HttpRequest der
aktuellen Gruppe
Bernd M¨uller, JAX 2014, 15.5.2014 53/61
80. Aus
”
Dokumentation“
import static org.jboss.arquillian.warp
.client.filter.http.HttpFilters.request;
// will accept only requests for HTML
... group ()
.observe(request (). uri (). contains(".html"))
// will accept only REST requests for JSON
... group ()
.observe(request (). header ()
.containsValue("Accept", "application/json"))
// will accept only POST requests
... group ()
.observe(request (). method (). equal(POST ))
Bernd M¨uller, JAX 2014, 15.5.2014 54/61
81. Was kann alles injiziert werden?
Injizierbar ¨uber @ArquillianResource
Servlet-Ressourcen
ServletRequest or HttpServletRequest
ServletResponse or HttpServletResponse
Bernd M¨uller, JAX 2014, 15.5.2014 55/61
83. Wo Licht ist, ist auch Schatten
Sehr schlechte Doku
Noch viele/schwere Fehler
Scheinbar Ein-Mann-Projekt: Luk´aˇs Fryˇc (Project Lead)
Bernd M¨uller, JAX 2014, 15.5.2014 57/61