1 of 170

1

Softwaretest für EntwicklerInnen

Javacream

Softwaretest für EntwicklerInnen

2 of 170

Vorstellungsrunde

  • Name
  • Rolle im Unternehmen im Rahmen der Software-Entwicklung
  • Themenbezogene Vorkenntnisse (auch Programmiersprachen)
  • Aktuelle Problemsituation
  • Individuelle Zielsetzung

2

Javacream

Softwaretest für EntwicklerInnen

3 of 170

Motivation

3

Javacream

Softwaretest für EntwicklerInnen

4 of 170

Warum Testen?

  • Triviale Antwort
    • “Ich muss sicherstellen, dass mein Produkt funktioniert”
  • Neben gibt es eine Reihe weiterer Antworten
    • Dokumentation
    • Sicherstellung der Wiederverwendbarkeit
    • Projektsteuerung
    • Kommunikation im Team
    • Qualität

4

Javacream

Softwaretest für EntwicklerInnen

5 of 170

Ein Widerspruch

  • Testen von Software ist unbestritten elementar wichtig
  • “Software ist (gefühlt?) nicht oder unbefriedigend getestet”

5

Javacream

Softwaretest für EntwicklerInnen

6 of 170

Die Effizienzkurve

  • Natürlich nur eine grobe Abstraktion!

6

Zeit

Effizienz

“Wie viele geschriebene Codezeilen werden im fertigen Produkt übernommen?”

100

50

No Tests

Test-getriebene Entwicklung

Javacream

Softwaretest für EntwicklerInnen

7 of 170

These: “Aus betriebswirtschaftlicher Sicht sind Tests einsparbar”

7

Zeit

Effizienz

“Wie viele geschriebene Codezeilen werden im fertigen Produkt übernommen?”

100

50

No Tests

Test-getriebene Entwicklung

Javacream

Softwaretest für EntwicklerInnen

8 of 170

Methoden der Software-Entwicklung

  • z.B. Klassisches Wasserfallmodell
    • Phasen
      • Spezifikation
      • Implementierung
      • Test
      • Korrektur
  • z.B. Agile Entwicklung
    • Parallelisierung der Phasen

8

Javacream

Softwaretest für EntwicklerInnen

9 of 170

Die reale Effizienzkurve

9

Zeit

Effizienz

“Wie viele geschriebene Codezeilen werden im fertigen Produkt übernommen?”

100

50

Wasserfall

Agile

Javacream

Softwaretest für EntwicklerInnen

10 of 170

Risiko!

10

Zeit

Effizienz

100

50

Wasserfall

Agil

Javacream

Softwaretest für EntwicklerInnen

11 of 170

Risiko!

11

Zeit

Effizienz

100

50

Wasserfall

Agil

Javacream

Softwaretest für EntwicklerInnen

12 of 170

Warum wird dann nicht oder unbefriedigend getestet?

  • "Tests verringern die Effizienz der Softwareentwicklung"
  • Das Prinzip “Testen” ist nicht verstanden

12

Javacream

Softwaretest für EntwicklerInnen

13 of 170

Testing Frameworks

13

Javacream

Softwaretest für EntwicklerInnen

14 of 170

Formulieren von Tests

  • Test-Logik ist etwas völlig anderes als eine Implementierung einer Fachvorgabe
    • Typische Testsequenz
      • Statische Definition der Eingangsdaten
        • Keine Validierung notwendig
      • Statische Definition der erwarteten Ergebnisse
        • Ein Test berechnet keine erwarteten Ergebnisse!
        • Vorsicht: Das ist eine gewaltige Einschränkung dafür, was überhaupt alles getestet werden kann!
      • Aufruf des zu testenden Algorithmus mit den Eingangsdaten
      • Prüfen meiner Erwartungen
      • Protokollieren der Ergebnisse

14

Best Practice:

  • Test-Sequenzen sind syntaktisch sehr einfache Programme!

Javacream

Softwaretest für EntwicklerInnen

15 of 170

Testframework “xUnit”

  • “Spezifikation”: Welchen Befehlssatz und welche Features muss ein Testing-Framework bereitstellen?
    • Gruppierung von Tests
      • Test Case
        • Enthält die typische Testsequenz
      • Test Fixture
        • Stellt für Test Cases einen Kontext zur Verfügung
          • “Kontext”: Eingangsdaten oder ein Test-Objekt
      • Test Suite
        • Enthält einen oder mehrere Test Cases / Fixtures
    • Test-API
      • Formulierung von Assertions
      • Assertions für Fehlerbehandlung
      • Asynchrone Sequenzen
    • Automatisierung
      • Ausführung
      • Report-Generierung

15

  • JUnit verwendet für "Test Case" den Begriff "Test" und "Test Case" für Test Fixture
  • Google Test ist aktuell im Prozess seine Nomenklatur xUnit-konform zu machen
    • “Test Case” und “Test Suite” unsauber, stattdessen wird häufig von “Test”

Javacream

Softwaretest für EntwicklerInnen

16 of 170

Weitere Test-APIs

  • Erzeugen von
    • Dummies
    • Spy / Decorator
    • Mocks

16

Das ist in der Umsetzung alles andere als trivial, dazu werden hochwertige Sprach-Features genutzt

  • Code-Generierung zur Laufzeit
  • Dynamische Zugriffe (z.B. Java Reflection, Python Decorators, Macros)

Javacream

Softwaretest für EntwicklerInnen

17 of 170

ToDo

  • Recherche / Vorhandenes Wissen
    • In welchen typischen Szenarien werden diese Dinge denn genutzt?
    • Was ist denn der Unterschied zwischen einem Dummy, einem Spy und einem Mock?

17

Javacream

Softwaretest für EntwicklerInnen

18 of 170

Lösung

18

Test Fixture

Algorithm

Test Suite

Andere Algorithmen oder Ressourcen

Dependencies

Dummy

Ein Dummy realisiert die Dependencies mit Dummy-Daten

+ liefert damit keine garantiert fachlich konsistente Daten

Ein Mock realisiert die Dependencies mit Daten, die die Test-Suite definiert hat

Mock

Daten

Spy

Decorator

Ein Spy ergänzt den Ablauf des Algorithmus um Test-typische Sequenzen

Javacream

Softwaretest für EntwicklerInnen

19 of 170

Lösung Extended

19

Test Fixture

Algorithm

Test Suite

Andere Algorithmen oder Ressourcen

Dependencies

Dummy

Ein Dummy realisiert die Dependencies mit Dummy-Daten

+ liefert damit keine garantiert fachlich konsistente Daten

Ein Mock realisiert die Dependencies mit Daten, die die Test-Suite definiert hat

Mock

Daten

Spy

Ein Spy ergänzt den Ablauf des Algorithmus um Test-typische Sequenzen

Test Stub

Alternativ-

Implemen-

tierung

Javacream

Softwaretest für EntwicklerInnen

20 of 170

Verbreitung / Einschätzung

  • Dummy
    • Sie liefern keine fachlich konsistenten Daten
    • Einsatzbereich limitiert, auch zeitlich
  • Mock
    • Können bei korrektem Gebrauch fachlich konsistente Daten liefern
    • Das "Recording" eines Mocks bläht den Testfall gewaltig auf
  • Test-Stub als Alternativimplementierung für Algorithmen
    • Verführerisch, "hört sich gut an", in der Praxis aber mit das erste, das rausfliegt / stillgelegt wird
    • Nischen
      • Test Stub für Ressourcen = Datenzugriffslogik + Testdaten
      • Testtreiber können in Regressionstests, Lasttests sowie in UI-Aufzeichnungen genutzt werden

20

Javacream

Softwaretest für EntwicklerInnen

21 of 170

Exkurs: Weitere Begriffe

21

Javacream

Softwaretest für EntwicklerInnen

22 of 170

“Was ist Agile?”

  • Agile bedeutet, dass alle Beteiligten des Entwicklungsprozesses nach Standards arbeiten müssen, um die notwendige Flexibilität und Geschwindigkeit zu bekommen
    • Das gilt auch Spezifikation der Anwendung
      • Erstellen von kleinen Spezifikations-Paketen
      • Parallelentwicklung muss möglich sein
    • Umsetzung als “User Story”
      • “as authenticated user i am able to order an item”
    • Definition of Done
      • Kriterien: Wann ist die User Story erfolgreich umgesetzt?

22

Javacream

Softwaretest für EntwicklerInnen

23 of 170

