GEB UND GRAPHENE IM VERGLEICH. Stefan Hildebrandt

Ähnliche Dokumente
Web-Anwendungen mit Arquillian testen

Webtests und JMeter. Technologien: Überblick Funktionale Tests: Simplelenium Performance Messungen: JMeter Projekt Setup: Gradle, Jenkins

Christian Meder inovex. Sauberes Grün QS für Android

Andreas Hartmann, Stephan Müller adesso AG. JSF Testing: Tools und Technics

Spock und Geb (WebDriver) Wie können freie Werkzeuge zum strukturierten Testen von Web-Applicationen eingesetzt werden?

Andreas Hartmann, Stephan Müller adesso AG. JSF Testing: Tools and Technics

Web-Testen mit JUnit und HttpUnit. Kai Schmitz-Hofbauer Lehrstuhl für Software-Technik Ruhr-Universität Bochum

Webentwicklung mit Vaadin 7. Theoretische und praktische Einführung in Vaadin 7. Christian Dresen, Michael Gerdes, Sergej Schumilo

Testgetriebenes Ajax. Johannes Link unabhängiger Softwarecoach Marco Klemm andrena objects ag

Moderne Web- Anwendungen mit

Automatisches Exploratives Testen von Webanwendungen

Geister, Gurken und Halbmetalle. Tools für Web-UI-Acceptance-Tests. Malte Clasen

12. Ausblick: Test von Web-Applikationen

Automatisiertes Testen von Java EE-Applikationen mit Arquillian

Erfahrungen und Erkenntnisse. Klaus Richarz, HBT GmbH

Der EMF-generierte Code. 7. November 2012

Spock und Geb: Übersichtlich und nachvollziehbar Testen für alle!

Coach für agile Softwareentwicklung

OpenSource Individualentwicklungsplattform für weborientierte/mobile Anwendungen

magazin Avatar 2.0 JCache JavaFX auf Rädern NewSQL mit VoltDB Java Mag JavaScript für die Java Virtual Machine 26

Struts 2 Das Imperium schlägt zurück?

Testen von webbasierten Benutzeroberflächen

Moderne Web-Anwendungen mit Vaadin

Praktikum Datenbanksysteme. Ho Ngoc Duc IFIS - Universität zu Lübeck

Asynchrone Webservices mit Axis 1.x in Java

Ein Jahr mit dem. Play! Framework FLAVIA IT. Dmitrij Funkner & Jonas Kilian. Quelle:

AJAX Implementierung mit Joomla!

JUnit. Unit testing unter Java

Schritt 4: Hallo Enterprise Bean

Legacy Web-Apps mit AngularJS pimpen

Javakurs FSS Lehrstuhl Stuckenschmidt. Tag 3 - Objektorientierung

aformatik Training & Consulting GmbH & Co. KG Eine Einführung in das automatisierte Testen mit dem Robot-Framework Thomas Gauss

Komponentenorientierte Software-Entwicklung. Seite 1 / 42

Swp08-6 Verantwortliche: Yundensuren, Baigalmaa. Testkonzept

Application Frameworks

Entwicklung von effizienten UI-basierten Akzeptanztests für Webanwendungen

Die Alternative zum Web-Form Modell

RAP vs. GWT vs. GAE/J + jquery. Web Technologien im Verlgeich

Höhere Programmierkonzepte Testklausur

JUnit - Test Driven Development. Bernhard Frey, Thorsten Stratmann, Jackson Takam, Michel Müller 1

Anforderungsgetriebene Webentwicklung mit Grails:

Einstieg in die Informatik mit Java

Themen. Web Service - Clients. Kommunikation zw. Web Services

Java - Programmierung - Objektorientierte Programmierung 1

JavaFX8 - JumpStart - JUGCH. file:///d:/workspace/kurs-java8/doc/javafx-jumpstart.html#1 1/128

4. Servlets Ein kleiner Einstieg. Kurze Java Historie. Erinnerung: Internet Anwendungen. Konzept eines Seitenaufrufs

EJB3.0 Unit-Testing Reloaded

Bean-Mapping mit MapStruct

JAX-RS 2.0 REST mit Java EE 7

Gebundene Typparameter

Typumwandlungen bei Referenztypen

Java-Schulung Grundlagen

Reflection. Arthur Zaczek. Nov 2014

Auszug aus JAX-WS Folien

