Janusz Leidgens (@Killerdackel) 26.06.13 15:16:
Der @dtanzer sagt seperate Testabteilungen brauchen zu lange. Unsere Tester testen über Nacht, klappt bisher gut. #dwx13
WebDriver driver = new HtmlUnitDriver();
// And now use this to visit Google
driver.get("http://www.google.com");
// Find the text input element by its name
WebElement element = driver.findElement(By.name("q"));
// Enter something to search for
element.sendKeys("Cheese!");
// Now submit the form. WebDriver will find the form for us from the element
element.submit();
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
WebElement resultsDiv = driver.findElement(By.className("gssb_e"));
// If results have been returned, the results are displayed in a drop down.
if (resultsDiv.isDisplayed()) {
break;
}
}
// And now list the suggestions
List<WebElement> allSuggestions
= driver.findElements(By.xpath("//td[@class='gssb_a gbqfsf']"));
for (WebElement suggestion : allSuggestions) {
System.out.println(suggestion.getText());
}
//Exception nach dem Wait-Timeout
assert dynamicallyAdded.text() == "I'm here now"
assert dynamicallyAddedOrNot.text() == "I'm here now"
//nach dem Wait-Timeout ist das Value null
|| dynamicallyAddedOrNot.value() == null
Geb: Async mit waitFor
waitFor { title.endsWith("Google Search") }
waitFor { at GoogleResultsPage }
waitFor 30 { at GoogleResultsPage }
waitFor ("searchResult", { at GoogleResultsPage })
Alle Logik in Pages und Module
Candies
Download
Mit WebDriver nicht direkt möglich
Nur per Hack über Download-Dialog und sendKeys
geb transferiert Session und Location in einen HttpURLConnection
Download ohne Browser
interact
Möglichkeit komplexe Operationen mit dem WebDriver durchzuführen
environments {
'phantomjs' {
driver = {
final capabilities = new DesiredCapabilities()
capabilities.setCapability("javascriptEnabled", true)
final phantomJSDriver = new PhantomJSDriver(capabilities)
phantomJSDriver
.manage()
.window()
.setSize(new Dimension(1028, 768))
return phantomJSDriver
}
}
}
mvn -Dgeb.env=phantomjs test
Browserunterstützung WebDriver
Firefox ab 3.6
IE 7,8,9
Opera 8,9
HtmlUnit
Browserunterstützung WebDriver - 3rd-Party
Google Chrome und Chromium
PhantomJS
Android Chrome (EMU und Remote)
iOS Safari (EMU und Remote)
Opera 10, 11
Browserunterstützung geb
htmlunit
firefox
ie
chrome
Kombination mit Arquillian
Test mit @TestRunner(Arquillian.class) annotieren
@Deployment nur einmal ausführen
Bei Pageentwicklung gegen laufende Instantz
Spock
Behavior Driven Development
Spock
Namenswahl frei
Struktur
Vorbedingung (given)
Aktion (when)
Prüfungen (then)
"then"-Bock enthält implizite assertions
Spock
class ExamplePageAndModuleSpec extends geb.spock.GebSpec {
def "test search with page and module"() {
when: {
to GoogleStartPage
search.searchField.value("wikipedia")
waitFor { at GoogleResultsPage }
}
then: {
searchFirstResultLink.text() == "Wikipedia"
}
}
}
Reporting
Automatisch bei jedem Seitewechsel und bei Fehlern
Aktivierung durch Ableiten von
geb.spock.GebReportingSpec
geb.junit4.GebReportingTest
...
browser.report('<name>')
Cucumber
Behavior Driven Development
Umgangsprachliche Beschreibung
Mehrere reale Sprachen unterstützt
Ideal für Anforderer und Fachtester
Cucumber
Feature: Password management
Scenario: Forgot password
Given a user with email "cukes@cukes.info" exists
When I ask for a password reset
Then an email with a password reset link should be sent
Lasttests
Mit JMeter® und geb
Wiederverwendung von Seiten / Tests
Relativ leicht zu erstellen
Werden automatisch mitgepflegt
Korrekte Bedienung
Regressionssicher
Lasttests
Mit JMeter® und geb
Begrenzte Last
Resourcenbedarf für die Browser
Erhöhung durch Remoteserver möglich
Sonar
z.B. in Verbindung mit Arquilliantests
Als Unit- und Integrationstestabdeckung
Prozess für Tests mit Browserinteraktion
Unittests
Für selbst erstellte UI-Fuktionalität
Detailprüfungen in isolierter Umgebung
Verwendung von Mocks / kleinen Deployments
Schnelle Ausführung
Sehr robust
Komponententests
Für Seiten / Abläufen als Ganzes
Mit fixer DB und Umsystemen oder Mocks
Relativ schnell, wenn parallisiert
Robust
Systemintegrationstests
Grundsätzlich weniger robust
Ausschluss von Bedienungsproblemen durch Verwendung der selben Pages
Relativ langsamm
Parallisierung fördern
Fachliche Akzeptanztests
Auf der tiefst möglichen Ebene implementieren
Wenn möglich ohne UI
Vorteile
Fehler durch Änderung der Seitenstruktur fallen sehr früh auf
Sehr gute Abdeckung des deklarativen UI-Codes
Anforderungen an in UI implementierte Features über Tests gut dokumentiert
Best Practices
Wenn ohne UI testbar --> Ohne UI
Best Practices
Wiederverwendung von Pages und Modulen
Best Practices
Im Test/Speck kein wait
Asychronität bleibt in der Page / Modul
Idealerweise durch Marker in Page auswerten
Best Practices
Anwendung testbar gestallten, z.B. css Klassen als Alternative zu IDs, falls diese durch Frameworks
nicht stabil sind.
Best Practices
Anwendung testbar machen
CSS Selektoren
Marker für Ajax
Tests mit festem DB Stand
Dedizierte Daten je Test zum Verändern
Parallelisierbar
Wenig doppelt testen
50% Testabdeckung (Lines) über Unittests ggf. OK !?!
100% der Logik
Wenig doppelt testen
Integrationtests > 75%
Wenig doppelt testen
Kommuliert > 90%
Automatische Tests
sind die immer gültige Dokumentation
der Anforderungen an das System
Testautomatisierung sollte in der Entwicklug geschehen!