Agile und Testen

  • Agile bedeutet, dass alle Beteiligten des Entwicklungsprozesses nach Standards arbeiten müssen, um die notwendige Flexibilität und Geschwindigkeit zu bekommen
    • Das gilt auch Spezifikation der Anwendung
      • Erstellen von kleinen Spezifikations-Paketen
      • Parallelentwicklung muss möglich sein
    • Umsetzung als “User Story”
      • “as authenticated user i am able to order an item”
      • Das ist der Test Cases
    • Definition of Done
      • Kriterien: Wann ist die User Story erfolgreich umgesetzt?
      • Assertions

23

Javacream

Softwaretest für EntwicklerInnen

24 of 170

Behaviour Driven Tests

  • Statt eines Algorithmus-Testes wird ein Usertest formuliert
    • User Stories aus dem Agile Development-Konzept können als BDT-Tests genutzt werden
      • order = authenticated_user order isbn42
    • Die Story ist damit der Test Case
  • Wertung (“Sawitzki”)
    • BDTs sind in der Formulierung für “echte” EntwicklerInnen etwas schräg
    • User Stories sind als Tests definitiv nicht genügend

24

Javacream

Softwaretest für EntwicklerInnen

25 of 170

FitNess

  • Voraussetzung
    • Irgendeine Form von Prosa-Vorgabe
      • Word-Dokument, Wiki-Seite (z.B. mit Confluence), …
      • Gemeinsames Element
        • Beispiel-Tabellen mit Eingangsdaten und erwarteten Ergebnisse

25

1

Hugo

True

2

Emil

False

FIT

zu testender Algorithmus

1

Hugo

True

2

Fritz

False

Javacream

Softwaretest für EntwicklerInnen

26 of 170

End to End Tests mit GUI

  • Anwendung mit Benutzerinterface
    • Das Komplizierteste, was man überhaupt Testen kann
      • Eingangsdaten sind Benutzer-Aktionen (Mausklicks, Tastatureingaben)
      • Ergebnisse sind geänderte Oberflächen
        • “Wenn Eingabe ‘Hugo’ dann wird Schaltfläche deaktiviert”
      • Laufzeitumgebung ist
        • Das Betriebssystem direkt (z.B. Windows)
        • Browser
        • App (Android, iOS)
  • Lösung
    • Zur Erstellung eines automatisierbaren Tests wird eine Aufzeichnung eines realen Nutzerverhaltens als Grundlage genommen
  • Framework-Lösung für Web Applikationen ist Selenium

26

Javacream

Softwaretest für EntwicklerInnen

27 of 170

Details zu xUnit-Frameworks

27

Javacream

Softwaretest für EntwicklerInnen

28 of 170

Was ist denn dieses "xUnit"?

  • Keine Spezifikation, kein Fachbegriff, sondern ein Konstrukt nur für dieses Seminar
    • "Sawitzki"
  • xUnit ist eine Pseudosprache, die für die Praxis nahtlos in ein konkretes Unittest-Framework transformiert werden kann
    • jUnit
    • XUnit
    • unittest bzw. PyUnit

28

Javacream

Softwaretest für EntwicklerInnen

29 of 170

Best Practice zum Schneiden von Tests

  • Ein Test Case prüft im Idealfall nur eine einzige Annahme
  • Vollständige Abdeckung aller möglichen Situationen / Kombinationen von Eingabeparametern ist notwendig
    • Mission Impossible bei Zahlen-Bereichen
    • Möglich ist die Bestimmung der Klassifikation der Parameter
  • Test Cases sind unabhängig zu formulieren
    • Idempotenz
    • Die Reihenfolge der Ausführung ist beliebig, ebenso können Test Cases beliebig oft wiederholt werden
      • Das führt ebenfalls zu einer Einschränkung der zu testenden Algorithmen ->

29

Javacream

Softwaretest für EntwicklerInnen

30 of 170

Was ist nicht idempotent?

  • insert_data(42, ‘Hugo’)
    • Intern Einfügen eines Datensatzes mit dem Primärschlüssel 42
  • Damit muss für jede Ausführung des Test Cases eine komplett neue Datenbank-Instanz benutzt werden

30

Javacream

Softwaretest für EntwicklerInnen

31 of 170

ToDo

  • Ein Programm akzeptiert als Eingabewerte positive ganze Zahlen.
    • Es interpretiert jeweils 3 eingegebene positive ganze Zahlen als die Seiten a, b und c eines Dreiecks
    • Das Programm gibt eine Meldung aus, ob es sich um kein, ein nicht gleichschenkliges, gleichschenkliges oder gleichseitiges Dreieck handelt.
      • Kein Dreieck (Dreiecksformel)
        • "Die Summe zweier Seite ist kleiner gleich als die dritte Seite"
  • Aufgabe
    • Entwerfen Sie geeignete Testfälle für dieses Programm!
    • Lösung in Form einer Tabelle (“Test-Matrix”)
      • Pro Zeile: (Sprechender) Name des Test Case, Eingangsdaten (a=,b=,c=), Ergebnis

31

Javacream

Softwaretest für EntwicklerInnen

32 of 170

Lösungsvorschlag

negative_length_is_invalid, (-1,3,4), (3,-1,4), (3,4,-1), (-1,-1,1), (-1,1,-1), (1,-1,-1), (-1,-1,-1) , Kein Dreieck

0_is_invalid_length, (0,3,4), (3,0,4), (3,4,0), (0,0,1), (0,1,0), (1,0,0), (0,0,0) , Kein Dreieck

2_5_4_is_triangle, (2,5,4), Dreieck

3_3_3_is_equiliteral, (3,3,3), Gleichseitiges Dreieck

3_3_4_is_isoscele, (3,3,4), Gleichschenkliges Dreieck

sum_of_two_sides_is_greater_than_third_side, (2,5,4), (5,4,2), Dreieck

sum_of_two_sides_is_less_or_equal_third_side, (1,2,3), (42,44,1), Kein Dreieck

32

Javacream

Softwaretest für EntwicklerInnen

33 of 170

Exkurs

  • Black Box Test
    • Es sind aus Sicht des Tests keinerlei Implementierungs-Details verfügbar
      • calculate(2, 5) ist eine willkürliche Auswahl von Eingabeparametern
      • Klassifikation muss aus der Fachvorgabe entnommen werden
        • Kann unvollständig sein
  • White Box Test
    • Es sind aus Sicht des Tests ist die Implementierung bekannt
      • if p1 > 5 or p2 < 10 then …
      • if p1 > 4711 or p2 < -5 then …
      • else …
    • Damit wird eine Parameter-Klassifikation ermöglicht
      • “ich schaue mir die Kriterien der im Code enthaltenen Abfragen an”

33

Javacream

Softwaretest für EntwicklerInnen

34 of 170

Bestimmung der Test Coverage

  • Bestandteil eines xUnit-Frameworks
  • Bestimmung ist relativ Ressourcen-intensiv (CPU)
    • Optional
  • Reporting-Metriken
    • https://grosser.it/2008/04/04/whats-my-coverage-c0-c1-c2-c3-path-coverage/
    • Bedeutung
      • C0
        • Sequenz-Metrik
          • Visualisierung häufig im Quellcode-Editor
      • C1, C2, C3
      • Path-Coverage ist erreicht, wenn die Tests alle Pfade aller Kontrollstrukturen durchlaufen haben

34

Javacream

Softwaretest für EntwicklerInnen

35 of 170

Testen und Anwendungs-Architektur

35

Javacream

Softwaretest für EntwicklerInnen

36 of 170

Wozu “Architektur”?

36

Service

  • operation1
  • operation2

Actor

  • Interaktiver Benutzer
  • Anderes System / Service / Prozess

Test

Triviale Architektur, nichts anderes als die fachliche Sicht auf die Anwendung

Javacream

Softwaretest für EntwicklerInnen

37 of 170

Beispiel

  • Der BooksService soll eine Anwendung sein, die Buchbestände erfasst und verwaltet
    • Operationen
      • create(title): isbn_number
      • find_book_by_isbn(isbn): book
      • delete_book_by_isbn(isbn): true | false

37

BooksService

  • create()
  • find…
  • delete…

Actor

Javacream

Softwaretest für EntwicklerInnen

38 of 170

Reale Architektur mit einem technischen Modell

38

Goldene Regel der Architektur

  • Jeder Bestandteil des Modells (= jeder Service) erfüllt exakt eine einzige, wohldefinierte Aufgabe / Rolle
  • BooksService verwaltet Bücher
  • IsbnGeneratorService erzeugt eindeutige ISBN-Nummern

BooksService

  • create()
  • find…
  • delete…

Actor

IsbnGeneratorService

  • next(): isbn

Javacream

Softwaretest für EntwicklerInnen

39 of 170

Modularisierung und Test Cases

