Das Erstellen und Verwalten von Tests stellt im Software-Engineering eine komplexe und zeitaufwändige Disziplin dar. Nicht selten überschreiten die Aufwände, automatisierte Tests zu schreiben, den eigentlichen Implementierungsaufwand. Und noch viel schlimmer: Tests müssen gepflegt werden. Bei fachlichen oder technischen Änderungen der getesteten Software müssen auch die Tests angepasst werden.
Nils und Oliver zeigen am Beispiel von Oberflächentests wie man lesbare, wartbare und dokumentierte Tests schreiben kann, damit sich die Aufwände amortisieren. Sie zeigen dabei, dass man weder teure, kommerzielle Produkte einsetzen noch sämtliche Komponenten selbst implementieren muss. Durch die Kombination etablierter Java-Frameworks und -Tools ist es möglich, ein Test-Werkzeug zu schaffen, das das Erstellen und vor allem die Wartung von Oberflächentests extrem vereinfacht.
4. www.bmiag.de 4
• Formulierung und Ausführung von integrativen UI-Tests
• Fokus auf Webanwendungen
• Fokus auf Lesbarkeit, Nachvollziehbarkeit und Wartbarkeit
• Formulierung in Java
• Don‘t reinvent the wheel
• Einsatz von Open-Source-Software
• Integration über definierte Schnittstellen
Prinzipien
Test API for Regressiontests
6. www.bmiag.de 6
Selenium Web Driver
• API zur Interaktion mit dem Browser
• Implementierungen in Java, C#, Ruby, Python und Javascript
• Implementierungen für alle gängigen Browser und headless
Selenium IDE
• Add-on für Firefox
• Capture-Replay-Funktionalität
• Export in Web Driver Format
Selenium
7. www.bmiag.de 7
Aktion Selenium-Befehl
„Cheese!“
in Suchfeld
eingeben
driver.findElement(By.id("lst-ib")).clear();
driver.findElement(By.id("lst-ib")).sendKeys("Cheese!");
„Lupe“
anklicken
driver.findElement(By.name("btnG")).click();
„Bilder“
anklicken
driver.findElement(By.cssSelector("a.q.qs")).click();
„Shopping“
anklicken
driver.findElement(
By.xpath("//a[contains(text(),'Shopping')]")).click();
„Web“
anklicken
driver.findElement(By.linkText("Web")).click();
Warum Tapir? Es gibt die Selenium IDE!
8. www.bmiag.de 8
Tests schreiben ist Programmieren!
In automated testing the Test Engineer
[…] must have software coding ability,
since the test cases are written in the
form of source code … (Test
automation, Wikipedia)
Many test automation tools provide record
and playback features […] reliance on
these features poses major reliability and
maintainability problems (Test automation,
Wikipedia)
9. www.bmiag.de 9
Google als Beispiel
WebDriver driver = new HtmlUnitDriver();
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());
driver.quit();
Quelle: https://code.google.com/p/selenium/wiki/GettingStarted
15. www.bmiag.de 15
Browserunabhängigkeit
@Autowired
private WebDriver driver;
@Test
public void testGoogleSearch() {
driver.get("http://www.google.com");
WebElement element = driver.findElement(By.name("q"));
element.sendKeys("Cheese!");
element.submit();
assertThat(driver.getTitle(), is("Cheese! - Google
Search"));
}
16. www.bmiag.de 16
@Test
public void testGoogleSearch() {
driver.get("http://www.google.com");
WebElement element = driver.findElement(By.name("q"));
element.sendKeys("Cheese!");
element.submit();
assertThat(driver.getTitle(), is("Cheese! - Google
Search"));
}
Lesbarkeit / Nachvollziehbarkeit / Wartbarkeit
17. www.bmiag.de 17
HTML-Abhängigkeiten beseitigen
If you have WebDriver APIs in your test methods,
You're Doing It Wrong.
-- Simon Stewart (Creator of Selenium Web Driver)
Test
Page Object
Page
Component
Element
Interface
HTML
Test
Page Object
Page
Component
Element
Interface
HTML
18. www.bmiag.de 18
• Interfaces spiegeln die Möglichkeiten des Benutzers wider
• Beispiel CheckboxField:
• void click(), boolean isEnabled(), boolean isDisplayed(),
boolean isSelected()
Element-Interfaces
«interface» CheckboxField
DefaultSeleniumCheckboxField
MyAppCheckboxField
Tapir Core
Tapir Selenium
MyApp Test
19. www.bmiag.de 19
@Page
public class GoogleSearchPage {
@FindBy(name = "q")
private WebElement queryField;
@FindBy(name = "btnK")
private WebElement googleSearchButton;
@Autowired
private BeanFactory beanFactory;
public TextField getQueryField() {
…
}
public Button getGoogleSearchButton() {
…
}
}
Page-Objekte und Element-Interfaces
20. www.bmiag.de 20
@Autowired
private WebDriver driver;
@Autowired
private GoogleSearchPage googleSearchPage;
@Test
public void testGoogleSearch() {
driver.get("http://www.google.com");
googleSearchPage.getQueryField().setText("Cheese!");
googleSearchPage.getGoogleSearchButton().click();
assertThat(driver.getTitle(), is("Cheese! - Google
Search"));
}
Page-Objekte und Element-Interfaces
21. www.bmiag.de 21
Auslagerung zur Wiederverwendung
public class BrowserInteraction {
@Autowired
private WebDriver driver;
public void openURL(String url) {
driver.get(url);
}
public String getTitle() {
return driver.getTitle();
}
}
22. www.bmiag.de 22
Auslagerung zur Wiederverwendung
@Autowired
private BrowserInteraction browserInteraction;
@Autowired
private GoogleSearchPage googleSearchPage;
@Test
public void testGoogleSearch() {
browserInteraction.openURL("http://www.google.com");
googleSearchPage.getQueryField().setText("Cheese!");
googleSearchPage.getGoogleSearchButton().click();
assertThat(browserInteraction.getTitle(), is("Cheese!
- Google Search"));
}
23. www.bmiag.de 23
@Page
public class GoogleSearchPage {
@FindBy(name = "q")
private WebElement queryField;
@FindBy(name = "btnK")
private WebElement googleSearchButton;
@Autowired
private BeanFactory beanFactory;
public TextField getQueryField() {
…
}
public Button getGoogleSearchButton() {
…
}
}
Alles gut, wenn das Page-Objekt nicht wäre…
38. Kontakt
www.bmiag.de 39
Oliver Libutzki
Softwarearchitekt
b+m Informatik AG
Rotenhofer Weg 20
24109 Melsdorf
[oliver.libutzki@bmiag.de]
T +49 4340 404-1668
F +49 4340 404-111
Nils Christian Ehmke
Softwareentwickler
b+m Informatik AG
Rotenhofer Weg 20
24109 Melsdorf
[nils-christian.ehmke@bmiag.de]
T +49 4340 404-1686
F +49 4340 404-111
Hinweis der Redaktion
Vorstellung Nils und Oliver
Vorstellung b+m
Engineering: hilft bei Beratung, Planung und Umsetzung von IT-Vorhaben
Fokus auf Banken- und Versicherungslösungen
Warum ein neues Oberflächentest-Tool?
Altes Tool seit 6 Jahren nicht weiterentwickelt
Viele Testfälle nicht abbildbar
Keine Akzeptanz bei Entwicklern
Weg zu wartbarem Test aufzeigen
Erwähnen Tapir selbst nicht Open-Source
Fokus auf Methodik
Eclipse / Selenium
Vorteil headless kurz erläutern
Aufgezeichnet mit Selenium IDE
Dopplung bei der Suchfeld-Adressierung
Jeweils anderer Zugriffspfad auf optisch ähnliche Elemente
Einführen in das Beispiel
Quelle: Getting started von der Web Driver Website
Einführung JUnit
Integration über Junit Runner
Einbettung in Junit-Test-Methode
Nutzung von Hamcrest
Spezifischer Web-Driver wird instanziiert
Einführung Spring
Auf Spring eingehen:
Möglichkeit die konkrete Implementierung von außen festzulegen
Code ist unabhängig vom konkreten Browser (WebDriver)
Test schwer lesbar und nachvollziehbar:
Es ist nicht ersichtlich, dass das Suchfeld den Namen „q“ hat
Dass die Suche über ein submit gestartet werden kann, ist ein Implementierungsdetail der getesteten Anwendung. Für den Benutzer nicht relevant. Benutzer würde Enter drücken oder aber auf „Google Search“ klicken.
Wartbarkeit:
Problematisch, wenn Google den Namen des Suchfeldes ändert.
Darauf eingehen, dass Tapir nur das Interface und eine Default-Implementierung zur Verfügung stellt.
Bzgl. MyApp auf die spezielle Implementierung der readonly-Checkboxen in Referenzanwendung eingehen
Eingehen auf:
Adressierung der HTML-Elemente (FindBy aus Selenium WebDriver)
public-Methoden liefern Element-Interfaces
Vorteile Xtend:
statische Typisierung
Java Typsystem
Kompiliert zu Java
IDE Support
Nur auf die notwendigen Informationen beschränkt
Eingehen auf die Möglichkeit die Methoden sequentiell auszuführen dank Xtend Active Annotations