p.blog
Unternehmenskultur, Softwareentwicklung und Architektur

9. Juni 2020

Testing in Boxes

8 Minuten Lesedauer

Inside the out … äh … outside the in?

Dass es unterschiedliche, teils widersprüchliche Sichtweisen auf automatisierte Software-Tests gibt, haben wir schon beleuchtet. Das der Blick auf White- und Black-Box-Tests mindestens genauso ambivalent sein kann, überrascht vielleicht doch. Und zeigt, dass die Sicht auf White/Black-Box-Tests stark vom Kontext abhängt. Wir haben uns dafür entschieden, die Realität nicht weiter zu verbiegen, sondern dies zu akzeptieren und uns auf den resultierenden Teufelskreis einzulassen. Also haben wir White- und Black-Box-Tests aus zwei Blickwinkeln beleuchtet, letztere natürlich mit Schwarzlicht.
Viel Spaß beim Lesen von Are you ready to think outside the box? und Testing in Boxes.

Zuletzt hatte Ramon einen ausführlichen Blick auf die Gründe und Ziele für automatisiertes Testen geworfen. Dabei konnten wir eine ganze Menge unterschiedlicher Charaktere kennenlernen, die teilweise etwas gegensätzlich schienen. Wir wissen nun, welche Ziele sie verfolgen, und betrachten heute verschiedene Möglichkeiten des Testens von Software.

Dabei reduzieren wir uns zunächst auf zwei Ansätze: schwarz und weiß. Außerdem tun wir, wozu wir Softwerker gelegentlich neigen: Wir denken in Kisten, die wir dann wieder verlassen können – kaum eine Diskussion am Whiteboard kommt ohne sie aus. Wenden wir das auf das Testen von Software an, stehen wir erstmal vor einer schwarzen und einer weißen Kiste.

 

Black Box

Die schwarze Kiste, unsere Black Box, ist ganz schön dunkel. Wir sehen kaum die Hand vor Augen. Eigentlich können wir überhaupt nichts erkennen, so dunkel ist es.

Photo by Majid Rangraz on Unsplash

 

Manchmal ist das gar nicht so verkehrt. Was ich nicht weiß, macht mich nicht heiß. Und dass dieses Ding hier eine Kiste ist, ist für den Moment vielleicht schon Information genug.

Was ist nämlich, wenn es genau darum geht und nicht um mehr? Wir wollen gar nicht mehr wissen von unserer Kiste.

Von außen ist sie ja trotz allem gut zu erkennen. Sechs Seiten, jeweils vier Ecken, nicht zu groß und nicht zu klein – eindeutig eine Kiste. Darauf können wir uns verlassen und zum Beispiel Dinge darauf abstellen oder aufbauen.

Genauso ist es mit Software auch. Die Details interessieren uns gar nicht, die würden uns wahrscheinlich nur verwirren und ablenken. Was zählt, ist in der Regel einzig und allein das Verhalten: Wenn wir etwas auf unserer Kiste abstellen oder eine vielleicht ziemlich fragile Konstruktion darauf aufbauen, wollen wir ja sichergehen, dass die Kiste nicht in sich zusammenfällt und alles mit sich reißt. Sie soll sich so verhalten wie wir es von ihr erwarten.

Dementsprechend verstehen wir in der Software-Welt unter Black-Box-Testing das Testen von Verhalten (behavioral testing). Wir nehmen dabei keinerlei Bezug auf interne Aspekte. Und auch wenn wir sie eigentlich kennen, schalten wir für den Wechsel der Perspektive das Licht aus.

Das ermöglicht uns ein unvoreingenommenes Herangehen an den Test. Mit Black-Box-Tests können wir feststellen, ob unsere Annahmen über die Kiste möglicherweise falsch sind. Warum sie im Detail falsch sind, ist letztendlich unerheblich. Das gilt insbesondere, wenn wir mit einer Box zu tun haben, auf die wir keinen Einfluss haben. Das gilt ebenfalls beim Zusammenspiel von verschiedenen Boxen. In Zeiten verteilter Architekturen ist das immerhin eher die Regel als die Ausnahme.

Black-Box-Tests ermöglichen uns also festzustellen, ob

  • Funktionen fehlen oder anders funktionieren als wir dachten,

  • Schnittstellen fehlerhaft sind,

  • Datenstrukturen oder der Zugriff auf externe Datenbanken nicht so funktionieren wie erwartet oder

  • das allgemeine Verhalten oder die Performance grundsätzlich von unseren Erwartungen oder Anforderungen abweichen.

Dementsprechend kommen Black-Box-Tests vor allem zum Einsatz, wenn der Fokus auf Schnittstellen liegt – in API-Smoke-Tests oder Systemintegrationstests. Dabei tun wir einfach so, als hätten wir keine Ahnung von unserer eigenen Kiste. Wir versetzen uns zum Beispiel in die Perspektive eines Konsumenten unserer bereitgestellten API, um zu prüfen, ob sich unsere Kiste als Ganzes so verhält wie wir meinen, dass es der Konsument oder Nutzer von ihr erwartet. Letztendlich testen wir auf diese Weise auf eine vergleichsweise unabhängige Sicht, ob Absprachen und Verträge eingehalten werden, um ein harmonisches Zusammenspiel zu gewährleisten.

