Export_Kartei_Beispiel für eine Lernkarte_2018_07_06.json 12.8 KB
Newer Older
1
{"name":"C: Beispiel für eine Lernkarte","description":"Die Lernkartei ist Teil der Demo-Kartei, siehe den roten Button auf der Startseite.","date":"2018-05-25T07:24:31.276Z","dateUpdated":"2018-07-06T04:27:51.347Z","editors":[],"owner":"jCZ6oHcbZhJaKKodN","visible":false,"ratings":true,"kind":"personal","price":0,"reviewed":false,"reviewer":"undefined","request":false,"relevance":0,"raterCount":0,"quantity":1,"license":["by","nc","nd"],"userDeleted":false,"learningActive":false,"maxCards":1,"daysBeforeReset":7,"learningStart":"2018-05-25T07:24:31.276Z","learningEnd":"2038-01-19T19:42:43.323Z","learningInterval":[1,3,7,28,84],"learners":1,"wordcloud":false,"shuffled":false,"cardType":0,"difficulty":1,"originalAuthor":"Quibeldey-Cirkel, Klaus, Dr."}, {"subject":"Test-Pyramide","difficulty":1,"centerTextElement":[false,false,false,false],"date":"2018-05-25T07:31:40.262Z","learningGoalLevel":0,"backgroundStyle":1,"learningIndex":"0","learningUnit":"0","cardType":0,"front":"Die Test-Pyramide von Mike Cohn dient als **Metapher für die Testautomation**.\n\n![Test-Pyramide nach Mike Cohn ([Zeichnung von Ham Vocke](https://martinfowler.com/articles/practical-test-pyramid.html))](https://martinfowler.com/articles/practical-test-pyramid/testPyramid.png)\n\n!!! Tip Lernziel\n   Sie sollen den Aufbau der Test-Pyramide beschreiben können und verstehen, welche automatisierten Tests in welcher Quantität und Qualität für eine CI/CD-Pipeline erforderlich sind. </br> </br>\n\n","dateUpdated":"2018-07-06T04:27:51.338Z","back":"Die **Test-Pyramide** ist ein Konzept, ursprünglich von **Mike Cohn** vorgestellt, das eine anschauliche Gliederung von automatisierten Testprozessen in drei Schichten vorschlägt:\n\n1. **Unit Tests** (viele und möglichst kleine Tests von Funktionen und Klassen)\n2. **Service Tests** (weitere, gröbere Tests unter Beteiligung externer Dienste)\n3. **User Interface Tests** (möglichst wenige End-to-End-Akzeptanztests)\n\n!!! Tip Merke \n   Tests werden mit **unterschiedlicher Granularität** geschrieben und **je höher die Ebene, desto weniger Tests**! </br></br>\n","hint":"**Fowler, Martin (2006)**: *”TestDouble”*. Online-Artikel, veröffentlicht: 17. Januar 2006. URL: https://martinfowler.com/bliki/TestDouble.html (Stand: 25.05.2018). \n\n**Vocke, Ham (2018)**: *\"The Practical Test Pyramid\"*. Online-Artikel, veröffentlicht: 26. Februar 2018. URL: https://martinfowler.com/articles/practical-test-pyramid.html (Stand: 25.05.2018)\n\n![\"The Practical Test Pyramid\", Zeichnung von Ham Vocke](https://martinfowler.com/articles/practical-test-pyramid/teaser.png)\n\n---\n\n!!! TIP Hinweis\n   Diese **Lernkarte** bereitet den Inhalt des Artikels [The Practical Test Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html) von Ham Vocke auf. Im Zentrum steht die **Test Pyramide** von Mike Cohn und die **Testautomation** im Kontext einer _Continuous Delivery Pipeline_. Das Thema Testautomation wurde von den Teilnehmern des Master-Informatikkurses \"Continuous Delivery\" im SoSe 2018 am Fachbereich MNI der THM bearbeitet.</br></br>Während des Semesters erstellten die Studenten auf .cards jeder für sich ein Kursglossar, Lernkarteien zu einzelnen Kursinhalten, eine Zitatensammlung und eine Prüfungskartei mit insgesamt ca. 200 Karten. In den Sommerferien lernten sie kontinuierlich ca. 500 Karten -- max. 20 täglich -- nach der [5-Fächer-Lernmethode von Sebastian Leitner](https://de.wikipedia.org/wiki/Lernkartei). Wer dies befolgte, erhielt für seine Lernleistung einen Bonus von 15 Prozent auf die Klausurnote. Die Klausur umfasste 15 zufällige Lernziel- und Prüfungsfragen aus allen Lern- und Prüfungskarteien sowie eine Transferaufgabe.\n\n!!! NOTE Danksagung\n   Die Lernkarte basiert auf einer Exzerpt-Karte des Kursteilnehmers Felix Brück. ","lecture":"# The Importance of (Test) Automation\nSoftware wird immer wichtiger und bestimmt zunehmend den Alltag. Um mithalten zu können, muss Software schneller entwickelt werden können, ohne an Qualität einzubüßen. \n\n**Continuous Delivery**, ist eine Praxis, bei der eine **Buildpipeline** zum automatischen Testen eingesetzt wird und die damit einen beschleunigten Softwareentwicklungsprozess unterstützen kann, indem sie repetitive, umständliche, händische Tests durch Automatisierung ersetzen und effizienter machen.\n\n# The Test Pyramid\n![Die Test-Pyramide](https://martinfowler.com/articles/practical-test-pyramid/testPyramid.png)\n\nDie **Test-Pyramide** ist ein Konzept, ursprünglich von *Mike Cohn* vorgestellt, das eine simple Gliederung bei der Erstellung von Testsuiten in grob drei Schichten vorschlägt:\n\n1. **Unit Tests** *(viele und möglichst kleine Tests)*\n2. **Service Tests** *(weitere, gröbere Tests)*\n3. **User Interface Tests** *(möglichst wenige High-Level End-to-End-Tests)*\n\n!!! Tip Merke \n   Tests werden mit **unterschiedlicher Granularität** geschrieben und **je höher die Ebene, desto weniger Tests**\n\n\n# Unit Tests\n![Unit Tests ersetzen externe Objekte mit Test Doubles](https://martinfowler.com/articles/practical-test-pyramid/unitTest.png)\n\n**Unit Tests** dienen als eine Art Sicherheitsnetz bei Codeänderungen (weshalb sie auch nicht zu stark an die Implementierung gebunden sein sollten) ([Vocke 2018](https://martinfowler.com/articles/practical-test-pyramid.html#WhatToTest)).\n\nAllgemein soll getestet werden, ob eine **Unit** (Einheit) so funktioniert wie erwartet. Dabei ist nicht genau definiert, was eine „Unit“ ist. In einer funktionalen Programmiersprache wären dies z.B. Funktionen, in einer OO Sprache könnten es einzelne Methoden oder ganze Klassen sein [Vocke 2018](https://martinfowler.com/articles/practical-test-pyramid.html#UnitTests).\n\n## Mocking and Stubbing\nUm automatische Tests einfach und möglichst schnell zu halten, werden **Mocks** und **Stubs** benutzt, die anstelle von z.B. teuren Datenbankaufrufen oder HTTP-Queries verwendet werden. Außerdem dienen sie zur Vermeidung von Seiteneffekten und komplexen Testsetups. Es werden also reale Module/Klassen/Funktionen/etc. durch Fake-Versionen ersetzt, die dieselbe Signatur aufweisen. \nDiese sogenannten **Test Doubles** umfassen u.a. (vgl. [Fowler 2006](https://martinfowler.com/bliki/TestDouble.html)):\n- **Mocks**: Sind vorprogrammiert mit Erwartungen an Aufrufen, die sie gemäß den Spezifikationen ihrer realen Vorbilder erhalten sollten, um zu testen, ob alle erwarteten Aktionen ausgeführt werden. Bei unerwarteten Aufrufen können sie Exceptions auswerfen.\n\n- **Stubs**: Sie enthalten vorgefertigte Antworten, die sie für Aufrufe während der Testphase verwenden.\n\n!!! NOTE Hinweis\n   Es wird oft unterschieden zwischen **solitary Unit Tests**, bei denen alles durch Stubs und Mocks ersetzt wird und **sociable Unit Tests**, bei denen teilweise mit den realen Objekten getestet wird.\n\n## What to Test?\nGrundsätzlich können Unit Tests für alle Klassen (unabhängig von ihrer Funktion) eingesetzt werden. Es empfiehlt sich jedoch, nur **eine Testklasse pro Produktions-Klasse** zu schreiben. Dabei sollte eine Testklasse **mindestens das *public*-Interface der Klasse abdecken**. ([Vocke 2018](https://martinfowler.com/articles/practical-test-pyramid.html#WhatToTest))\n\nUnit Tests sollten nicht 100% des Codes abdecken, sondern sich auf nicht-trivialen Testpfade (z.B. Happy Path und Grenzwerte) beschränken. Dabei sollten sie nicht zu implementierungsspezifisch sein, da sie sonst - etwa nach einem Refactoring - umgeschrieben werden müssten.\n\n## Test Structure\nEine gute und grundlegende Struktur für Tests allgemein, sieht wie folgt aus (vgl. [Vocke 2018](https://martinfowler.com/articles/practical-test-pyramid.html#TestStructure)):\n1. Testdaten einrichten\n2. Zu testende Methode aufrufen\n3. Sicherstellen, dass die erwarteten Ergebnisse zurückgegeben werden.\nDiese kann man sich auch durch die Alliteration [Arrange, Act, Assert](https://xp123.com/articles/3a-arrange-act-assert/) merken.\n\n\n\n# Integration Tests\nWie der Name vermuten lässt, testen **Integration Tests** die Integration der eigenen Applikation mit applikationsexternen Services (Datenbank, Dateisystem, Netzwerkaufrufe, REST APIs, etc.).\nEs geht also um Fälle, in denen Aktionen die Integration externer Dinge triggern. \n\nIm Falle eines Datenbankaufrufs, könnte dies bspw. so aussehen:\n1. Datenbank starten\n2. Applikation mit DB verbinden\n3. Funktion triggern, die in die DB schreibt\n4. Testen, ob die erwarteten Daten geschrieben wurden, indem man sie aus der DB lädt\n\nGenerell sollten Integration Tests für alle Fälle geschrieben werden, bei denen **Daten serialisiert oder deserialisiert** werden, um sicherzustellen, dass alle externen Abhängigkeiten/Kollaborateure wie erwartet funktionieren. Also z.B. bei:\n- Aufrufe an REST APIs\n- Lesen/Schreiben auf Datenbanken oder Queues\n- Schreiben auf das Dateisystem\n\nEs sollte dabei mit lokalen Instanzen der Abhängigkeiten gearbeitet werden und **nicht mit realen Produktivsystemen** (bei unzähligen automatisierten Tests kann dies im schlimmsten Falle zu einem Denial of Service führen). Ist es nicht möglich, eine eigene Instanz laufen zu lassen, sollten Fake-Versionen implementiert werden, die das reale Verhalten nachahmen. \n\n![Integration mit separatem Service](https://martinfowler.com/articles/practical-test-pyramid/httpIntegrationTest.png)\n\n\n# Contract Tests\nEs kann sein, dass Softwareentwicklung derart organisiert ist, dass unterschiedliche Teams an unterschiedlichen Serviceimplementierungen arbeiten, die zum Schluss zu einem großen, zusammenhängenden System zusammengefügt werden. \n\nDiese unterschiedlichen Services kommunizieren über Interfaces miteinander (dazu nutzen sie etwa REST und JSON via HTTPS, RPC oder bei einer eventgesteuerten, asynchronen Anwendung via Queues oder Channels). Dann ist immer ein Service ein **Consumer** (der Daten abruft) und der andere ein **Provider** (der Daten bereitstellt). </br>(Bei asynchronen Anwendungen auch **Publisher** und **Subscriber**).\n\nDie Spezifikation eines Interfaces kann als **Contract** (Vertrag) angesehen werden.\n\nBeim **Consumer-Driven Contract Test (CDC)** übernimmt das Team des Consumer-Services die Implementierung des Vertrags. Es schreibt also Tests, die das Interface auf alle Daten prüfen, die es benötig/erwartet, um diese dann an das Provider-Team weiterzugeben. Dieses entwickelt nun die API nach diesen Tests. Dabei durchlaufen alle Änderungen kontinuierlich die Tests in der Buildpipeline. Bei Problemen tauschen sich die Teams aus. (Vgl. [Vocke 2018](https://martinfowler.com/articles/practical-test-pyramid.html#ContractTests))\n\n![Consumer-Driven Contract Tests](https://martinfowler.com/articles/practical-test-pyramid/cdc_tests.png)\n\n\n# UI Tests\n**UI Tests** prüfen, ob das User Interface wie erwartet auf Interaktionen reagiert (dazu zählen Webinterfaces genauso, wie Kommandozeilen-Interfaces oder REST API). Dabei kann auf Dinge geachtet werden wie *Verhalten, Layout, Usability* oder *Wahrung des Corporate Designs*.\n\nUI Tests müssen keine vollständigen End-to-End-Tests sein. Dies kann z.B. auch mit Unit Tests gemacht werden, in dem der Frontend-Code mit Backend-Stubs getestet wird.\n\n![](https://martinfowler.com/articles/practical-test-pyramid/ui_tests.png)\n\n!!! NOTE\n   Während das Verhalten automatisiert (z.B. mit Tools wie Selenium) getestet werden kann, kommt man spätestens beim Look & Feel an die Grenzen der Automatisierung.\n\n\n# End-to-End Tests\n**End-to-End Tests** (manchmal auch **Broad Stack Tests**) prüfen die Applikation über ihr eigenes Interface. UI Tests können ebenfalls zu hierzu zählen.\n\nJe komplexer das User Interface ist, desto mehr Probleme können bei Tests auftreten. Doch auch Eigenarten unterschiedlicher Browser können Fehlverhalten verursachen.\nBei Entwicklung der Tests sollte sich auf die Kernanwendungen/interaktionen der Endnutzer konzentriert werden, um Vorlagen für automatisierte Tests dafür zu erstellen (bspw. Produktsuche, Warenkorb und Bezahlen in einem Webshop).\n\nDiese Tests sind sehr zeit- und ressourcenaufwendig und sollten – wie von Cohn empfohlen – auf ein Minimum reduziert werden. Die Lowlevel-Funktionen sollten sowieso bereits auf den unteren Ebenen der **Test-Pyramide** getestet worden sein.\n\n![End-to-End Tests testen das ganze, voll integrierte System](https://martinfowler.com/articles/practical-test-pyramid/e2etests.png)\n\n# Weitere Anmerkungen\n- Neben automatisierten Tests ist es auch sinnvoll, einige Tests selbst durchzuführen und zu testen, wie man Fehlverhalten der eigenen Anwendung provozieren kann. Feedback und Ergebnisse können dokumentiert werden, um sie später in die Tests zu integrieren.\n\n- Es dreht sich beim automatisierten Testen alles um schnelles Feedback. Es ist daher sinnvoll, die Testpipeline so zu gestalten, dass langsame Tests gegen Ende ablaufen, um die einfachen und schnellen nicht aufzuhalten.","originalAuthor":"Quibeldey-Cirkel, Klaus, Dr."}