39

BooksService

  • create()
  • find…
  • delete…

Test Case

IsbnGeneratorService

  • next(): isbn

Test Case

Jeder Service kann durch eigene Test Suiten getestet werden

Die Modularisierung erhöht die Testbarkeit der Anwendung

Javacream

Softwaretest für EntwicklerInnen

40 of 170

Test-Case-Kategorien in modularisierten Systemen

  • Unit-Test
    • Enthält Test Cases, die einen einzigen Service isoliert testen
      • Während der Ausführung eines Unit-Tests hat der zu testenden Service keinerlei Abhängigkeiten
  • Integration Test
    • Enthält Test Cases, die Services testen, die auch andere Services aufrufen können

40

Hinweis

xUnit ist ein Test Framework und kann sowohl Unit- als auch IntegrationsTests…

Javacream

Softwaretest für EntwicklerInnen

41 of 170

Was ist besser: Unit oder Integration?

  • Die Interpretation eines aufgetretenen Test-Fehlers ist bei Unit-Test eindeutig, bei einem Integrationstest nicht
    • Das ist eine eher negative Konsequenz aus der Modularisierung
  • Lösungsvorschlag
    • Hierarchisches Testen
      • Identifikation aller Unit-Tests
      • Falls alle Unit-Tests erfolgreich sind werden diese Services als “fehlerfrei” angenommen
        • Damit werden nun alle Integrations-Tests, die diese getesteten Module benutzen, als Unit-Test aufgefasst
    • Dummies und Mocks sind als fehlerfrei aufzufassen und zählen nicht als Dependency!

41

Javacream

Softwaretest für EntwicklerInnen

42 of 170

Umgang mit Ressourcen

  • Lokales Dateisystem
  • Remote Ressourcen
    • Datenbank-Instanzen
    • Web Server
  • Sobald Ressourcen benutzt werden spricht man nun von einem System-Test

42

Javacream

Softwaretest für EntwicklerInnen

43 of 170

Modell mit Ressourcen

43

BooksService

  • create()
  • find…
  • delete…

Test Case

IsbnGeneratorService

  • next(): isbn

Test Case

MySql-DB

RESTful Web Service

Javacream

Softwaretest für EntwicklerInnen

44 of 170

Konsequenzen von System-Tests

  • Jede reale Anwendung hat Ressourcen-Zugriffe
    • Damit sind System-Tests unvermeidlich
  • System-Tests sind immer aufwändig und nicht mehr unter Kontrolle der Tests
    • Erweiterung der Test-Fixture
      • Stelle eine Testumgebung bereit
        • z.B. mit Datenbank und externen Web Service
      • Ein System-Test kann willkürlich fehlschlagen, aber der Fehler liegt in der externen Ressource
        • “Jemand stoppt den Web Server”
        • “jemand dropped die Datenbank”

44

Javacream

Softwaretest für EntwicklerInnen

45 of 170

Konsequenzen von System-Tests 2

  • Rückgabe der Kontrolle zur Test Suite
    • Mocks
      • xUnit-Frameworks bieten interne Lösungen an für das Mocken z.B. von Http-Requests bzw. Datenbank-Aufrufen
    • Datenbankinstanz pro Test Suite bzw. pro Test Case
      • Häufig werden hierfür “Embeddable Databases” benutzt, teilweise im “In Memory Modus”

45

Javacream

Softwaretest für EntwicklerInnen

46 of 170

Exkurs

  • Tests und Bestandssoftware
    • Extremfall:
      • Die Bestandssoftware funktioniert am 30.6.2025, hat aber keinen einzigen Unittest
    • Ab 1.7.2025: Umstieg auf Testgetriebenen Ansatz auch mit Einführung von Werkzeugen zur Bestimmung der Softwarequalität
      • Damit wird meine funktionsfähige Anwendung sofort als qualitativ miserabel eingeschätzt
      • Völlig falsch wäre es nun aber, nachträglich Unittests etc. einzuführen
      • Sinnvoll ist es nun aber, Erweiterungen / neue Features testgetrieben zu realisieren
      • Damit kann die Bestandssoftware "erodieren", was zu Fehlern im System- / Anwender test führt
        • Jetzt wird für die Bestandssoftware für dieses Fehlerticket ein Unittest geschrieben, der
          • die Fehlersituation bestätigt / nachstellt
          • nach Fehlerkorrektur auf "grün" schaltet

46

"Fehler-Hotspots"

an einer Stelle mit erkanntem Fehler befinden sich häufig weitere Schwachstellen

Javacream

Softwaretest für EntwicklerInnen

47 of 170

ToDo: Test Fixtures

47

BooksService

  • create()
  • find…
  • delete…

Test

IsbnGeneratorService

  • next(): isbn

Test

MySql-DB

  • Konzipieren Sie hierfür eine Reihe von “Tests” = Test Cases!
  • Wie unterscheiden Sie Unit- / Integration- / System-Tests?

RESTful Web Service

Javacream

Softwaretest für EntwicklerInnen

48 of 170

Lösung: Template

48

BooksService Test Suite

  • Test Case

Fixture

Javacream

Softwaretest für EntwicklerInnen

49 of 170

Lösung: Template

49

IsbnGeneratorService Test Suite

  • Test Case

Fixture

Javacream

Softwaretest für EntwicklerInnen

50 of 170

Lösung: Test Suites pro Operation

50

BooksService Test Suite

Create Test Suite

  • valid_title_creates_isbn
  • null_title_signales_error

FindByIsbn Test Suite

  • isbn42_finds_book_with_title_xyz
  • isbn4711_is_not_a_book

DeleteByIsbn Test Suite

  • isbn42_deletes_book
  • isbn4711_is_not_a_book

IsbnGeneratorService Test Suite

Next Test Suite

  • valid_isbn_is_created
  • isbns_are_unique

Fixture

Fixture

Javacream

Softwaretest für EntwicklerInnen

51 of 170

Hinweis

  • Die Implementierung ist völlig unverändert, egal wie ich den Test kategorisiere
    • Beispiel
      • IsbnGeneratorServiceImpl
        • next()
          • import requests
          • requests.post(endpoint)
      • BookServiceImpl
        • find_book(...)
          • import mysql.connector
          • con = mysql.connector.connect()
          • com.execute('SELECT * FROM BOOKS')

51

Javacream

Softwaretest für EntwicklerInnen

52 of 170

Lösung: Unit Test

52

IsbnGeneratorService Test Suite

Next Test Suite

  • valid_isbn_is_created
  • isbns_are_unique

Fixture

  • HttpMock

Javacream

Softwaretest für EntwicklerInnen

53 of 170

Lösung: Unit Test

53

IsbnGeneratorService Test Suite

Next Test Suite

  • valid_isbn_is_created
  • isbns_are_unique

Fixture

  • Test WebService

Javacream

Softwaretest für EntwicklerInnen

54 of 170

Lösung: System-Test

54

IsbnGeneratorService Test Suite

Next Test Suite

  • valid_isbn_is_created
  • isbns_are_unique

Fixture

  • external WebService

Javacream

Softwaretest für EntwicklerInnen

55 of 170

Lösung: Unit Tests

55

BooksService Test Suite

Create Test Suite

  • valid_title_creates_isbn
  • null_title_signales_error

Fixture

  • IsbnGenerator-Dummy oder -Mock

Javacream

Softwaretest für EntwicklerInnen

56 of 170

Lösung: Unit Tests

56

BooksService Test Suite

Fixture

  • DB Mock
  • TestDB per TestCase

FindByIsbn Test Suite

  • isbn42_finds_book_with_title_xyz
  • isbn4711_is_not_a_book

DeleteByIsbn Test Suite

  • isbn42_deletes_book
  • isbn4711_is_not_a_book

Javacream

Softwaretest für EntwicklerInnen

57 of 170

Lösung: Integration Test

57

BooksService Test Suite

Create Test Suite

  • valid_title_creates_isbn
  • null_title_signales_error

Fixture

  • IsbnGenerator
    • HttpMock
    • Test WebService

Javacream

Softwaretest für EntwicklerInnen

58 of 170

Lösung: System Test

58

BooksService Test Suite

Create Test Suite

  • valid_title_creates_isbn
  • null_title_signales_error

Fixture

  • IsbnGenerator
    • External WebService

Javacream

Softwaretest für EntwicklerInnen

59 of 170

Lösung: System Tests

59

BooksService Test Suite

Fixture

  • External DataBase

FindByIsbn Test Suite

isbn_42_finds_book_or_not

DeleteByIsbn Test Suite

  • isbn4711_is_not_a_book

Javacream