Vorbereitungen Download. AVO-Übung 6. Beispiel. Slice. Varianten u.a. für Linux, Windows, OS X ICE-Dokumentation ICE-Binaries (inkl.

Algorithmen und Datenstrukturen

Automatisiertes Testen von Webanwendungen mit Selenium und Watij Sebastian Westkamp. Seminar Ausgewählte Themen des Softwareengineering

SemTalk Services. SemTalk UserMeeting

Beispiel für überladene Methode

JGiven: Ein entwicklerfreundliches BDD-Framework für Java

Web-Anwendungsentwicklung mit dem Delivery Server

Wie ich lernte die API zu lieben. 19. März sic[!]sec GmbH Industriestraße Gröbenzell

Handbuch für die Erweiterbarkeit

Testen und Debuggen von Webanwendungen

Android Testautomatisierung mit dem Framework Robotium

Fortgeschrittenes Programmieren mit Java. Test Driven Development

DataTables LDAP Service usage Guide

Benutzerauthentifizierung und Zugriffsschutz mit JAAS

Programmierprojekt. Anne0e Bieniusa Sommersemester 2014

Unit Tests mit Junit 4. Dario Borchers

Groovy und CouchDB. Ein traumhaftes Paar. Thomas Westphal

CamelCaseCon 2011 Vortrag von Stefan Glase am Statische Code-Analyse für Groovy & Grails mit CodeNarc

Workshop Java Webentwicklung Tapestry. Ulrich Stärk

Übungsaufgabe Transaktion als Middleware

Java Reflection. Andreas Lochbihler. 15. Mai Lehrstuhl Programmierparadigmen Universität Karlsruhe

Monaden in anderen Programmiersprachen

Neue Wege mit Contao 4

informatik ag IT mit klarer Linie S i e b e l O p e n U I

JBoss Seam. Ein JEE 5 Webframework. Jörg Wüthrich Infopoint, 4. Februar 2009

Dirk Weil GEDOPLAN GmbH. Feige sein! Testen im EE-Umfeld

7. Schnittstellen Grundlagen zu Schnittstellen. 7. Schnittstellen

Java Reflection. Meta-Programmierung mit der java.lang.reflection API. Prof. Dr. Nikolaus Wulff

CodedUI Gut vorbereitet ist halb getestet. Nico Orschel, AIT, DE Marc Müller, 4tecture, CH

Praktisches API-Design

Tipps und Hinweise zum Bezug der Beitragssatzdatei V5.0

The app the crashes, before the breakpoint is reached: Code to the event:

Erfahrungsbericht zu JBoss SOA Platform 6 Tech Talk 2013, 17. Oktober 2013, Bern

Java: Vererbung. Teil 3: super()

Apache Wicket Web Framework: Reinvented the Wheel? Stärken und Schwächen: Ein Erfahrungsbericht aus drei Projekten

Überleben im Funkloch

Prozessautomatisierung mit BPMN 2.0 und Java.

Zend Framework MVC Applikationen testen

Programmieren von Webinformationssystemen


Mobile und Verteilte Datenbanken

Wir bringen Ihre Notes/Domino Anwendungen sicher ins Web , Bilster Berg Drive Resort Michael Steinhoff, agentbase AG.

RESTful Services mit Java EE

Auffrischung jquery. jquery Mobile. Marco Francke I

Testen von graphischen Benutzeroberflächen. 24. Juni 2015

Transkript:

GEB UND GRAPHENE IM VERGLEICH Stefan Hildebrandt / @hildebrandttk

FOLIEN ALS HTML-PRÄSENTATION 0

TESTEN VON WEBANWENDUNGEN Akzeptanztests Funktionale Tests Unit-Tests von Komponenten Last- / Kapazitätstests

BEISPIELE 1. Google Suche 2. Java EE 7 Petclinic Von Thomas Wöhlke auf github Fachlichkeit: Tierärzte mit Spezialisierungen Haustiere mit Arten Besitzer haben Haustieren Besitzer kommen mit Haustieren zu einem Besuch Fork mit Testerweiterungen auf github

GEMEINSAME BASIS SELENIUM

SELENIUM HISTORIE Selenium RC: 2004 WebDriver: 2006 Merge zu Selenium 2: 2008

SELENIUM 2 BINDINGS java C# phyton ruby php perl javascript

SELENIUM 2 BROWSERUNTERSTÜTZUNG Firefox Internet Explorer Chrome Safari HTMLUnit Phantom JS ios Android

GEB (PRONOUNCED JEB ) Hint: "gebish" für Suchen WebDriver jquery Selection-API Groovy JUnit, TestNG oder Spock Release 0.4 vor 4,5 Jahren, aktuell: 0.10.0 gradleware-entwickler

ARQUILLIAN Von JBoss für Tests ihres AS und Frameworks entwickelt Deployment des Testobjekts in einen EE Container (CDI, Servlet, Appserver) Tests im Container oder als Client Injection von EE-Komponenten in die Tests JUnit und TestNG

ARQUILLIAN DRONE & GRAPHENE Graphene & Drone sind Arquillian Extensions Aus dem JBoss Umfeld Drone ca. 3,5 Jahren Graphene ca. 3 Jahre

BEISPIEL VON DER SELENIUM HOMEPAGE: public class Selenium2Example { public static void main(string[] args) { WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com"); WebElement element = driver.findelement(by.name("q")); element.sendkeys("cheese!"); element.submit(); System.out.println("Page title is: " + driver.gettitle()); (new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() { public Boolean apply(webdriver d) { return d.gettitle().tolowercase().startswith("cheese!"); ); System.out.println("Page title is: " + driver.gettitle()); driver.quit();

LESBARKEIT

WIEDERVERWENDBARKEIT

SELENIUM PAGE OBJECTS Seitenstruktur Bedienlogik Fluent API Führung bei der Testerstellung per Code Completion Synchron

PAGE public class FindOwnersPage extends AbstractPage<FindOwnersPage> { @FindBy(id = "findownersform:search") private WebElement search; @FindBy(css = "input[type='text']") private WebElement nameinput;... public FindOwnersResultPage searchforowner(string name) { nameinput.clear(); nameinput.sendkeys(name); search.click(); return new FindOwnersResultPage().waitForIsLoaded();

TEST @Test public void testopennewownerpagefromownerslist() { final FindOwnersPage findownerspage = new FindOwnersPage(); findownerspage.get(); findownerspage.assertisloaded().searchforowner("").assertisloaded().clicknewowner().assertpageisloaded();

TECHNISCHE OBERKLASSE public abstract class AbstractPage<T extends AbstractPage<T>> extends Loadable private static WebDriver driver; protected AbstractPage() { driver = WebDriverHolder.getDriver(); PageFactory.initElements(driver, this); @Override protected final void load() { getdriver().get(base_url + pageurl); @Override protected void isloaded() throws Error { asserttrue(getdriver().getcurrenturl().endswith(pageurl));

public class WebDriverHolder { private static WebDriver driver; HILFSKLASSE public static WebDriver getdriver() { if (driver == null) {... driver = new FirefoxDriver(profile); return driver; public static void closedriver() { if (driver!= null) { driver.quit(); driver = null;

FAZIT Wiederverwendbarkeit Fluent-API mit Problemen Eigene Framework-Klassen notwendig Manuelles Setup des Browsers

ARQUILLIAN GRAPHENE INKL. DRONE

ARQUILLIAN DRONE WebDriver Lifecycle inkl. Konfiguration WebDriver Injection in den Test

@RunWith(Arquillian.class) public class TestDroneOnly { @Drone private WebDriver driver; @ArquillianResource private URL deploymenturl; WEBDRIVER INJECTION @Test public void testopeninghomepage() { driver.get(deploymenturl + "/hello.jsf"); assertequals("java EE 7 Petclinic", driver.gettitle());

KONFIGURATION IN ARQUILLIAN.XML <arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arqui <extension qualifier="webdriver"> <property name="browser">firefox</property> <!--<property name="browser">phantomjs</property>--> <!--<property name="browser">chrome</property>--> </extension> <extension qualifier="drone"> <property name="instantiationtimeoutinseconds">120</property> </extension> </arquillian>

ARQUILLIAN GRAPHENE

PAGE OBJECT @Location("findOwners.jsf") public class FindOwnersPage<T extends FindOwnersPage<T>> extends AbstractFindO @Page private FindOwnersResultPage findownersresultpage; public FindOwnersResultPage searchforowner(string name) { searchforownerinternal(name); return findownersresultpage;

TECHNISCH NOTWENDIGE FACHLICHE OBERKLASSE public abstract class AbstractFindOwnersPage<T extends AbstractFindOwnersPage< @FindBy(css = "input[type='text']") private WebElement nameinput; @Page private NewOwnerPage newownerpage;... public NewOwnerPage opennewownerspage() { addnewownerlink.click(); return newownerpage; protected void searchforownerinternal(string name) { nameinput.clear(); nameinput.sendkeys(name); search.click();

TEST @Test public void testopennewownerpagefromownerslist() { goto(findownerspage.class).assertisloaded().searchforowner("").assertisloaded().opennewownerspage().assertisloaded();

FAZIT Browser Lifecycle Page und WebElement Injection echte jquery Selector-API Direkte Verwendung der Selenium-API Injection von Unterklasse in Oberklasse nicht möglich

GEB

GEB PAGE class FindOwnersPage extends AbstractPetClinicPage { static url ='findowners.jsf' static at = { pageheader.present static content = { pageheader { $('h2', id: 'findowners') nameinput { $('input', type:'text') searchbutton { $('input', type: 'submit') addnewownertype { $('a', text: 'Add New Owner') FindOwnersResultPage searchforowner(string name){ nameinput.value(name) searchbutton.click() return waitforatpage(findownersresultpage)

TECHNISCHE UND FACHLICHE OBERKLASSE abstract class AbstractPetClinicPage extends Page { static content = {... findownerslink { $("a", text: "Find Owners")... FindOwnersPage tofindowners() { findownerslink.click() return waitforatpage(findownerspage); def <T extends Page> T waitforatpage(class<t> targetpageclass){ waitfor { browser.isat(targetpageclass) return browser.page as T;

@RunWith(Arquillian) class Test04Owner extends GebTest {... GEB TEST @Test public void testopennewownerpagefromownerslist() { to(hellopage).tofindowners().searchforowner('').opennewownerspage()

KONFIGURATION: GEBCONFIG.GROOVY baseurl='http://localhost:8080/petclinic-all/' driver = { def FirefoxProfile profile = new FirefoxProfile();... def ffdriver = new FirefoxDriver(profile) ffdriver.manage().window().maximize() return ffdriver waiting { timeout = 10 retryinterval = 0.5 presets { test { timeout = 3 retryinterval = 0.5

FAZIT Page und Browser Lifecyle an jquery angelehnte Selector-API Auch Selenium-API verwendbar Warten auf Page in Page fehlt

KOMPONENTEN Natürliche Komponenten Tabellen inkl. Zugriff auf einzelne Zeilen und Spalten Menüs Gleichartige Validierung, Fehlermeldungen,... Wizzards 3. Party Komponenten Komplexe Inputs (Kalender, Vorschlagsboxen,...) jquery ui, PrimeFaces, RichFaces,...

GRAPHENE PAGE FRAGMENTS Verwendung der selben Annotationen wie in der Page Keine Oberklasse @Root für die Basis Verwendung in der Page wie WebElement

public class OwnersTableFragment { @Root private WebElement root; GRAPHENE PAGE FRAGMENT @FindBy(css = "tbody.rf-dt-b > tr") private List<OwnersTableRowFragment> rows; public List<OwnersTableRowFragment> findrowsbyparameters(string firstname, String city, St List<OwnersTableRowFragment> matchingrows = new ArrayList<>(); for (OwnersTableRowFragment row : rows) { if (row.getlastname().equals(lastname) && row.getfirstname().equals(f && row.getaddress().equals(address) && row.getcity().equals(city) matchingrows.add(row); return matchingrows;

GRAPHENE PAGE FRAGMENTS FÜR 3. PARTY- FRAMEWORKS Framework Verfügbarkeit von Page Fragments Richfaces 4.5 Final Richfaces 5.0 Alpha3 Primefaces jquery UI

GEB MODULE geb.module analog zu geb.page Verwendung im static-bereich mit dem Schlüsselwort: module Unterstützung von Listen mit modulelist petbirthdateinput { module RichFacesCalendar, $('#editpetform\\:petbirthdate') rowsintable { modulelist OwnersTableRowModule, $('table.table tbody tr')

GEB MODULE class OwnersTableRowModule extends Module { static content = { cell(required: false ) { $("td", it) editownerlink(required: false ) { cell(0).find('a') name(required: false ) { cell(0).text() address(required: false ) { cell(1).text() city(required: false ) { cell(2).text() telephone(required: false ) { cell(3).text() ShowOwnerPage opendetails() { editownerlink.click() waitfor { browser.isat(showownerpage) return browser.page as ShowOwnerPage

GEB KOMPONENTENBIBLIOTHEKEN FÜR 3. PARTY Einfach möglich Existieren nicht (öffentlich)

AJAX

GRAPHENE REQUEST GUARDS Blockiert Test für eine konfigurierte Wartezeit Wirft eine Exception falls kein Request mit Response verzeichnet wurde guardhttp(buttonwhichmakesfullpagerefresh).click(); guardajax(buttonwhichmakesajaxrequest).click(); guardnorequest(buttonwhichmakesnorequest).click();

GRAPHENE 2 WAITINGS Fluent API Referenzierung von WebElements button.click(); waitgui().withmessage("popup should be opened after clicking on that button!").until().element(popuppanel).is().visible();

GEB WAITINGSUPPORT durch Closure sehr flexibel Konfiguration von Defaults in GebConfig.groovy waitfor { waitfor(10) { waitfor(10, 0.5) { waitfor("quick") { waitfor { theresultdiv.present

GEB LAZY CONTENT class DynamicPage extends Page { static content = { dynamicallyadded(wait: true) { $("p.dynamic") Browser.drive { to DynamicPage assert dynamicallyadded.text() == "I'm here now" Es wird beim Zugriff automatisch gewartet Timing kann konfiguriert werden

VERGLEICH PROGRAMMIERSTIEL & LESBARKEIT

GRAPHENE & DRONE Annotation für Java EE Entwickler gewohnt Verbessertes Selektor-Api Größtenteils transparentes Wireing Waiting API ermöglicht Referenzierung von Feldern WebDriver-API ist in die Jahre gekommen

GEB Transparentes Wireing Verbesserte Selektor-Api Konfiguration z.b. für wait() Groovy-Power-Assertions groovy groovy static-bereich teilweise untypisiert

KOMBINATIONSMÖGLICHKEI Arquillian Arquillian Suite Deployments Arquillian Warp Cucumber / fit ArquillianCucumber jmeter

TESTAUSFÜHRUNG MIT ARQUILLIAN

ARQUILLIAN GRAPHENE Arquillian-Extension Keine Interferenzen mit Arquillian-Suite

GEB Kein eigener Testrunner Keine Interferenzen mit Arquillian-Suite

ARQUILLIAN GRAPHENE MIT CUCUMBER Ohne Arquillian-Testrunner nicht lauffähig Page Injection mit ArquillianCucumber fehlerhaft

class GebStepDefinitions { String gebconfenv = null String gebconfscript = null private Browser _browser GEB MIT CUCUMBER Etwas Glue-Code ArquillianCucumber Configuration createconf() { new ConfigurationLoader(gebConfEnv, System.properties, new GroovyClassLo Browser createbrowser() { new Browser(createConf()) Browser getbrowser() { if (_browser == null) { _browser = createbrowser()

PERFORMANCE / CAPACITY TESTS MIT SELENIUM Korrekte Bedienung "Echte" Last Revisionssichere Pflege durch fachliche Tests HtmlUnit oder Phantom JS Im Client Latenz (bis 200ms) durch WebDriver waitloop Hoher Ressourcenbedarf Eingeschränkte Last

GEB MIT JMETER Mit etwas Glue-Code abstract class AbstractGebSamplerClient extends AbstractJavaSamplerClient impl @Override Arguments getdefaultparameters() { return new Arguments() @Override void setuptest(final JavaSamplerContext context) { to(hellopage) @Override void teardowntest(final JavaSamplerContext context) { resetbrowser() String gebconfenv = null

Arquillian geb Graphene Arquillian Deployment Arquillian Suite Deployment Arquillian Warp Cucumber Cucumber mit Arquillian Deployment Cucumber mit Arquillian Suite Deployment jmeter

GESCHWINDIGKEIT DER TESTAUSFÜHRUNG Selenium: Referenz Graphene: geringe Nachteile bei Komponenten geb: : Redundante-Webdriver-Aufrufe geb: WebDriver-Cache

STABILITÄT Keine grundsätzlichen Unterschiede

GOODIES Arquillian geb Graphene Vereinfachte Screenshoots Javascript einfacher im Browser ausführen Download Konfiguration von Browser Konfiguration von Timings Angepasste Selektoren jquery Selektoren AngularJS

AUSWAHL KRITERIEN graphene Java EE - Server Große Basis existierender Selenium Page Objects Außerhalb von Unit-Tests nicht einsetzbar geb Kombinationsmöglichkeiten "Andere Sprache"

LINKS Folien: stefanh.de/vortraege.htm Beispiel auf github Luke Daley: Geb -- Very Groovy Browser Automation

STEFAN HILDEBRANDT - CONSULTING.HILDEBRANDT.TK Beratung, Coaching und Projektunterstützung Java EE Buildsysteme gradle und maven/ant-migration Testautomatisierung Coach in agilen Projekten DevOps