Nehmen wir zum Beispiel an, dass unsere Kiste statt der oben beschriebenen 6 Seiten mit je 4 Ecken nur 5 Seiten und insgesamt 5 Ecken hat, dann wird das geometrisch und statisch trotzdem funktionieren. Das Gebilde wird sehr stabil stehen (siehe auch “Pyramide”). Aus einer ganz bestimmten Perspektive betrachtet (beispielsweise von unten), wird unsere Kiste dieser Form auch so aussehen, als wäre alles in Ordnung. Darauf sollten wir uns aber nicht ausruhen!

Wir erinnern uns: Ziel war es, etwas auf unserer Kiste abzustellen und aufzubauen. Das wird nicht funktionieren, das wird im wahrsten Sinne des Wortes schiefgehen. Die Schnittstelle, die wir unseren Nutzern oder Konsumenten anbieten wollen, fehlt oder ist extrem fehlerhaft. Sie wären also sicher nicht glücklich darüber. Im Gegenteil, womöglich hassen sie unsere API.

In den meisten Fällen stellen wir nicht nur eine Schnittstelle bereit, wir konsumieren auch von anderen bereitgestellte. Das beschriebene Schicksal kann uns also auch treffen, wenn wir etwas auf Kisten Dritter abstellen und aufbauen wollen – und erwarten, dass das so funktioniert wie wir uns das gedacht haben.

In diesem Szenario können wir Black-Box-Tests nutzen, um sicherzustellen, dass das Verhalten anderer Kisten, auf die wir aufbauen wollen, unseren Erwartungen entspricht.

Ist das nicht der Fall, bleibt uns nicht viel anderes übrig als unsere Erwartungen dem festgestellten Verhalten anzupassen. Das können wir allerdings unmöglich von anderen, die unsere Schnittstelle nutzen wollen, erwarten:

“Du benutzt die Kiste nur falsch. Wenn du die richtige Balance findest, kannst du darauf bestimmt was abstellen, stell’ dich nicht so an!”

Die Diskussion dazu könnte interessant werden – und ist so gar nicht zu empfehlen. Vielmehr sollten wir uns unsere Kiste und den kommunizierten Vertrag zur Hand nehmen, um sie von außen betrachtet zu testen, so wie sie andere auch sehen würden.

Und wenn wir dann feststellen, dass unser gegebenes Versprechen zum Verhalten so nicht eingehalten werden kann, ist es an der Zeit daran etwas zu ändern. Nun sollten wir uns aber auch zunutze machen, dass diese Kiste unsere Kiste ist und wir die Möglichkeit haben das Licht anzuschalten.

 

White Box

Sicherung rein, Licht an! Wir öffnen die Kiste. Wenn wir vorher festgestellt haben, dass irgendwie eine Ecke fehlt und auch mit den Seiten was nicht stimmt, öffnen wir damit wahrscheinlich auch die Büchse der Pandora, das muss uns bewusst sein.

Werfen wir einen Blick hinein in die hell erleuchtete, weiße Kiste! Wir werden alles sehen, ganz im Detail, und können detailliert testen und sicherstellen, dass doch alle Ecken, Kanten und Seiten da sind und jeweils für sich betrachtet tun, wofür sie gedacht sind.

Photo by Kelli McClintock on Unsplash

 

Wenn wir wissen, wie es in der Box aussieht, hilft uns das auf jeden Fall ihr Innenleben zu verstehen. In den Details, die wir dort vorfinden, können wir uns aber auch verlieren. Mitunter gibt es viel zu sehen und zu entdecken in so einer Kiste. Dass wir eigentlich nur etwas darauf abstellen wollten, gerät da schnell in den Hintergrund, denn – das müssen wir doch zugeben – in Kisten zu kramen, kann verdammt spannend sein! Da vergisst man schon mal die Zeit. Es gibt einfach so viel zu entdecken!

Vielleicht ist auch gar nicht immer so ganz klar, wie denn eigentlich alles zusammenspielt, damit man am Ende von außen etwas auf der Kiste abstellen kann. Um das zu verstehen, tauchen wir bis in den letzten Winkel ab. Das erfordert Zeit, Einarbeitung und generell Know-how. Das ist aufwändig, das ist anstrengend. Es ermöglicht uns aber ein tiefes Verständnis unserer Kiste und so die Vermeidung von letztlich unerwünschtem Verhalten an einem sehr frühen Punkt als solide Basis für alles, was noch darauf aufbaut.