Softwaretest für EntwicklerInnen

60 of 170

Lösung: Unit Test

60

BooksService Test Suite

Scenario Test Suite

  • create_find_delete

Fixture

  • IsbnGenerator Dummy
  • DB-Mock

Javacream

Softwaretest für EntwicklerInnen

61 of 170

Lösung: System Test

61

BooksService Test Suite

Scenario Test Suite

  • create_find_delete

Fixture

  • IsbnGenerator
    • External WebService
  • Externe Datenbank

Javacream

Softwaretest für EntwicklerInnen

62 of 170

Aufsetzen der Test Fixtures

62

Javacream

Softwaretest für EntwicklerInnen

63 of 170

Klassisch

  • Es werden Prozesse gestartet, die für eine Testausführung die notwendige Infrastruktur bereitstellt
  • z.B.
    • Starte eine Datenbankinstanz (Standalone, Embedded)
    • Starte WebServices
  • In der klassischen Variante werden diese Prozesse häufig aufgrund des Aufwands als Testsysteme zentral bereitgestellt

63

Javacream

Softwaretest für EntwicklerInnen

64 of 170

Mocking

  • Testframeworks enthalten für Standard-Systeme Mock-Implementierungen
    • Internet und RESTful WebServices
    • (Relationale) Datenbanken
  • Aufsetzen
    • Nutzen der Mock-Module statt der richtigen
    • Aufzeichnen des Verhaltens des Mocks
      • http_mock.expect('http://host:8080/people').andAnswer('[{"lastname": "Sawitzki}]')

64

Javacream

Softwaretest für EntwicklerInnen

65 of 170

Verwendung der Container-Technologie

  • Aus einem Image wird auf einem Host ein Container erzeugt, der dann auf diesem Host (in einer Sandbox) betrieben wird
    • docker run mysql
  • Images werden abgelegt in einem Image-Repository
    • Im Unternehmen z.B. Artifactory
  • Container sind leichtgewichtig und starten / stoppen recht schnell

65

Javacream

Softwaretest für EntwicklerInnen

66 of 170

Verwendung der Container im Testumfeld

  • Eine komplette "klassische" Testumgebung kann on-demand gestartet werden
    • docker-compose up
  • Eine Mock-Datenbank kann über ein Image bereitgestellt werden
    • Statt in einem Testfall den Mock zu programmieren, nutze ich ein Image mit einer Datenbank mit den entsprechenden Daten
  • Jedes Team, das einen Service implementiert, kann Images bereitstellen, die von anderen Service für Integrationstests benutzt werden können

66

Test Fixtures können damit viel einfacher in einer "per Test Case"-Variante bereitgestellt werden

Javacream

Softwaretest für EntwicklerInnen

67 of 170

Beispiel

  • Team "IsbnGeneratorService"
    • Implementiert und testet seinen Service
  • Aus der Testumgebung kann nun einfach ein Docker-Image erstellt werden, das z.B. b esteht aus
    • Service läuft in seiner Umgebung und nutzt einen internen WebService

67

Javacream

Softwaretest für EntwicklerInnen

68 of 170

Lösung: Integration Test

68

BooksService Test Suite

Create Test Suite

  • valid_title_creates_isbn
  • null_title_signales_error

Fixture

  • IsbnGeneratorTestContainer

Javacream

Softwaretest für EntwicklerInnen

69 of 170

Heute

  • Sämtliche Ressourcen werden über Container bereitgestellt
  • Ausnahmen
    • Hardware-Ressourcen
    • GUI-Anwendungen

69

Javacream

Softwaretest für EntwicklerInnen

70 of 170

Testen und Architektur im Detail

70

Javacream

Softwaretest für EntwicklerInnen

71 of 170

Beispiel: Modell

71

BooksService

  • create(title, pages, price): isbn | not created
  • find_by(isbn): book | not found
  • find_all(): books
  • update(book): status
  • delete_by(isbn): status

IsbnGeneratorService

  • next(): isbn

StoreService

  • get_stock(category, item): stock

Book

  • isbn <<pk>>
  • title
  • pages
  • price
  • available

n

1

1

Javacream

Softwaretest für EntwicklerInnen

72 of 170

Beispiel: BooksService-Operations

  • create
    • Parameter
      • title eine Zeichenkette mit mindestens einem Zeichen
      • pages > 0
      • price >= 0
    • Rückgabe
      • isbn, eine ISBN-Nummer mit dem Format ‘ISBN-<Zahl>-<Länderkürzel>’
      • Falls invalide Parameter übergeben wurden: Fehler mit der Meldung “illegal parameter <name> <wert>, <gültiger Bereich>”
    • Die ISBN-Nummer wird durch einen Aufruf des IsbnGeneratorService bestimmt

72

Javacream

Softwaretest für EntwicklerInnen

73 of 170

Beispiel: BooksService-Operations

  • find_by_isbn
    • Parameter
      • isbn eine ISBN-Nummer mit dem Format ‘ISBN-<Zahl>-<Länderkürzel>’
    • Rückgabe
      • Das gefundene Buch
      • Falls invalide Parameter übergeben wurden: Fehler mit der Meldung “illegal isbn <wert>, <gültiger Bereich>
      • Falls das Buch nicht gefunden wurde wird ein Fehler mit der Meldung ‘book for isbn <isbn> not found’
    • Die Verfügbarkeit des Buches wird durch eine Bestandsabfrage beim StoreService bestimmt. Kategorie: ‘books’, item: isbn. Falls der Stock > 0 ist ist das Buch verfügbar, sonst nicht
  • find_all
    • Rückgabe
      • Eine Liste von Büchern, gegebenenfalls eine leere Liste
      • Die Verfügbarkeit der Bücher wird wie oben für alle Bücher bestimmt

73

Javacream

Softwaretest für EntwicklerInnen

74 of 170

Beispiel: BooksService-Operations

  • update
    • Parameter
      • book, eine Datenstruktur mit gesetzter isbn, title, pages, price
    • Rückgabe
      • Ein Status
        • ‘OK’
        • Fehlermeldung ‘illegal book <invalider parameter>, <invalider wert>’
        • oder ‘book for isbn <isbn> not found’

74

Javacream

Softwaretest für EntwicklerInnen

75 of 170

Beispiel: BooksService-Operations

  • delete_by
    • Parameter
      • isbn eine ISBN-Nummer mit dem Format ‘ISBN-<Zahl>-<Länderkürzel>’
    • Rückgabe
      • Ein Status
        • ‘OK’
        • Fehlermeldung ‘illegal isbn <wert> <gültiger bereich>’ oder ‘book for isbn <isbn> not found’ oder ‘book for isbn <isbn> cannot be deleted, cause: <cause>’

75

Javacream

Softwaretest für EntwicklerInnen

76 of 170

Beispiel: StoreService-Operations

  • get_stock
    • Parameter
      • Kategorie ist eine nicht-leere Zeichenkette
      • Item ist eine nicht-leere Zeichenkette
    • Rückgabe
      • die Anzahl der im Bestand vorhandenen Items der angegebenen Kategorie. Es gibt keine unbekannten Kategorien oder Items; hier ist der Stock dann 0

76

Javacream

Softwaretest für EntwicklerInnen

77 of 170

Beispiel: IsbnGeneratorService-Operations

  • next
    • Rückgabe
      • Eine eindeutige ISBN mit dem Format ‘ISBN-<Zahl>-<Länderkürzel>’

77

Javacream

Softwaretest für EntwicklerInnen

78 of 170

xUnit-Pseudocode (Sawitzki)

  • Struktur
    • <Test-Suite>:
      • <Test Case 1>:
      • <Test Case 2>:
      • <Test-Suite 2>:
        • <Test Case 3>:
        • <Test Case 4>:

78

storeservice_test_suite:

store_service_get_stock:

Javacream

Softwaretest für EntwicklerInnen

79 of 170

xUnit-Pseudocode (Sawitzki)

  • Variablen-Deklarationen
    • <name> = <wert>
      • title = ‘Hello’

79

storeservice_test_suite:

store_service_get_stock:

category = 'books'

item = 'ISBN-1234-dk'

expected_stock = 42

Javacream

Softwaretest für EntwicklerInnen

80 of 170

xUnit-Pseudocode

  • Aufruf des Algorithmus
    • result = algorithm(params)

80

storeservice_test_suite:

store_service_get_stock:

category = ‘books’

item = ‘ISBN-1234-dk’

exprected_stock = 42

stock = get_stock(category, item)

Javacream

Softwaretest für EntwicklerInnen

81 of 170

xUnit-Pseudocode

  • Assertions
    • assert_xyz(value1, value2)
      • Im Fehlerfall wird abgebrochen
    • expect_xyz(value1, value2)
      • Im Fehlerfall wird protokolliert und fortgesetzt
    • xyz
      • equals(expected, actual)
      • true(value)
      • false(value)
      • contains(list, element)

81

storeservice_test_suite:

store_service_get_stock:

category = ‘books’

item = ‘ISBN-1234-dk’

expected_stock = 42

stock = get_stock(category, item)

assert_equals(expected_stock, stock)

Javacream

Softwaretest für EntwicklerInnen

82 of 170

xUnit-Pseudocode

  • Programmierung
    • Vergleichsoperatoren (<, >, ==, !=)
      • assert_true(stock >= 0)
    • “OOP-light”
      • assert_true(isbn.ends_with(‘-dk’))

82

Javacream

Softwaretest für EntwicklerInnen

83 of 170

ToDo Schreiben von Tests in xUnit

  • Schreiben Sie Tests für das angegebene Modell der Books-Applikation
    • Hinweis
      • Wir nutzen aktuell noch keine Mocks!
      • Überlegen Sie sich, dass damit nicht "alles" getestet werden kann!
  • Hinweise
    • IsbnGeneratorService -> StoreService -> BooksService
    • Überlegen Sie sich, welche der geschriebenen xUnit-Tests sind Unit-Tests, welche sind Integrationstest?
    • Machen Sie so detailliert wie möglich, aber Sie müssen nicht “alles” formulieren
      • StoreService "komplett"
      • Für BooksService genügt create

83

Javacream

Softwaretest für EntwicklerInnen

84 of 170

Probleme bei den BooksServiceTests

84

Problem!

Problem!

Der Test nutzt 2 (oder mehrere) Operationen und ist damit kein Unit-Test -> Scenario-Test bzw. Story-Test (Sawitzki-Begriffe)

Problem!

Unspezifische Assertion, ich kann nicht testen, dass der BooksService eine vom IsbnGenerator erzeugte ISBN zurückgibt

Javacream

Softwaretest für EntwicklerInnen

85 of 170

Exkurs: Context & Dependency Injection

85

Javacream

Softwaretest für EntwicklerInnen

86 of 170

Context & Dependency Injection

  • Ein (besser DAS) Design Pattern in modernen Anwendungen
    • “Erfunden” 2003
      • CDI ist ein Meta-Pattern aus Factory und Strategy
  • Ausgangssituation
    • Wir haben eine modularisierte Anwendung
      • Durch die Modularisierung wird die Qualität der Software, insbesondere die Testbarkeit erhöht
        • Ein Monolith ist damit qualitativ schlechter
  • Problem
    • Zur Laufzeit besteht die gesamte Anwendung aus einem Geflecht von einzelnen Modulen, die sinnvoll miteinander verbunden sein müssen
      • Der Aufbau dieses Geflechts ist kompliziert!
  • Lösung
    • Ein Context kennt alle Module einer Anwendung und baut das zugehörige Geflecht der Abhängigkeit zentral auf

86

Javacream

Softwaretest für EntwicklerInnen

87 of 170

Beispiel: Modell

87

BooksService

  • create(title, pages, price): isbn | not created
  • find_by(isbn): book | not found
  • find_all(): books
  • update(book): status
  • delete_by(isbn): status

IsbnGeneratorService

  • next(): isbn

StoreService

  • get_stock(category, item): stock

Book

  • isbn <<pk>>
  • title
  • pages
  • price
  • available

n

1

1

Das ist ein Klassendiagramm

Problem: Die Laufzeitumgebung kennt Objekte, keine Klassen

dependency

Javacream

Softwaretest für EntwicklerInnen

88 of 170

Beispiel: Die fertige Books-Anwendung

88

booksService

storeService

isbnGeneratorService

actor

actor2

Javacream

Softwaretest für EntwicklerInnen

89 of 170

Beispiel: Step 1

89

Context

booksService

storeService

isbnGeneratorService

actor

actor2

Der Context erzeugt aus jeder relevanten Klasse ein Objekt

Anmerkung: In den allermeisten Fällen erzeugt der Context aus der Klasse exakt ein Objekt (“Singleton”)

Javacream

Softwaretest für EntwicklerInnen

90 of 170

Beispiel: Step 2

90

Context

booksService

storeService

isbnGeneratorService

actor

actor2

Der Context identifiziert und setzt (“injected”) die Dependencies

Javacream

Softwaretest für EntwicklerInnen

91 of 170

Beispiele

  • Python
  • Java
    • Umsetzung von CDI über das Spring Framework
    • https://github.com/Javacream/org.javacream.training.spring/blob/427975e4fe5143e15fc58773f5dc893c93ef57c9/projects/org.javacream.training.spring/src/main/java/org/javacream/books/warehouse/impl/MapBooksService.java

91

Javacream

Softwaretest für EntwicklerInnen

92 of 170

Ab jetzt

  • Es ist vorauszusetzen, dass eine modularisierte Anwendung CDI-konform implementiert ist
  • Wichtig
    • CDI ist in modernen Anwendungen gesetzt
    • Refactoring hin zu CDI wird durch etablierte Strategien und Frameworks erleichtert
    • In einer CDI-Anwendung ist (mit Ausnahme des Contexts) keine Dependency im Code "hart verdrahtet"

92

Javacream

Softwaretest für EntwicklerInnen

93 of 170

Tests und CDI

  • Die zu testende Anwendung wird durch einen Test-Context definiert
  • Syntax-Erweiterung für xUnit
    • context = fixture:
      • isbngeneratorService=IsbnGeneratorService()
      • storeService=StoreService()
      • booksService=BooksService(isbngeneratorService, storeService)
    • Hinweis
      • Der Context / die Fixture wird für jeden Test Case neu erzeugt
      • Eine Test case-übergreifende Fixture wird ‘static’ genannt
        • eher unüblich, weil damit die Isolation der Test Cases ausgehebelt wird

93

Javacream

Softwaretest für EntwicklerInnen

94 of 170

Test-Treiber

94

Javacream

Softwaretest für EntwicklerInnen

95 of 170

Modell mit Test-Treibern

95

<<implementation>>

BooksService

  • create(title, pages, price): isbn | not created
  • find_by(isbn): book | not found
  • find_all(): books
  • update(book): status
  • delete_by(isbn): status

<<implementation>>

IsbnGeneratorService

  • next(): isbn

StoreService

  • get_stock(category, item): stock

1

1

<<implementation>>

<<test-driver>>

Javacream

Softwaretest für EntwicklerInnen

96 of 170

Exkurs: Realisierung von Test-Treibern in verschiedenen Sprachen

  • Untypisierte Programmiersprachen
    • Typ-Prüfungen finden nur zur Laufzeit statt
    • “Duck typing”
    • Test-Treiber sind dann fast trivial, der Test-Treiber muss halt “nur” die gleichen Operationen anbieten wie die Implementierung
  • Typisierte Programmiersprachen
    • z.B. Java, C#, C++, Python (typed)

96

<<interface>>

Service

<<impl>>

Implementation

<<impl>>

Test-Treiber

Javacream

Softwaretest für EntwicklerInnen

97 of 170

Exkurs: Was war das mit den Interfaces?

97

Actor

Service

  • op1
  • op2

<<interface>>

Service

<<class>>

Impl

<<class>>

Test-Driver

Javacream

Softwaretest für EntwicklerInnen

98 of 170

Test-Treiber Kategorien

  • Dummy
    • Ein Aufruf einer Operation auf einem Dummy gibt einen Standardwert zurück
    • Eine Dummy-Implementierung ist immer komplett trivial
      • return 42 -> Dummy
      • if (p1 = True): return 42 else return 4711 -> Kein Dummy
    • Standardwerte eines Dummies sind einer Dokumentation zu entnehmen
      • Zeichenkette: “String”
      • Zahlen: 0, 0.0
      • Boolean: True
      • Collections: Leere Collections
      • Datenstrukturen: Alle Attribute stehen auf den Standardwerten
    • Hinweis
      • Jedes xUnit-Framework stellt Ihnen für einen Typen Dummies zur Verfügung
      • Ein Dummy wird nicht garantiert fachlich konsistente Daten liefern können

98

Javacream

Softwaretest für EntwicklerInnen

99 of 170

Beispiel

  • Ein Dummy für den BooksService
    • isbn = booksService.create(‘a’, 0, 0)
      • ‘String’
    • book = booksService.find_by_isbn(‘a’)
      • book.isbn -> ‘String’
      • book.title -> ‘String’
      • book.pages -> 0
      • book.price -> 0.0
    • books = booksService.find_all()
      • leere Liste

