Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Continuous Delivery aus Sicht des Testers

Continuous Delivery aus Sicht des Testers

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.

M.-Leander Reimer

October 18, 2018
Tweet

More Decks by M.-Leander Reimer

Other Decks in Technology

Transcript

  1. Mario- Leander Reimer Cheftechnologe, QAware GmbH Kontakt Details Mail: mario-

    [email protected] Twitter: @LeanderReimer Github: https://github.com/lreimer/ 18.10.18 2 Entwickler && Architekt 20+ Jahre Erfahrung #CloudNativeNerd Open Source Enthusiast
  2. DISRUPT 3 INDUSTRIALIZE Modern Software Engineering 100% Agile X-Funktionale Teams

    E2E Speed DevOps & Continuous Delivery Gute UX und Usability
  3. 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
  4. 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
  5. 7

  6. 8

  7. 9

  8. Manuelle Tests 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 Angenommene Ausführungskosten
  9. 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
  10. 14 Die Herausforderung: ein einfacher, homogener Test- Ansatz trotz heterogener

    Clients und Technologien. • Vorgehensweise • Frameworks & Tools • Programmiermodell • Spec Language • Automatisierung • Virtualisierung 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(Diagnose Codes) - 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 Befund Trefferliste Befunde - Ankerobjekt(Fahrzeugart) - Objektauswahl(Schadensort, Produktart) - Ankerobjekt(Fahrzeugart) Merkliste - Ankerobjekt(Leittyp, Produktionsdatum) - KontextFilter(PaketNummer) - Ankerobjekt(Fahrzeugart) - KontextFilter(AwPosNr) (wegklickbarer Filter AwPos: Wenn VFC, dann IFCM Algorithmus; Wenn kein Ergebnis oder kein VFC, dann HG+UG oder direkt Verknüpfung;) - Ankerobjekt(Leittyp, Produktionsdatum) - KontextFilter(AwPosNr, ) - Ankerobjekt(Leittyp, Produktionsdatum) - KontextFilter(RepUmf gefiltert über Liste mit AwPosNr)) - 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-Plan Konfigurations-Popups - Ankerobjekt(Leittyp, Produktionsdatum) - Ankerobjekt(Leittyp, Produktionsdatum) - Sonst(Popup-Konfig) Navigationspfad mit Ankerobjekt- Attributen und Kontextfilter Screen/Popup <Parameter> - Ankerobjekt(Leittyp, Produktionsdatum) - Kontextfilter(Liste der PaketIDs) Detailansicht Arbeitswertpositionsgruppe Suche eing.: - Baureihe Suche eing.: - HG + UG - Fehlerort Suche eing.: - Suche eing.: - HG/UG - Pakettyp Suche eing.: - HG/UG Suche eing.: - HG/UG Suche eing.: - 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
  11. „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
  12. 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
  13. 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(Diagnose Codes) - 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 Befund Trefferliste Befunde - Ankerobjekt(Fahrzeugart) - Objektauswahl(Schadensort, Produktart) - Ankerobjekt(Fahrzeugart) Merkliste - Ankerobjekt(Leittyp, Produktionsdatum) - KontextFilter(PaketNummer) - Ankerobjekt(Fahrzeugart) - KontextFilter(AwPosNr) (wegklickbarer Filter AwPos: Wenn VFC, dann IFCM Algorithmus; Wenn kein Ergebnis oder kein VFC, dann HG+UG oder direkt Verknüpfung;) - Ankerobjekt(Leittyp, Produktionsdatum) - KontextFilter(AwPosNr, ) - Ankerobjekt(Leittyp, Produktionsdatum) - KontextFilter(RepUmf gefiltert über Liste mit AwPosNr)) - 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-Plan Konfigurations-Popups - Ankerobjekt(Leittyp, Produktionsdatum) - Ankerobjekt(Leittyp, Produktionsdatum) - Sonst(Popup-Konfig) Navigationspfad mit Ankerobjekt- Attributen und Kontextfilter Screen/Popup <Parameter> - Ankerobjekt(Leittyp, Produktionsdatum) - Kontextfilter(Liste der PaketIDs) Detailansicht Arbeitswertpositionsgruppe Suche eing.: - Baureihe Suche eing.: - HG + UG - Fehlerort Suche eing.: - Suche eing.: - HG/UG - Pakettyp Suche eing.: - HG/UG Suche eing.: - HG/UG Suche eing.: - 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
  14. 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
  15. 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
  16. 23 Auch die Test-Werkzeuge sollten bei der Evolution unserer Systeme

    modernisiert werden. Monolithic Deployment Traditional Infrastructure Microservices Continuous Delivery Containerization Cloud Infrastructure
  17. „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, …)
  18. 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
  19. 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) }
  20. 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 }
  21. 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, …
  22. 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"() {...} }
  23. Einfache PageObject Implementierung mit Geb. 30 https://github.com/lreimer/enterprise-spock class IndexPage extends

    Page { static url = "http://www.qaware.de" static at = { browser.title.contains("QAware") } static content = { headline { $("h1", 0) } } } class CommunityPage extends Page { static url = "http://www.qaware.de/community/" static at = { browser.title.contains("Community") } static content = { headline { $("h1", 1) } } }
  24. 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.
  25. 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.