Abstract vs. Concrete

„Es gibt die einen und die anderen, die Konkreten und die Abstrakten. Die Konkreten, das sind die, die sich im Code bewegen wie ein Fisch im Wasser. Sie kennen jedes kleine Detail und wissen immer wo was wie funktioniert. Die anderen sind die Abstrakten, also die, die es gewohnt sind, Systeme aus der Vogelperspektive zu sehen, die auch mal einen Schritt zurück gehen und das Große Ganze im Blick haben. Nichts davon ist besser als das andere. Beides sind einfach unterschiedliche Qualifikationen.“

So oder so ähnlich hab ich das bei unseren zahlreichen Vorträgen zu Design Types immer erklärt. Was ich oft auch dazu sage, ist, dass es genau diese Dimension ist, die einen an einander vorbeireden lässt.

Auch mir passiert das immer mal wieder. Wie man an meinem Design Type klar ablesen kann, bin ich in der abstrakten Hälfte beheimatet. Obwohl ich das weiß und versuche, das beim Kommunizieren immer zu beachten, passiert es mir gefühlt einmal im Jahr (und vermutlich noch häufiger), dass ich mit Kollegen aus der konkreten Ecke rede und wir uns gegenseitig einfach nicht verstehen.

Vor ein paar Tagen war das wieder der Fall. Wir haben im Team eine Architekturentscheidung getroffen. Es ging darum, ob und wann wir eine bestimmte Art Unit-Test schreiben wollen — parallel zu einem Integrationstest, den wir für diesen Teil des Codes immer schreiben.

Bei der Diskussion ging es mir darum, heraus zu arbeiten, was die Kriterien sind, wann solche Unit-Tests angebracht sind. Auf drei oder vier dieser Kriterien konnten wir uns relativ schnell einigen. Das waren so Dinge wie „wenn keine Testdaten beschafft werden können oder sich bestimmte Fehlersituationen im Integrationstest nicht nachstellen lassen, bietet ein Unit-Test die Möglichkeit, die Daten zu mocken“. Das war für uns alle relativ einleuchtend.

Der Punkt, der für Verwirrung gesorgt hat, war folgender: „Der Unit-Test ist schneller“. Und das stimmt. Ein Unit-Test ist innerhalb von weniger als einer Sekunde durchgelaufen und gibt mir ein grünes oder rotes Ergebnis. Der Integrationstest braucht im konkreten Fall eine längere Setup-Phase, was dafür sorgt, dass man — sagen wir mal — so zwischen 10 und 30 Sekunden auf sein Ergebnis warten muss. Der Feedbackzyklus ist deutlich länger, was diese Integrationstests ziemlich unbequem macht.

Die Ausführungszeit ist durchaus ein gewichtiger Punkt. Nur ist es im konkreten Fall eben kein Kriterium dafür, ob ich zusätzlich zum langsamen Integrationstest noch einen schnellen Unit-Test schreiben soll. Es wäre nur dann ein Kriterium, wenn sie die selbe Testaussage liefern würden, d.h. die selben Bugs finden würden. Das tun sie aber nicht, denn sie testen unterschiedliche Dinge. Der Integrationstest testet, ob ich das aufgerufene System richtig verstanden habe bzw. ob dieses sich so verhält, wie ich das vermute. Der Unit-Test kann das aus Prinzip nicht testen, weil er das andere System wegmockt. Dafür kann ich — wie gesagt — in diesem Unit-Test bestimmte Fehlersituationen testen, die ich im Integrationstest nicht testen kann.

Die schnellere Ausführungszeit ist also ganz klar ein Vorteil beim Unit-Test. Sie ist nur eben kein Kriterium dafür, was im Unit-Test getestet werden kann und was nicht. Für mich — den Abstrakten — war diese Bedeutungsnuance glasklar. Ich habe nicht verstanden, wie man ihn nicht sehen kann.

Vermutlich gibt es auch unter euch, die ihr diesen meinen Text lest, manche, die sagen werden „Ja, klar. Der Unterschied ist doch logisch!“ und andere, die sagen werden „Hä? Wovon redest du da?“ Ich behaupte, zu einem gewissen Teil liegt das an der beschriebenen Dimension abstract-vs.-concrete. Es sind einfach andere Denkweisen.

