Test is dead – Die Technik
Dieser Artikel ist der dritte und letzte Teil der „Test is dead“-Reihe. Im ersten Teil sind wir auf die provokanten Aussagen von Alberto Savoia eingegangen. Er setzt den Fokus bei der Produktentwicklung neu und will zuerst sicherstellen, dass wir das richtige bauen, bevor wir es richtig bauen. Im zweiten Teil der Reihe ging es darum, was es bedeuten kann Testen für tot zu erklären und wie man mit den Produktverantwortlichen klar machen kann, warum nach dem richtigen Feature auch das Feature richtig gemacht werden muss. Dieser Artikel nimmt sich den technischen Themen an, denn eine Software einfach mal so ohne Qualität zu entwickeln ist nicht so trivial, wie es auf Anhieb scheint.
Nehmen wir eine Situation, in der wir ein neues Produkt bauen wollen. Ob es ein Erfolg wird, wissen wir nicht, also schauen wir, dass wir möglichst schnell etwas funktionierendes an den Start bringen, was einen Mehrwert für den Nutzer hat. Wir hauen das Stück Software raus und alle sind glücklich. Wenn wir Hardware-Probleme haben, dann stellen wir da neue hin, wenn wir nicht wartbar sind, dann brauchen wir halt ein wenig länger bei kleineren Erweiterungen. Alles gut also. In dieser Situation kommen wir also problemlos mit diesen Ansatz zurecht.
Problematisch wird es aber in einer Situation, in der es darum geht ein neues Feature in ein bestehendes Portal einzubauen. Hier können wir auch wieder ein Feature ohne Rücksicht auf Qualitätsmerkmale raushauen. Klingt jetzt erstmal ähnlich wie bei der ersten Situation. Jetzt darf man aber nicht vergessen, dass Software sich immer gegenseitig beeinflusst. Das neue Feature wird sich im Normalfall eine Datenbank und wohl sogar einen Webserver mit dem existierenden Portal teilen. Dumm gelaufen, wenn das neue also das alte runterzieht. So einfach ist das ganze also nicht.
Technisch gesehen ist das Problem nicht trivial. Wir wollen möglichst schnell etwas bauen, haben aber ein hohes Risiko, dass wir etwas kaputt machen, von dem wir bereits wissen, dass es wertvoll für unsere Nutzer ist. Das wir nicht so schnell vorankommen, wie es bei der „Test is dead“-Theorie versprochen wird ist klar. Aber da kann man vielleicht gemeinsam dran arbeiten.
Meine Idee zu dem Thema wäre ein Framework, das bereits für solche Situationen vorbereitet ist. Es müsste folgende Eigenschaften mitbringen:
- Modulare Architektur
Einzelne Features müssen strikt von anderen getrennt sein. Nur wenn man eine lose Kopplung durch Plugins aufbaut, kann man unabhängig denken.Der Big Ball of Mud ist an dieser Stelle eher schädlich, zumindest wenn es um das innere des Frameworks geht. Ich könnte mir auch vorstellen, dass man das Framework so baut, dass man explizit angeben kann, dass ein Modul noch im „Incubator-Status“ ist. Vielleicht würden ihm damit gewissen Rechte entzogen werden. - Sicherheitskonzept
Einzelne Module sollten nicht die Möglichkeit haben alle Daten auszulesen, die existieren. Wenn sich in dem ungetesteten Feature eine Sicherheitslücke befindet, dann darf diese nicht die anderen Daten kompromittieren. Dies könnte man z.B. über Fassaden vor den eigentlichen Klassen machen und diese dem Feature zur Verfügung stellen. Oder über unabhängige Datenbanken, so dass man gar nicht in der Lage ist auf die Daten der anderen zuzugreifen. Sicherlich kann man hier auch in Services denken und diese sicher machen. - Getrennte Infrastruktur
Wäre es nicht toll, wenn das neue Feature das System nicht runterziehen könnte, wenn es CPU oder I/O frisst wie nichts gutes? Ich denke der einfachste Ansatz wäre eine getrennte Infrastruktur auszusetzen. Wenn das Feature langsam ist, dann ist nur das Feature langsam. Sonst nichts. Auch hier muss das Framework eine Trennung schon vorsehen. Im einfachste Fall könnte man hier sogar auf ESI setzen. Damit hat man für den User eine Trennung, die er nicht mitbekommt und jedes Feature würde in HTML denken. Meine Meinung nach ein wirklich sauberer Ansatz.
Ein solches Framework zu bauen, das bereits eine solche Trennung mitbringt sollte zwar nicht trivial sein, aber machbar.
Fassen wir also noch mal die drei Artikel kurz zusammen:
- Wir sollten zuerst sicherstellen, dass wir das richtige bauen, bevor wir es richtig bauen
- Wenn wir sicher sind, dass es das richtige ist, müssen wir die nicht-funktionalen Anforderungen anpassen und es sauber implementieren
- Technisch muss es eine saubere Trennung zwischen den „Guten“ und den „Schlechten“ geben.
Sicherlich ist der „Test is dead“-Ansatz in der Realität nicht so einfach durchzusetzen, wie hier auf dem Papier. Nichtsdestotrotz ist es eine Arbeitsweise, mit der schon sehr viele Unternehmen auf der Erfolgschiene fahren.
Das sind die Grundprinzipien des OOD wenn ich nicht irre. So wird das Design betrieben, so wird programmiert wenn man es ordentlich macht und schon immer war es ratsam Fileserver, Webserver, Applikationsserver, Datenbankserver voneinander zu trennen und via Kapselung die Sicherheit zu gewähren. Was ist jetzt daran neu oder gar revolutionär? Modulare Software Entwicklung ist das Grundprinzip. Aus Faulheit oder Bequemlichkeit und nicht zuletzt aus vermeintlichen Einsparmöglichkeiten wird es aber oft ignoriert.
Ist eher SOA als OOD denke ich, aber klar, neu ist es nicht wirklich. Wobei ich kein Web-Framework kenne, das eine infrastrukturelle Trennung von Komponenten vorsieht.
Webserver und Datenbank würde ich jetzt mal voraussetzen, dass dort eine Trennung häufig existiert.
Es ist SOA und OOD.
Just stay clean wherever you are.
Being it the code or the architecture.
High level must not depend on low level.
etc. etc….