Software QS-Tag 2018, Frankfurt: Vortrag von Mario-Leander Reimer (@LeanderReimer, Cheftechnologe bei QAware)
=== Dokument bitte herunterladen, falls unscharf! Please download slides if blurred! ===
Abstract: Software wie vom Fließband - das ist die Idee hinter DevOps und Continuous Delivery.
Doch damit am Ende der Fertigungsstrecke qualitativ hochwertige Software regelmäßig vom Band laufen kann, braucht es eine integrierte und vor allem hoch automatisierte Werkzeugkette, um 'das Produkt' nach allen Regeln der Kunst zu testen bevor es zum Kunden geht. Everything-as-code ist Pflicht, um kurze Absicherungs- und Release-Zyklen überhaupt erst möglich zu machen.
Die traditionelle Test-Pyramide scheint überholt. Anstatt ausgiebiger manueller Absicherungs-Zyklen braucht es nun vor allem automatisierte Schnittstellen-, Acceptance- und End-2-End Tests. Die Grenzen zwischen Entwickler und Tester verschwimmen dabei zunehmend, denn der Tester muss zukünftig zu einem Experten für Testautomatisierung werden. Aber welche Technologien und Frameworks gilt es zu erlernen und zu beherrschen? Und wie sieht die Test-Pyramide heute aus, wie viele Tests braucht es auf welchen Ebenen? Dieser Vortrag berichtet aus der Praxis und zeigt anhand etlicher Beispiele wie wir diesen Fragen und Herausforderungen in unseren Projekten begegnet sind.
4. Veränderte Vorgehen bei Entwicklung, Absicherung und
Betrieb erfordern ein Umdenken und zusätzliche Skills.
4
Das klappt so
nicht mehr!
2 Monate
1 Monat
6. Software Industrialisierung ist eine Schlüsselanforderung
für erfolgreiches Continuous Delivery.
6
Hoher Automatisierungsgrad von arbeits-
intensiven und wiederkehrenden Tasks
Bessere Software-Qualität durch eine
abgestimmte Tool-Chain
Mehr Produktivität und Zufriedenheit der
Entwickler- und Test-Teams
Bessere Kosten-Effizienz und
Wettbewerbsfähigkeit
Everything-as-code
10. Evolution der Test-Pyramide für ein agiles Vorgehen.
10
http://www.agilecoachjournal.com/2014-01-28/the-agile-testing-pyramid
11. Evolution der Test-Pyramide für ein agiles Vorgehen.
11
http://www.agilecoachjournal.com/2014-01-28/the-agile-testing-pyramid
12. ManuelleTests
Hoher Testautomatisierung auf den
unteren Ebenen ist häufig vorhanden.
Hoher Anteil an manuellen Test auf den
oberen Ebenen mündet in langen,
und aufwändigen Absicherungs-Zyklen
Testautomatisierung auf den oberen
Ebenen ist
gut für Regressionstests geeignet
reduziert manuelle Test-Aufwände
Mythen (?) der Test-Pyramide:
Langsame Ausführungsgeschwindigkeit
Aufwändig in der Umsetzung
Fehleranfällig und schlechte Wartbarkeit
Evolution der Test-Pyramide für ein agiles Vorgehen.
12
Unit Tests
Acceptance
Tests
UI
Tests
Anzahl der Tests
AngenommeneAusführungskosten
13. Evolution hin zu einem „Test-Haus“ ist möglich.
13
Unit Tests
Acceptance Tests
Load Tests
Schnittstellen Tests
Security Tests
Infrastructure Tests
End-2-End Tests
Exploratory Test
15. „Wenn ich diesen Button klicke dann ...“
15
Funktionen von Softwaresystemen werden häufig über das erwartete Verhalten der
Benutzeroberfläche beschrieben
Ein Akzeptanztest-getriebenes Vorgehen hilft die geforderten Features eindeutig zu
spezifizieren, umzusetzen und automatisiert zu testen
Dies gilt ganz besonders für die Entwicklung von grafischen Benutzeroberflächen
Optimal für die leichtgewichtige Umsetzung als natürlich-sprachliche Test- und
Automatisierungs-DSL
16. TL;DR - Akzeptanztest getriebene Entwicklung (ATDD)
16
Agile Methode, die die Zusammenarbeit von Auftraggebern, Entwicklern und Testern
unterstützt
Anforderungen und Akzeptanzkriterien werden von den Beteiligten gemeinsam erarbeitet
und formuliert
Spezifikation erfolgt in natürlicher Sprache, ist einfach und für alle Projektbeteiligten
verständlich
Kommunikation wird verbessert, man spricht gemeinsame Sprache
Akzeptanztests überprüfen
die Systemfunktionalität aus Sicht der Anwender und Kunden,
funktionale und soweit möglich nicht-funktionale Eigenschaften
Akzeptanztests sind automatisiert ausführbar
18. Page Object API anstatt Record & Replay stellen die
optimale Wartbarkeit der Test sicher
Legende
Startbildschirm
Trefferliste Fzg Detailansicht Fzg
Trefferliste Maßnahmen/
Service Bulletins
Detailansicht Maßnahmen /
Service Bulletins
- Ankerobjekt(Baureihe,
Motorbaureihe,
Karosserie)
- Ankerobjekt(Baureihe,
Motorbaureihe,
Karosserie)
- KontextFilter(DTCs)
-Ankerobjekt(Leittyp,Produktionsdatum)
Trefferliste Arbeitspositionsgruppe
- Objektauswahl(AwPosNr,
GroupOrderNumber)
- Ankerobjekt(Leittyp,
Produktionsdatum)
-Ankerobjekt(Leittyp,Produktionsdatum)
Instandsetzungen Übersicht Detailansicht Instandsetzungen
-Ankerobjekt(Leittyp,Produktionsdatum)
- Ankerobjekt(Leittyp, Produktionsdatum)
- KontextFilter(DiagnoseCodes)
- Ankerobjekt(Leittyp,
Produktionsdatum)
- KontextFilter(PumaID)
- Objektauswahl(RepUmfID)
- Ankerobjekt(Leittyp,
Produktionsdatum)
- Ankerobjekt(Baureihe,
Motorbaureihe,
Karosserie)
- Kontextfilter(Instandsetzung)
Über Algorithmus
- Objektauswahl
(PumaID/SIB-ID)
Trefferliste Pakete Detailansicht Pakete
-Ankerobjekt(Leittyp,Produktionsdatum)
Detailansicht BefundTrefferliste Befunde
- Ankerobjekt(Fahrzeugart)
- Objektauswahl(Schadensort,
Produktart)
- Ankerobjekt(Fahrzeugart)
Merkliste
-Ankerobjekt(Leittyp,
Produktionsdatum)
-KontextFilter(PaketNummer)
-Ankerobjekt(Fahrzeugart)
-KontextFilter(AwPosNr)
(wegklickbarerFilterAwPos:
WennVFC,dannIFCMAlgorithmus;
WennkeinErgebnisoderkeinVFC,
dannHG+UGoderdirektVerknüpfung;)
- Ankerobjekt(Leittyp,
Produktionsdatum)
- KontextFilter(AwPosNr, )
-Ankerobjekt(Leittyp,
Produktionsdatum)
-KontextFilter(RepUmfgefiltert
überListemitAwPosNr))
- Objektauswahl(PaketID,
Pakettyp)
- Ankerobjekt(Leittyp,
Produktionsdatum)
- Ankerobjekt(Fahrzeugart)
- KontextFilter(PaketNr)
- Objektauswahl(PaketID,
Pakettyp)
- Ankerobjekt(Leittyp,
Produktionsdatum)
- Objektauswahl(Schadensort,
Produktart)
- Ankerobjekt(Fahrzeugart)
- Objektauswahl(AwPosNr,
GroupOrderNumber)
- Ankerobjekt(Leittyp,
Produktionsdatum)
Trefferliste W-Pläne Detailansicht W-PlanKonfigurations-Popups
- Ankerobjekt(Leittyp,
Produktionsdatum) - Ankerobjekt(Leittyp,
Produktionsdatum)
- Sonst(Popup-Konfig)
Navigationspfad mit Ankerobjekt-
Attributen und Kontextfilter
Screen/Popup
<Parameter>
- Ankerobjekt(Leittyp, Produktionsdatum)
- Kontextfilter(Listeder PaketIDs)
Detailansicht
Arbeitswertpositionsgruppe
Sucheeing.:
- Baureihe
Sucheeing.:
- HG + UG
- Fehlerort
Sucheeing.:
-
Sucheeing.:
- HG/UG
- Pakettyp
Sucheeing.:
- HG/UG
Sucheeing.:
- HG/UG
Sucheeing.:
- Fehlerort
- Tätigkeit
Ablagemöglichkeit in die Merkliste und
Rücksprungnavigation aus der Merkliste.
Parameter sind nur für
Rücksprungnavigation gültig
<Parameter>
Detailansicht Service Historie
Aufruf eines Popups ohne
Weiternavigationsmöglichkeit
Detailansicht Technische Aktionen
Page Objects sind das
Application Level API
für die UI Tests
Interaktion mit
technischen APIs wird
gekapselt OO-Repräsentation aller
relevanten UI
Elementen
(Seiten, Dialoge,
Buttons)
18
19. Beispiel für Java PageObject mit Selenium WebDriver
zur Automatisierung der Google Suche
19
Findet WebElements über deren ID
<input id=„gbqfq“></input>
Findet WebElements mittels XPath im
aktuellen HTML Document
Keyboard Interaktion und
Navigation zu neuer Seite
21. Eine minimale SEU befähigt alle Non-Developer unsere
Suite an automatisierten Integrations-, Akzeptanz- und
Oberflächentests auszuführen.
Die SEU bietet Convenience-Features zur Ausführung der
Tests mit verschiedenen Browser-Konfigurationen gegen
unterschiedliche Umgebungen
Die SEU selbst ist nun ein offizielles Lieferartefakt: jedes
Release hat auch eine dazu passende Version der Test-
SEU
Ursprünglich als VHD angelegt, nun ein einfaches ZIP:
leichte und problemlose Installation auf allen Geräten mit
geringen Permissions.
Dedizierte Test-SEU zur Unterstützung von (externen)
Testern und Absicherungsabteilungen
21
22. Wir haben die automatisierten Akzeptanz- und UI-Tests
mit HP ALM synchronisiert.
22
23. 23
Auch die Test-Werkzeuge sollten bei der Evolution
unserer Systeme modernisiert werden.
Monolithic Deployment
Traditional Infrastructure
Microservices
Continuous Delivery
Containerization
Cloud Infrastructure
24. „Test long and prosper“: Schnelle und einfache Test auf
allen Ebenen mit Groovy und Spock.
24
Groovy eignet sich hervorragend zum agilen Testen von Systemen
Transparente Nutzung aller Java Klassen des Projektes durch Groovy Tests
Volle Unterstützung aller Java Frameworks (Spring, JPA, …)
Groovy Sprachfeatures und GDK Erweiterungen für elegante und knappe Tests
Guter Tool-Support durch Maven und IntelliJ Plugin sind gegeben
Kurze und flache Lernkurve durch die Nähe zu Java für schnellen Nutzen und Erfolge
Spock: The enterprise ready specification framework
Unterstützung von Behavior Driven Development
Für alle Test-Bereiche gleichermaßen gut geeignet
Eingebautes Mocking und Stubbing
Guter DIE and Framework Support (JUnit, Spring, …)
25. Einfaches BDD-Style Testing.
25
class GreeterSpec extends Specification {
def "Call Greeter using a Mock and check interactions"() {
given:
def greeting = Mock(Greeting)
def kirk = new Greeter(greeting)
when:
def reply = kirk.sayHello('Spock', 3)
then:
3 * greeting.message(_ as String) >>> ['Hello', 'Mr.', 'Spock']
and:
reply == 'Hello Mr. Spock'
}
}
https://github.com/lreimer/enterprise-spock
26. Einfaches Data Driven Testing.
26
https://github.com/lreimer/enterprise-spock
@Unroll
def "#a Quadrat + #b Quadrat = #c Quadrat (with Data Pipes)"() {
expect:
Math.pow(a, 2) + Math.pow(b, 2) == Math.pow(c, 2).round(0)
where:
a << [1, 2, 3]
b << [4, 5, 6]
c = Math.sqrt(a * a + b * b)
}
@Unroll
def "#a Quadrat + #b Quadrat = #c Quadrat (with Data Tables)"() {
expect:
Math.pow(a, 2) + Math.pow(b, 2) == Math.pow(c, 2).round(0)
where:
a | b || c
1 | 4 || Math.sqrt(17)
2 | 5 || Math.sqrt(29)
}
27. Einfache Integrations-Tests mit Spock und WireMock.
27
https://github.com/lreimer/enterprise-spock
@Rule
WireMockRule wireMockRule = new WireMockRule(18080)
def wireMock = new WireMockGroovy(18080)
def "Find all books from a stub server using a JSON body file"() {
given: "a stubbed GET request for all books"
wireMock.stub {
request {
method "GET"
url "/book"
}
response {
status 200
bodyFileName "books.json"
headers { "Content-Type" "application/json" }
}
}
when: "we invoke the REST client to find all books"
def books = client.findAll()
then: "we expect the correct number of books"
books.size() == 2
}
28. Groovy Browser Automation mit dem Geb Framework
28
Groovy basiertes Framework mit DSL für UI Automatisierung
Cross Browser Automation per Selenium WebDriver
jQuery-like API zur Content Navigation
Native Unterstützung des Page Object Patterns
Unterstützung für asynchrones Laden von Seiten und Inhalten
Gute Test-Framework Integration: JUnit, Spock, Cucumber, …
Einfache Integration in Build-Tools: Maven, Gradle, …
29. Automatisierte Browser Tests mit Spock und Geb.
29
https://github.com/lreimer/enterprise-spock
@Title("Basic navigation features for QAware homepage.")
@Narrative('''We need to make sure the navigation is working correctly.''')
@Stepwise
class HomePageSpec extends GebReportingSpec {
def "Launch browser and navigate to index page"() {
when: 'we navigate to the QAware homepage'
go("http://www.qaware.de")
then: 'the index page is displayed'
waitFor { at IndexPage }
and: 'the headline is correct'
assertThat headline.text(), containsString("Qualität und Agilität")
}
def "Navigate to the community page"() {...}
}
31. Die steigende Verteilung macht stabile Integrations-
Tests so gut wie unmöglich.
31
Nicht alle Systeme und Schnittstellen eines Verbundes stehen gleichzeitig und immer
konsistent zur Verfügung.
Variabilitäts- und Versions-Tests sind Infrastruktur intensiv.
Schlechte oder volatile Datenqualität in Backend-Systemen führt zu instabilen Tests.
Instabile Integrationstests vermindern das Vertrauen in die Tests.
Manuelle Tests sind bei Server zu Server Kommunikation oft sehr aufwändig.
32. Die Evolution von Schnittstellen führt in einem verteilten
System schnell zu Breaking Chances.
32
X
33. 33
Die Verwendung von Consumer-driven Contract Tests
berücksichtigt die Abnehmer-Perspektive im Provider.
34. Fazit
34
Alle (Unit, Integrations, Acceptance, Security, Load, Infrastructure) Tests müssen in agilen
Projekten und Zeiten von Continuous Delivery automatisiert sein.
Everything-as-code ist Pflicht!
Die Grenzen zwischen Entwickler und Tester verschwimmen zunehmend.
Der „klassische“ Tester muss zukünftig zu einem Experten für Testautomatisierung werden.
Page Object Pattern als UI-Abstraktion für optimale Wartbarkeit
Ist Technologie-unabhängig: das funktioniert für Java und .NET gleichermaßen
Page Objects: Application Level API
Selenium, Coded-UI: Technical APIs