99

Javacream

Softwaretest für EntwicklerInnen

100 of 170

Dummies und Test CDI

fixture:

isbngeneratorService=Dummy()

storeService=StoreService()

booksService=BooksService(isbngeneratorService, storeService)

100

Javacream

Softwaretest für EntwicklerInnen

101 of 170

Test-Treiber Kategorien

  • Stub
    • Im Endeffekt eine Alternativ-Implementierung
    • Beispiel
      • Richtige Implementierung macht einen Datenbankzugriff
      • Test-Stub macht Dateizugriff, generiert Test-Daten etc. etc.
    • Hinweis
      • Stubs liefern fachlich konsistente Daten
      • Stubs müssen immer gesondert programmiert werden
  • Stubs und Fixtures
    • Nichts neues, statt der eigentlichen Implementierung wird der Stub angegeben
    • isbn_generator = IsbnGeneratorRandomStub()

101

Javacream

Softwaretest für EntwicklerInnen

102 of 170

Test-Treiber Kategorien

  • Mocks (englisch für “Häme”, “Spott” -> “Attrappe”)
    • Ein Mock ist ein Objekt, der 3 Phasen hat
      • Record
      • Play
      • Validate
    • In der Record-Phase wird das Verhalten des Mocks definiert
      • “Wenn die Methode “get_stock(‘books’, ‘ISBN42’)” aufgerufen wird, dann gib zurück den Wert 4711”
    • In der Play-Phase reagiert der Mock auf Aufrufe, und gibt die aufgezeichneten Wert zurück
      • Falls ein nicht aufgezeichneter Aufruf erfolgt, kann ein ‘strict mock’ in der Play-Phase Fehler erzeugen
    • Validate-Phase prüft, ob die aufgezeichneten Operationen auch alle aufgerufen wurden
      • Optionale Phase
  • Hinweis
    • Jedes xUnit-Framework stellt Ihnen Mocks zur Verfügung
    • Ein Mock liefert die aufgezeichneten Daten, die fachlich konsistent sein können

102

Javacream

Softwaretest für EntwicklerInnen

103 of 170

xUnit-Syntax und Mocks

  • Mock-API
    • fixture:
      • storeService = Mock()
      • storeService.expect(get_stock(‘books’, ‘ISBN42’)).and_return(4711)
      • storeService.expect(get_stock(‘books’, ‘ISBN43’)).and_return(10)
      • booksService= BooksService(isbnGenerator, storeService) #play-Phase
    • Innerhalb eines Test Cases
      • storeService.validate()
    • Detail
      • Mocking-Bibliotheken unterstützen “Platzhalter”
        • storeService.expect(get_stock(‘books’, String.any)).and_return(42)
      • Mocks können auch Fehler signalisieren
        • storeService.expect(get_stock(‘this’,’that’)).and_throw(“illegal…”)

103

Javacream

Softwaretest für EntwicklerInnen

104 of 170

ToDo

  • Bisher
    • BooksService-Tests sind Integrationstests
  • Neu
    • Unit-Test mit Dummies
  • Was für Vorteile / Nachteile ergeben sich, wenn mit Mocks gearbeitet wird?
    • Vorteile
      • "Schärfere" Assertions
    • Nachteil
      • Aufzeichnen des Mocks muss erfolgen

104

Javacream

Softwaretest für EntwicklerInnen

105 of 170

Tag 3

105

Javacream

Softwaretest für EntwicklerInnen

106 of 170

Agenda

  • Umgang mit Ressourcen
  • Fixtures mit Containern
  • Spies
  • Weitere Test-Kategorien (Regressionstest, System-Simulation, Smoking Gun-Tests, Security, Gui-Tests)
    • Insbesondere im Zusammenspiel mit Dummies, Mocks und Spies
  • Software-Tests und CI/CD
    • Vom Test zur Test-Pipeline
      • CI/CD -> Vector Seminar
  • Q&A

106

Javacream

Softwaretest für EntwicklerInnen

107 of 170

Idee für die Warm Up-Phase

  • Wann und wie häufig laufen denn die Tests im Kontext "Quellcodeverwaltung / Git"?
  • Mögliche Lösung
    • Software-Entwicklung
      • Speichern
      • Commit
      • Pull- / Merge Request
      • "Release" (Meilenstein / Release)

107

Unit

Integration

System

Javacream

Softwaretest für EntwicklerInnen

108 of 170

Umgang mit Ressourcen

  • Eine Ressource ist eine Dependency
  • Besonderheiten im Umgang mit CDI
    • Eine “Embedded Datenbank” kann als CDI-Objekt aufgefasst werden
      • H2
      • Derby
    • Ein separater Datenbank-Prozess wird über ein konfiguriertes Treiberobjekt angesprochen
  • Testdaten
    • Sind, besonders bei Verwendung einer Embedded Datenbank, Bestandteil der Test-Fixture

108

Javacream

Softwaretest für EntwicklerInnen

109 of 170

ToDo

  • Unter der Voraussetzung, dass Ressourcen in der Fixture definiert und als Dependency injiziert werden können
    • Wie können nun die Tests "schärfer" formuliert werden
  • Check
    • schema.sql und data.sql werden für jeden Service definiert und müssen natürlich nicht valides SQL enthalten

109

Javacream

Softwaretest für EntwicklerInnen

110 of 170

Containers als Fixture

110

Javacream

Softwaretest für EntwicklerInnen

111 of 170

Motivation

  • Die Ressourcen werden über Container bereitgestellt
    • Die Images liegen als Baukastensystem im Image Repository
    • Die Erstellung der Images erfolgt "zentral" bzw. im Rahmen des Projekts

111

Javacream

Softwaretest für EntwicklerInnen

112 of 170

Technik

  • Docker
  • Arbeitsablauf zum Erstellen des Images
    • "ich benötige einen Web Server, der mir eine Web Anwendung bereitstellt"
    • Ein Docker-Entwickler programmiert ein Dockerfile und erzeugt daraus ein Image
    • Push dieses Images auf das allgemeine Image-Repository
  • Arbeitsablauf zum Nutzen des Images
    • "Quick and Dirty"
      • docker run --rm -p 8077:80 javacream/test_web_app:1.0
    • Produktionsumgebung schreibt einen Kubernetes-POD
    • Testumgebung nutzt docker-compose

112

Javacream

Softwaretest für EntwicklerInnen

113 of 170

Anwendungen und Container

  • Moderne Anwendungsprogramme werden heute nicht mehr als "native executable" vertrieben, sondern ebenfalls als Docker-Images
  • Die zu testende Anwendung wird damit ebenfalls als Docker-Container laufen
    • und kann damit ebenfalls in der docker-compose.yml eingetragen werden
  • Hinweis:
    • Die docker-compose.yml definiert quasi CDI für verteilte Services, die über Netzwerk angesprochen werden

113

Javacream

Softwaretest für EntwicklerInnen

114 of 170

Docker Details

114

Javacream

Softwaretest für EntwicklerInnen

115 of 170

Reale Anwendungen

  • Ressourcen
    • Applikationen haben persistenten State
    • Server-Zugriffe
      • Web Server
      • Datenbanken
  • Anwendung ist selbst auch eine Ressource
    • Deployment in
      • Web Server
      • Application Server

115

Javacream

Softwaretest für EntwicklerInnen

116 of 170

Klassische Lösung

  • Aufbau einer Testumgebung

116

Test-Center

MySql-DB

Oracle-DB

Web Server

Application Server

Zu testende Anwendung

deploy

Javacream

Softwaretest für EntwicklerInnen

117 of 170

Moderne Lösung

117

Test-Center

Host

Host

Host

Host

Pool

Host-Maschinen sind allesamt identisch und werden nach Bedarf vom Pool entnommen

Image Repository

Javacream

Softwaretest für EntwicklerInnen

118 of 170

Was ist ein “Image”?

  • Das klassische Image (VMWare, VirtualBox) ist eine komplette Betriebssystem-Installation + darauf installierte Anwendungen
    • Hochfahren dauert ein paar Minuten
  • Ein modernes Image ist ein Template für einen Container
    • Das Image selber enthält nur noch eine Betriebssystem-Distribution (ohne Kernel und damit sehr schlank) + darauf installierte Anwendung
    • Starten eines Containers ist in wenigen Sekunden passiert

118

Javacream

Softwaretest für EntwicklerInnen

119 of 170

Ablauf, Beispiel Container

  • containerd | docker run image_name:tag
    • Transfer des Images in ein lokales Host-Image-Repository
    • Erzeugen eines Containers daraus
    • Starten des Containers
  • docker run --rm -p host_port:container_port image_name:tag
  • docker run --rm -v /host-path:container_path