Für die, die den Unterschied noch nicht sehen, versuche ich das nochmal mit einer Analogie zu verdeutlichen: Angenommen es ist dunkel und ich laufe auf einer Straße. Dabei verliere ich ein paar Gegenstände. Als ich es bemerke, fliegt gerade mein Handy aus meiner Tasche und landet im Gras am Wegrand. Ich könnte nun im Gras am Wegrand suchen. Oder ich könnte (ggf. zusätzlich) dort hinten bei der Laterne suchen. Für das Gras spricht, dass ich weiß, dass dort irgendwo mein Handy liegt. Für die Laterne spricht vielleicht, dass ich mich erinnere, dass ich etwas hab klimpern hören, als ich dort vorbei gelaufen bin. Das könnte mein Schlüssel gewesen sein. Dass die Laterne Licht macht und es deshalb einfacher ist, dort zu suchen, ist ein klarer Vorteil dieser Stelle. Aber es ist nicht der Grund, dass ich dort suche. Wenn ich bemerke, dass ich den Schlüssel noch hab und nur noch mein Handy fehlt, gibt es keinen Grund, bei der Laterne zu suchen — so hell sie auch leuchten mag.

Ich bin gut im Kategorisieren. Ich packe das eine in die Kategorie „Vorteil“ und das andere ist die Kategorie „Kriterium“. Wie stellt sich jetzt die Situation aber für meine konkret denkenden Kollegen dar? Für meine Kollegen gibt es keinen signifikanten Unterschied zwischen Vorteilen und Kriterien. Meine Kollegen sind nicht blöd. Im Gegenteil! Ich halte große Stücke auf sie. Aber sie haben eine andere Denkweise, messen der Bedeutungsnuance weniger Gewicht bei und sind es deshalb nicht gewohnt, solche Kategorisierungen zu machen. Christian fragt also nach Vorteilen einer bestimmten Art Unit-Test. Ein paar davon schreibt er klaglos auf. Bei einem quasi-willkürlichen anderen Argument weigert er sich aber, es auf zu schreiben und behauptet, dass er das doch glasklare Argument nicht versteht. Wir haben bestimmt einige Minuten aneinander vorbei geredet und dabei gegenseitiges Unverständnis erzeugt.

Die Frage, die ich mir jetzt stelle: Was hätte ich tun können, um eine produktivere Diskussion zu haben? Die Diskussion darüber, ob die Ausführungsgeschwindigkeit nun ein Kriterium oder ein Vorteil darstellt, war jedenfalls nicht produktiv. Meine aktuelle Erkenntnis ist folgende: Die genannte Bedeutungsnuance mag ihre Berechtigung haben. Es ist aber nicht von der Hand zu weisen, dass ich sie für wichtiger halte als meine Kollegen. Und das ist vollkommen in Ordnung. Statt darauf herum zu reiten, hätte ich lieber auch diesen Punkt einfach aufschreiben sollen. Ich selbst hätte ihn ja für mich anders bewerten, gewichten und kategorisieren können. Aber das muss ich nicht ausdiskutieren.

Die Diskussion wäre dadurch nicht nur angenehmer geworden, sondern meine Kollegen hätten ihre Stärken besser ausspielen können. Als konkrete Denker fällt es ihnen nämlich deutlich leichter als mir, sich an die vielen einzelnen Aspekte zu erinnern und diese zu benennen. Von den vier Punkten, die wir aufgeschrieben haben, hatte ich ursprünglich nämlich nur einen im Kopf. Und vielleicht, vielleicht hätten wir noch einen fünften Punkt gefunden. Der wäre dann vielleicht ja doch wieder ein Kriterium gewesen.

Ein Kommentar


  1. Dies klingt sehr nach Anwendung der [Test-Pyramide](https://martinfowler.com/bliki/TestPyramid.html).

    Dabei wird sehr viel Wert auf die schnelle Ausführung von Unit-Tests gelegt und gelehrt, dass man weniger Intergrations-Tests haben sollte. Dies führt leider manchmal dazu, dass komplexes Zusammenspiel von verschiedenen Komponenten (insbesondere im Fehlerfall) nicht als ‚testwüdig‘ angesehen wird.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert