Qualitätssicherung ausgewogen

Architektur/Methoden  –  11 Kommentare

Die Geschichte der Softwareentwicklung ist eine Geschichte voller Missverständnisse. Diese drehen sich besonders um den Begriff Qualität und wie man sie absichert. Eine der wichtigsten Maßnahmen ist es, die richtigen Tests zu automatisieren und die richtigen Tests weiterhin manuell durchzuführen. Um den passenden Kompromiss zwischen beidem zu finden, können Techniken wie Test-, Acceptance-Test- und Behaviour-Driven-Development in Kombination mit explorativem Testen helfen.

Im 21. Jahrhundert gelten andere Standards für Softwareentwicklung als in den Pionierjahren der Informationstechnik. Lange schon arbeiten Softwareentwickler nicht mehr mit 0en und 1en, Lochkarten oder prozeduralem Code. Stattdessen gehören objektorientierte Programmiersprachen mit ihren zahlreichen Frameworks zum Berufsalltag.

In der Frühzeit der Computerevolution war vieles ganz anders. Durch niedrige Personal- im Verhältnis zu den Hardwarekosten war Rechenzeit wertvoll, und Programme wurden akribisch von Hand geprüft [1]. Hier bereits entstanden die ersten Ansätze zum Unit-Testing. Der einzige Unterschied zur heutigen Praxis ist, dass die Programme von Hand durchgespielt wurden und Entwickler kein komfortables Unit-Test- Framework wie JUnit zur Verfügung hatten, das die Arbeit automatisieren konnte.

Doch warum testen Entwickler heute überhaupt noch? Schließlich ist die Rechenzeit um einiges günstiger geworden, und sollte die Möglichkeit bestehen, auf eine eigene Testabteilung zurückgreifen zu können, muss sich auch nicht mehr um die Qualität gesorgt werden. Allerdings wäre das ein wenig kurz gedacht: Eine nachgelagerte Testabteilung nimmt vielleicht ein wenig Arbeit ab, dafür kommt aber die Information, dass etwas am vorgelegten Programm kaputt ist, viel zu spät beim Entwickler an. Bis zur Rückmeldung ist er vielleicht schon drei Aufgaben weiter und kann sich vermutlich nur noch vage an den alten Code erinnern. Aus diesem Grund sollte die abgelieferte Arbeit bereits größtmögliche Qualität besitzen und die Qualitätssicherung im Idealfall keine Fehler mehr finden.

Das klingt alles schön und gut. Aber wie ist dem im echten Leben nachzukommen? Dort gibt es Projektdeadlines, Druck von oben und vom Kunden und eine Menge Fehler, die dem Produktivsystem entspringen. Zusätzliche Zeit zum Testen ist da kaum vorhanden. Langfristig ist es aber schwer, ohne Testen dem Teufelskreis zu entfliehen, denn je mehr Bugs produziert werden, desto mehr Druck baut sich auf. Umso wahrscheinlicher wird es auch, dass Entwickler mehr "Abkürzungen" im Code und in den Tests nehmen und mehr Fehler einbauen, was wiederum mehr Druck verursacht.

Auf lange Sicht hilft es nur, Abkürzungen zu vermeiden, da so zwar kurzfristig Deadlines eingehalten und Kunden milde gestimmt werden können, aber die Arbeit an Rückläufern und Ähnlichem wieder länger dauert. Werden hingegen die Zeit und der Aufwand in Kauf genommen, die eigene Arbeit mit Tests zu versehen und zu einem vernünftigen Design zu kommen, verringert sich die Arbeit merklich.

Die Mischung macht's

Das kritische Feedback vom Kunden bleibt nach wie vor wichtig, da sich häufig nur so Fehler in der Software aufdecken lassen. Allerdings wären möglichst frühe Rückmeldungen wünschenswert, denn je eher der Entwickler auf Softwarefehler stößt, desto geringer sind die Kosten durch Kontextwechsel und desto präsenter ist ihm der Code, der das Problem verursacht.

Wie lässt sich dieses Dilemma lösen? Maßnahmen wie Testautomatisierung, Continuous Integration, Test-driven Development und Acceptance Test-driven Development sowie exploratives Testen sind ein guter Ansatz. Testautomatisierung gibt hierbei kurzfristig das Feedback, das benötigt wird, um notwendige Verbesserungen einzuleiten. Durch Continuous Integration erhält der Entwickler regelmäßiges Feedback über den derzeitigen Stand des Projekts.

Testautomatisierung löst nicht alle Probleme, denn es lässt sich weder alles testen noch alles automatisieren. Beim sogenannten explorativen Testen geht es darum, die Fähigkeiten des menschlichen Gehirns - Assoziationsvermögen, Adaption und Lernen - beim Testen direkt einzusetzen. Die Lücken der Testautomatiserung können damit häufig geschlossen werden.

Durch einen Ansatz, der beides kombiniert, lässt sich sicherstellen, dass alle Risiken vor der Auslieferung adressiert wurden. Hat er sich etabliert, kann sogar damit begonnen werden, Tests zu entwickeln, bevor der entsprechende Code geschrieben ist.

Testgetriebene Entwicklung beeinflusst das Design des Codes, während Akzeptanztests das eigene Verständnis im Code durchzusetzender Anforderungen voranbringen. Richtig angewandt können alle diese Praktiken dabei helfen, langfristig die Qualität einer Arbeit zu erhöhen und der Zeitfalle zu entkommen.