119

Javacream

Softwaretest für EntwicklerInnen

120 of 170

Aufbau der Testumgebung, eine Möglichkeit

120

Skript mit docker run-Anweisungen wird auf einem Host im Data Center ausgeführt

Host

nginx

mysql

application server

port

Javacream

Softwaretest für EntwicklerInnen

121 of 170

Besser: Docker Compose

121

docker-compose.yml wird auf dem Host mit docker-compose up gestartet

Host

nginx

mysql

application server

port

Javacream

Softwaretest für EntwicklerInnen

122 of 170

Stand bisher

  • Mit docker-compose können alle notwendigen Ressourcen im Test Center mit einem einzigen Befehl bereitgestellt werden
  • Es fehlt
    • Bestücken der Container mit Konfiguration / Daten
    • Deployment der Anwendung

122

Javacream

Softwaretest für EntwicklerInnen

123 of 170

Das Dockerfile

  • Im Endeffekt ein Installationsskript
  • Beispiel
  • Es ist in der Verantwortung der Entwickler von Anwendungen, diese in ein Docker-Image umzuwandeln
    • Ausnahme: Native Applications wie z.B. Treiber etc.

123

Javacream

Softwaretest für EntwicklerInnen

124 of 170

Erstellen eigener Images

  • Eigentlich sehr einfach
  • Dockerfile
  • Damit ist möglich
    • das Deployment der Anwendung als Container
    • Konfiguration von Servern und das Einspielen von Datenbeständen

124

Javacream

Softwaretest für EntwicklerInnen

125 of 170

Zusammenfassung

  • Ressourcen für eine Testausführung werden über Container realisiert
    • Starten der Testumgebung ist ein Einzeiler
      • docker-compose up
    • Aufräumen der Testumgebung ist ein Einzeiler
      • docker-compose down
  • Ist die zu testende Anwendung selber ebenfalls eine Ressource (insbesondere ein RESTful Web Service) wird die Anwendung in ein Docker Image verpackt
    • und ebenfalls über einen Container gestartet

125

Javacream

Softwaretest für EntwicklerInnen

126 of 170

Spies

126

Javacream

Softwaretest für EntwicklerInnen

127 of 170

Ein simples Modell

127

Actor

{

...

}

Service

{

}

Javacream

Softwaretest für EntwicklerInnen

128 of 170

Erweiterung: Wir benötigen zusätzliche Logik

128

Actor

{

...

}

Service

{

}

{

1…

}

Diese zusätzliche Logik gehört weder in den Actor, noch in den Service

  • insbesondere ist das Test-Logik
    • Tracing (1)
    • Performance (2)

Test

{

...

}

{

2…

}

Test

{

...

}

{

1…

}

{

X…

}

Javacream

Softwaretest für EntwicklerInnen

129 of 170

Modell mit Aspekten

129

<<implementation>>

BooksService

  • create(title, pages, price): isbn | not created
  • find_by(isbn): book | not found
  • find_all(): books
  • update(book): status
  • delete_by(isbn): status

<<implementation>>

IsbnGeneratorService

  • next(): isbn

StoreService

  • get_stock(category, item): stock

1

1

<<implementation>>

<<test-driver>>

Decorator

Aspect

Querschnittsfunktion

Cross Cutting Concern

Javacream

Softwaretest für EntwicklerInnen

130 of 170

Aspekte im Rahmen des Testens

  • Tracing
    • Protokollierung von Operations-Aufrufen mit ‘entering’, ‘returning’, ‘throwing’
    • Analog: Debugging
  • Performance
    • Messung der Dauer des Operations-Aufrufs

130

Javacream

Softwaretest für EntwicklerInnen

131 of 170

Aspekte im Rahmen der Anwendungsprogrammierung

  • Authentifizierung und Autorisierung
  • Transaktionssteuerung
  • Parametervalidierung

131

Diese Aspekte werden in der Regel von der Plattform der Anwendung realisiert, nicht selber programmiert

Javacream

Softwaretest für EntwicklerInnen

132 of 170

Aspekte im Test-Umfeld

  • Simple Umbenennung
    • ‘Spy’ statt ‘Aspekt’
  • Es existiert in einer Testumgebung ein Satz vordefinierter Spies
  • Eigene Spies sind im konkreten xUnit-Framework recht einfach zu erstellen
  • Syntax für xUnit
    • Spy(TRACE, object)

132

Javacream

Softwaretest für EntwicklerInnen

133 of 170

Beispielcode

133

Javacream

Softwaretest für EntwicklerInnen

134 of 170

Einsatzbereiche

  • Wie bereits präsentiert
    • Tracing
    • Performance
      • Neues Kriterium: Ein Test schlägt fehl, wenn ein vorgegebenes Zeitlimit überschritten wird
  • ToDo: Kurz überlegen, was könnten man denn alles machen…

134

Javacream

Softwaretest für EntwicklerInnen

135 of 170

Bisher: Lokale Dependencies

135

<<implementation>>

BooksService

  • create(title, pages, price): isbn | not created
  • find_by(isbn): book | not found
  • find_all(): books
  • update(book): status
  • delete_by(isbn): status

IsbnGeneratorService

  • next(): isbn

StoreService

  • get_stock(category, item): stock

1

1

Bisher laufen alle Module in einem einzigen Prozess, einem einzigen Heap-Speicher, Dependency ist eine Referenz

Javacream

Softwaretest für EntwicklerInnen

136 of 170

Szenarium: Wie würde sich die Anwendung verhalten, wenn die Services remote angesprochen werden?

136

<<implementation>>

BooksService

  • create(title, pages, price): isbn | not created
  • find_by(isbn): book | not found
  • find_all(): books
  • update(book): status
  • delete_by(isbn): status

IsbnGeneratorService

  • next(): isbn

StoreService

  • get_stock(category, item): stock

1

1

Problem

  • Um hier einen Integrationstest durchzuführen, müsste nun eine komplexe Testumgebung aufgebaut werden
    • Das ist damit ein System-Test

Javacream

Softwaretest für EntwicklerInnen

137 of 170

Idee: “Netzwerk-Simulator”

  • Aufgaben
    • Sämtliche Daten = Parameter und Rückgabewerte werden serialisiert / encodiert übertragen
      • Das ist im Endeffekt eine Änderung einer “Call-by-Reference” in eine “Call by Value”-Semantik
    • Einstellung einer konfigurierbaren Netzwerklatenz

137

Javacream

Softwaretest für EntwicklerInnen

138 of 170

Umsetzung

  • Das wird ein Spy

138

<<implementation>>

BooksService

  • create(title, pages, price): isbn | not created
  • find_by(isbn): book | not found
  • find_all(): books
  • update(book): status
  • delete_by(isbn): status

IsbnGeneratorService

  • next(): isbn

1

Network Simulator

Javacream

Softwaretest für EntwicklerInnen

139 of 170

Andere Ideen

  • (Zufälliges) "Ich gebe keine Antwort"
  • (Erratisches) Exception-Werfen

139

Javacream

Softwaretest für EntwicklerInnen

140 of 170

Player-"Spy"

  • Ein Player ruft einfach Service-Operationen mit (zufälligen) Parameterkombinationen auf
    • Interessant übrigens auch für Security-relevante Tests
      • Buffer-Overflow bzw. Denial of Service
    • Smoking Gun-Tests

140

Javacream

Softwaretest für EntwicklerInnen

141 of 170

Weitere Ideen

  • “Amok-Runner”
    • Aufrufe von Operationen werfen sofort oder nach einem einstellbaren Delay einen Fehler
    • Realisierung
      • Dummy mit Standard-Wert “Werfe Exception“
      • Mock
        • isbngeneratorMock.expect(next()).and_throw(exception)
      • Spy
        • Detaillierte Implementierung ist möglich, “Werfe nur alle paar mal, ... ”
  • Blocker
  • “Amok Runner 2”
    • CPU + Heap-Last

141

Javacream

Softwaretest für EntwicklerInnen

142 of 170

Ergebnis

  • Ihr verwendetes xUnit-Framework wird über einen Satz von fertigen Spies und Dummies ergänzt
  • Das Ganze ist ein kombinierbares Baukastensystem

142

Javacream

Softwaretest für EntwicklerInnen

143 of 170

Nächstes Szenario

  • Ausgangssituation
    • Unsere zu testende Applikation nutzt eine externe Ressource
      • Datenbank
      • Web Service
    • Ein System-Test für die Features der Version 1.0 wird aufgesetzt und durchgeführt
    • Test-Ausführung ist erfolgreich
    • booksService bekommt den Release 1.0

