Upload
oliver-libutzki
View
531
Download
2
Embed Size (px)
Citation preview
b+m Informatik AG
www.bmiag.de
Technologische Expertise im Software EngineeringWartbare Oberflächentests mit Open-Source-Software
Nils Christian Ehmke
Oliver Libutzki
www.bmiag.de
• Der Weg zum wartbaren Test• Erweiterte Konzepte• Demo
Agenda
www.bmiag.de
Wartbare Oberflächentests mit Open-Source-Software
Der Weg zum wartbaren Test
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
www.bmiag.de 5
Eingesetzte Frameworks/Tools
Browser-Automation
Entwicklungsumgebung
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
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!
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)
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
www.bmiag.de 10
Eingesetzte Frameworks/Tools
Browser-Automation
Entwicklungsumgebung
Testfall-Ausführung
www.bmiag.de 11
JUnit-Integration
@Testpublic void testGoogleSearch() {
WebDriver driver = new HtmlUnitDriver();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")); driver.quit();}
Integration über speziellen Runner@RunWith(TapirBootstrapper.class)
www.bmiag.de 12
Browserunabhängigkeit
@Testpublic void testGoogleSearch() {
WebDriver driver = new HtmlUnitDriver();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")); driver.quit();}
www.bmiag.de 13
Browserunabhängigkeit
@Testpublic void testGoogleSearch() {
WebDriver driver = new FirefoxDriver();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")); driver.quit();}
www.bmiag.de 14
Eingesetzte Frameworks/Tools
Browser-Automation
Entwicklungsumgebung
Testfall-AusführungDepedency-Injection /
Aspect oriented programming
www.bmiag.de 15
Browserunabhängigkeit
@Autowiredprivate WebDriver driver;
@Testpublic 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"));
}
www.bmiag.de 16
@Testpublic 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
www.bmiag.de 17
HTML-Abhängigkeiten beseitigenIf 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
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
www.bmiag.de 19
@Pagepublic 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
www.bmiag.de 20
@Autowiredprivate WebDriver driver;
@Autowiredprivate GoogleSearchPage googleSearchPage;
@Testpublic 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
www.bmiag.de 21
Auslagerung zur Wiederverwendungpublic class BrowserInteraction {
@Autowiredprivate WebDriver driver;
public void openURL(String url) {driver.get(url);
}
public String getTitle() {return driver.getTitle();
}}
www.bmiag.de 22
Auslagerung zur Wiederverwendung
@Autowiredprivate BrowserInteraction browserInteraction;
@Autowiredprivate GoogleSearchPage googleSearchPage;
@Testpublic void testGoogleSearch() {
browserInteraction.openURL("http://www.google.com");
googleSearchPage.getQueryField().setText("Cheese!");
googleSearchPage.getGoogleSearchButton().click();assertThat(browserInteraction.getTitle(),
is("Cheese! - Google Search"));
}
www.bmiag.de 23
@Pagepublic 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…
www.bmiag.de 24
Eingesetzte Frameworks/Tools
Browser-Automation
Entwicklungsumgebung
Testfall-AusführungDepedency-Injection /
Aspect oriented programming
Syntactic Sugar / Code-Generierung
www.bmiag.de 25
Xtend
Xtend-Compiler
Java-Compiler
Bytecode
Active Annotations
www.bmiag.de 26
Page-Objekte mit Xtend@Pageclass GoogleSearchPage {
@SeleniumElement(name="q")TextField queryField
@SeleniumElement(name="btnK")Button googleSearchButton
}
www.bmiag.de 27
@Autowiredextension BrowserInteraction
@AutowiredGoogleSearchPage googleSearchPage
@Testdef void testGoogleSearch() {
openURL("http://www.google.com")googleSearchPage.queryField.text = "Cheese!"googleSearchPage.googleSearchButton.clickassertThat(title, is("Cheese! - Google
Search"));
}
Test mit Xtend
www.bmiag.de 28
Wir haben es geschafft!
@Testdef void testGoogleSearch() {
openURL("http://www.google.com")googleSearchPage.queryField.text = "Cheese!"googleSearchPage.googleSearchButton.clickassertThat(title, is("Cheese! - Google
Search"));}
@Testpublic 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"));}
www.bmiag.de
Wartbare Oberflächentests mit Open-Source-Software
Erweiterte Konzepte
www.bmiag.de 30
• Parallele Testausführung• Feature-Modell zum Testen von Produktlinien• schrittweise Testdefinition• Testdatenanbindung
Erweiterte Konzepte
www.bmiag.de 31
Steps
@Autowiredextension BrowserInteraction
@AutowiredGoogleSearchPage googleSearchPage
@Stepdef void openGoogleWebsite() {
openURL("http://www.google.com")}
@Stepdef void queryGoogle() {
googleSearchPage.queryField.text = "Cheese!"googleSearchPage.googleSearchButton.clickassertThat(title, is("Cheese! - Google Search"));}
www.bmiag.de 32
Data Provider
def static queryData() {#["Cheese!", "Cake"]
}
@Stepdef void openGoogleWebsite() {
openURL("http://www.google.com")}
@Step@DataProvidedBy("queryData")def void testGoogleSearch(String queryData) {
googleSearchPage.queryField.text = queryDatagoogleSearchPage.googleSearchButton.clickassertThat(title, is(queryData + " - Google
Search"));}
www.bmiag.de 33
Eingesetzte Frameworks/Tools
Browser-Automation
Entwicklungsumgebung
Testfall-AusführungDepedency-Injection /
Aspect oriented programming
Syntactic Sugar / Code-Generierung
Testergebnis-Reporting
Allure
www.bmiag.de 34
Visuelle Aufbereitung der Testergebnisse
www.bmiag.de 35
Eingesetzte Frameworks/Tools
Browser-Automation
Entwicklungsumgebung
Testfall-AusführungDepedency-Injection /
Aspect oriented programming
Syntactic Sugar / Code-Generierung
Testergebnis-Reporting
Bau / Testausführungaußerhalb der IDE
Kontinuierliche Ausführung
Allure
www.bmiag.de 36
Kontinuierliche Ausführung
www.bmiag.de
Wartbare Oberflächentests mit Open-Source-Software
Demo
Kontakt
www.bmiag.de 39
Oliver LibutzkiSoftwarearchitekt
b+m Informatik AGRotenhofer Weg 2024109 Melsdorf
T +49 4340 404-1668F +49 4340 404-111
Nils Christian EhmkeSoftwareentwickler
b+m Informatik AGRotenhofer Weg 2024109 Melsdorf
T +49 4340 404-1686F +49 4340 404-111