In White-Box-Tests bewegen wir uns sehr dicht an den kleinen Details auf niedriger Ebene. Vielleicht erkennen wir dabei schon Ursachen, die später dazu führen, dass unsere Kiste von außen betrachtet keine Deckseite sondern eine Spitze hat. Wenn unsere Kiste eigentlich Software ist, bedeutet das, dass wir uns intensiv mit dem Code und seiner Struktur auseinandersetzen. Wir wissen, welcher Input wo und wie verwendet wird, welchen Output das erzeugt – und wo der dann wiederum verwendet wird. Wir können Pfade quer durch die Anwendung, die Box, nachvollziehen und unzählbare Ausnahmesituationen unter die Lupe nehmen.

Konzentrieren wir uns jedoch zu sehr auf diese Kleinteiligkeit, schreiben automatisierte Tests für jedes feine Detail, werden zwei Dinge eintreten:

    1. Die Testabdeckung bewegt sich Richtung 100 Prozent. Wir können beruhigt davon ausgehen, jeden noch so wahrscheinlichen oder unwahrscheinlichen Pfad in unserer Anwendung getestet zu haben.
    2. Unsere Tests orientieren sich mit recht hoher Wahrscheinlichkeit stärker an Details der Implementierung als am gewünschten beziehungsweise geforderten und vereinbarten Verhalten auf höherer Ebene.

Nun liegt es aber in der Natur der Sache, dass Anforderungen in der Regel von außen kommen und das Verhalten betreffen. Unsere Nutzer interessieren sich nicht dafür, ob unsere Kiste beispielsweise integrierte Versteifungen hat, damit sie ihre besonders schwere Kiste darauf abstellen können. Wenn sich an ihren Anforderungen an uns nur geringfügig etwas ändert, kann das zur Folge haben, dass wir mitunter sehr viel Aufwand haben, die gewünschte Änderung außen nach innen auf all die vielen Feinheiten und Kleinigkeiten zu übertragen. Haben wir vorher für alle detaillierte und feingranulare Tests bereitgestellt, werden wir vielleicht (fast) überall etwas aktualisieren müssen oder sie sind sogar obsolet geworden.

Das nimmt noch einmal viel Zeit in Anspruch. So richtig ideal ist das nicht. Eigentlich wollten wir doch nur das Verhalten der Software etwas modifizieren.

Es ist also nicht unbedingt sinnvoll, jede Kleinigkeit explizit und detailliert in einem (automatisierten) Test abzudecken. Und es ist auch nicht notwendig. Im Endeffekt ist das Verhalten entscheidend. Beim Test dessen ist es hilfreich, die grundlegenden Hintergründe zu verstehen, nachvollziehen und verifizieren zu können, darüber hinaus dann aber mit Augenmaß an die Sache heranzugehen.

 

Grey Box

Das ist weder so richtig “schwarz” noch “weiß”. Diese Einteilung funktioniert schon in der Realität nicht. So ist es auch mit unseren beiden Kisten und dem Black-Box- beziehungsweise White-Box-Test.

Photo by Martin Katler on Unsplash

 

Wir suchen also einen Mittelweg. Nehmen wir noch einmal unsere schwarze Kiste zur Hand und schalten das Licht ein. Wir dimmen es dabei aber und richten es so, dass wir einen Blick auf die wesentlichen Teile, die gerade von Interesse sind, werfen können. Geblendet zu werden sollten wir vermeiden. Unsere Box erscheint nun grau.

Unser Nutzer möchte eine besonders schwere Kiste auf unsere Kiste aufbauen. Wir wissen, dass wir für diesen Zweck eine Versteifung eingebaut haben, wir wissen auch, wie sich diese Versteifung verhalten und was sie aushalten soll, wir können uns also im Detail darauf konzentrieren, um sicher zu gehen, dass es später keine bösen Überraschungen gibt.

Beim Grey-Box-Testing fokussieren wir uns also weiterhin auf das gewünschte Verhalten. Wir betrachten den Code und die internen Datenstrukturen dabei jedoch teilweise und nur so weit wie es uns nützt. Die ausschlaggebende Perspektive für den Test ist die des Anwenders. Beim Design der Testfälle ist es aber förderlich, die zugrunde liegenden Details zu kennen und berücksichtigen zu können.

Im Beispiel unserer Kiste bedeutet das, dass wir die Testfälle so definieren, dass wir an den Grenzen der Belastbarkeit der Versteifung operieren, mit dem vereinbarten Vertrag im Hinterkopf. Wir wollen sicherstellen, dass die Erwartungen der Nutzer unserer Kiste erfüllt und die Vereinbarungen eingehalten werden. Und genau dabei hilft eben die eingebaute Versteifung.

Übrigens: Wir haben mittig in der Kiste eine Metallstrebe mit 2 cm Durchmesser eingebaut. Sie leuchtet blau. Das sieht zwar schön aus, interessiert aber niemanden von außen – und genau deshalb betrachten wir das in unseren Grey-Box-Tests nur bedingt. Um die Belastbarkeit der Kiste und die Versteifung der Kiste zu testen, genügt es zu wissen, dass sie da ist.

Dass sie blau leuchtet, ist aber trotzdem schön, das begeistert uns. Das ist letztlich aber nur ein Aspekt unserer Begeisterung für Technologie.