143

booksService 1.0

Test 1.0

http

Test Web Server

mit

Service

Javacream

Softwaretest für EntwicklerInnen

144 of 170

Nächstes Szenario

  • Der booksService wird weiterentwickelt
    • 1.0.1 (Patch / Bugfix), 1.1 (kompatible Erweiterung)
    • Ein System-Test wird aufgesetzt
      • Was muss getestet werden? -> Features von 1.1
      • Zusätzlich muss aber ein Regressionstest der Features 1.0 durchgeführt werden, um eine potenzielle Erosion der bereits getesteten Features zu erkennen

144

booksService

1.1

Test 1.0

http

Test Web Server

mit

Service

Test 1.1

Javacream

Softwaretest für EntwicklerInnen

145 of 170

Problem

  • Können wir uns das Aufsetzen der externen Ressource für den Regressionstest nicht sparen?
  • Lösungsidee
    • Wir zeichnen die Aufrufe an das externe System auf und Speichern diese als einfache Datei
    • Bei der Durchführung des erfolgreich laufenden Tests der Version 1.0 wird die Kommunikation in eine Datei protokolliert

145

Javacream

Softwaretest für EntwicklerInnen

146 of 170

Idee

146

booksService 1.0

Test 1.0

http

Test Web Server

mit

Service

File 1.0

Javacream

Softwaretest für EntwicklerInnen

147 of 170

Umsetzung

147

booksService 1.0

Test 1.0

http

Test Web Server

mit

Service

Recorder

Spy

File 1.0

Javacream

Softwaretest für EntwicklerInnen

148 of 170

Code-Scratch

Spy-Implementierung des Recorder

testframework.generateSpy(storeService, function(params){

recordFile.append(delegate.invokedMethod)

recordFile.append(serialize(params))

result = delegate.invoke(params)

recordFile.append(serialize(result)

return result

})

Record-File

get_stock, {category: “books”, item: “ISBN42”},27

get_stock, {category: “books”, item: “ISBN0”}, 0

...

148

Javacream

Softwaretest für EntwicklerInnen

149 of 170

Regressionstest

149

booksService

1.1

Test 1.0

Test 1.1

File 1.0

?

Javacream

Softwaretest für EntwicklerInnen

150 of 170

Lösung: Regressionstest

150

booksService

1.1

Regressionstest 1.0

Test 1.1

File 1.0

Player

Test Stub

Javacream

Softwaretest für EntwicklerInnen

151 of 170

Pseudo-Code

playerMock(expect(anything)).and_return(next_line_in_file)

komplexer

playerMock(expect(anything)).and_return(search_line_for_operation_and_params)

151

Javacream

Softwaretest für EntwicklerInnen

152 of 170

Sinnvolle Idee?

152

booksService

Actor

/

Test

Recorder

Spy

File

Ressourcen

/

andere Services

Javacream

Softwaretest für EntwicklerInnen

153 of 170

Sinnvolle Idee? Ja

153

booksService

Player

File

Ressourcen

/

andere Services

  • Benutzer-Interaktionen
  • Parallelisierte Ausführung z.B. für einen Lasttest
  • Wiederholte Ausführung als Langzeittest

Javacream

Softwaretest für EntwicklerInnen

154 of 170

Weitere Idee: Aufzeichnung eines Anwendertests

154

booksService

Anwender

GUI

Recorder

Spy

File

Ressourcen

/

andere Services

Javacream

Softwaretest für EntwicklerInnen

155 of 170

Weitere Idee: Aufzeichnung eines Anwendertests

155

booksService

Anwender

GUI

Recorder

Spy

Test

File

Player

booksService

Javacream

Softwaretest für EntwicklerInnen

156 of 170

Potenzielle weitere Ideen mit diesem File

156

File

Player

booksService

Player

Player

Editor

File

Player

booksService

Parallelisierbarer Lasttest

Javacream

Softwaretest für EntwicklerInnen

157 of 170

GUI-Tests

157

Javacream

Softwaretest für EntwicklerInnen

158 of 170

Beispiel: Selenium, Web Testing Tool

158

File

Browser 1

Player

Selenium Grid

Editor

File

Selenium IDE

(Firefox PlugIn)

booksService

Web Anwendung

Test in unterschiedlichen Plattformen (Edge, Firefox, Chrome, Safari)

Browser 2

Browser 3

Javacream

Softwaretest für EntwicklerInnen

159 of 170

GUI Recorder

159

booksService

Anwender

GUI

Recorder

Spy

File

Event Queue

Gui Recorder sind fertige Lösungen

  • z.B. Selenium für Web Anwendung
  • Gui Recorder für Windows / Linux / Mac
    • frei
    • kommerziell

Javacream

Softwaretest für EntwicklerInnen

160 of 170

Beispiel: Selenium, Web Testing Tool

160

Selenium Script

  • Java
  • Python
  • C#

Browser 1

Player

Selenium Grid

Test in unterschiedlichen Plattformen (Edge, Firefox, Chrome, Safari)

Browser 2

Browser 3

Python-Beispiele unter

https://github.com/Javacream/org.javacream.training.selenium

Javacream

Softwaretest für EntwicklerInnen

161 of 170

Umgang mit Legacy-Applikationen

161

Javacream

Softwaretest für EntwicklerInnen

162 of 170

Monolithische Applikationen

162

Monolith

Actor

API

Test

DB

NoSQL

File Share

Directory

Javacream

Softwaretest für EntwicklerInnen

163 of 170

Refactoring: Identifikation von Modulen

163

Monolith

Actor

API

Test

DB

NoSQL

File Share

Directory

Module 1

Module 3

Test 1

Test 2

Test 3

Module 2

Javacream

Softwaretest für EntwicklerInnen

164 of 170

Refactoring: CDI-Kompatibilität

164

Monolith

Actor

API

Test

DB

NoSQL

File Share

Directory

CDI

Module 1

CDI

Module 3

Test 1

Unit/Integration…

Test 2

Unit/Integration…

Test 3

Unit/Integration…

CDI

Module 2

Javacream

Softwaretest für EntwicklerInnen

165 of 170

Analyse: Service-Kompatibilität

165

Monolith

Actor

API

Test

DB

NoSQL

File Share

Directory

CDI

Module 1

CDI

Module 3

Test 1

Network Simulator

Test 2

Network Simulator

Test 3

Unit/Integration…

CDI

Module 2

Javacream

Softwaretest für EntwicklerInnen

166 of 170

Service-Kompatibilität

166

Service 1

Actor

API

Test

DB

Service 2

NoSQL

File Share

Directory

CDI

Module 1

CDI

Module 3

Test 1

Test 2

Test 3

CDI

Module 2

Javacream

Softwaretest für EntwicklerInnen

167 of 170

Exkurs CI/CD

167

Javacream

Softwaretest für EntwicklerInnen

168 of 170

CI/CD-Prozess

168

Source Code Management (GitHub, GitLab)

Repo mit Quellcodes, Tests, Pipeline…

Developer

Developer

Developer

Developer

Build Machine

(Jenkins, GitLab CI/CD)

Jobs = Pipeline

trigger = akzeptierter Pull Request

Artefakt-Repository

  • Binaries der Anwendung
  • Images

Betrieb

trigger: Release

Test & QA

trigger: Build

push

Pull Request

Javacream

Softwaretest für EntwicklerInnen

169 of 170

Tests, Pipelines: Aufgabenverteilung

  • Die Developer werden auf Ihren Maschinen vor einem push sämtliche Unit-Tests laufen lassen
    • Ausführung erfolgt in der Regel in der Entwicklungsumgebung
  • Alle weiteren Tests (Integration, System) werden in Pipelines definiert
    • Typische Sequenz einer Pipeline

Baue das Artefakt der eigentlichen Anwendung

Hier laufen die Unit-Tests meistens nochmal

Stelle im Test Center die benötigten Systeme zur Verfügung

Lasse alle Integrations / Systems -Tests laufen

Bringe das Artefakt aus

  • Regressionstests laufen scheduled

169

Javacream

Softwaretest für EntwicklerInnen

170 of 170

Ergänzung: Software-Qualität

  • Software-Qualität wird durch einen Satz anerkannter Metriken bestimmt
    • Lines of Code
    • Dependency Analyse
    • Test-Abdeckung, Coverage
      • Coverage wird von Testing-Frameworks optional bestimmt
    • Anzahl der gemeldeten Fehler
  • Security Scans mit Black Duck

170

Javacream

Softwaretest für EntwicklerInnen