Fertig!

25.05.2007 Permalink

Vor kurzem erst habe ich mich mit einem Bewerber für eine PL-Position darüber unterhalten, was man in einem Software-Projekt während der Entwicklung tun kann, um schon vor einem Systemtest möglichst viel Qualität in die entwickelte Anwendung zu bringen. "Viel Qualität" heißt hier konkret: Ich werde diese Tätigkeiten zunächst motivieren und dann in sechs aufeinander aufbauenenden Stufen beschreiben:

Warum macht die frühe Herstellung höherer Qualität Sinn?
Damit man sich eine vorhersehbare böse Überraschung spart. Denn wenn man erst nach offiziellem Entwicklungsende Acht auf innere und äußere Qualitätsmerkmale gibt, dann kann das Team längst in der Falle sitzen: jede Defektbehebung kostet Zeit, und die kann vor der Auslieferung schnell zu knapp werden. Die Folge ist ein gerissener Termin oder miese Auslieferungsqualität. Beides verursacht letztlich erschreckend viel Aufwand und bringt dazu noch Ärger und vielleicht zusätzlichen finanziellen Schaden ein.

Im Gesamtprozess kann man dagegen Zeit sparen, wenn das Team direkt während der Entwicklung Wert auf Fehlervermeidung legt. Man spart sich dadurch bei jedem Fehler, der im Systemtest nicht mehr auftaucht, das Entdecken, Reproduzieren, Melden, Zuweisen, Suchen, Beheben und Nachtesten des Fehlers.

Zahlen, die ich in meiner Vergangenheit sammeln konnte, zeigen, dass die Rechnung aufgeht:
Die Qualitätssicherung (QS) eines Stücks Entwicklungsarbeit kostet vielleicht 1-2 PT, die Analyse und Behebung von nur einem Defekt während des Systemtests kostet im Schnitt 0,5 bis 1 PT. Und zwar ohne erste Entdeckung und Nachtest. Und dabei ist auch nicht eingerechnet, dass statistisch eine von fünf Behebungen nicht wirkt oder einen Folgefehler produziert. D.h. bei nur einer Handvoll Fehler pro Arbeitspaket würde das späte Finden teurer als die entwicklungsbegleitende QS... mehr Argumente braucht's -- finde ich -- nicht.

Was kann man als PL konkret tun?
1. Verständnis und Kultur schaffen.
Die böse Überraschung trifft nicht nur den PL, und schlechte Qualität ist nicht das Problem des Tests. Stress und Ärger trifft vor allem die Entwicklung, die "den Dreck" wieder wegräumen muss. Denn wer sollte das sonst tun?
Jeder im Team wird anfänglich einen eigenen Begriff von Qualität haben. Es gilt, im Team eine gemeinsame Vision zu erschaffen, was man durch kleine Referate zu Einzelthemen und anschließende Diskussion fördern kann.
Auf diese Weise kann man das Verständnis für die Durchführung von QS im Team schaffen, aber Vorsätze, Bitten und Appelle sind ohne konkrete Handlungen nutzlos. Um eine wirksame Qualitätskultur zu begründen, ist es besser, unbeholfen aber konkret mit QS zu starten, als nur darüber zu diskutieren und QS aus Angst vor Nicht-Perfektion letztlich zu unterlassen.
Es wird anfänglich holpern und rumpeln, und die QS-Ergebnisse werden auch nicht immer Anlass zur Freude sein... es ist eben ein Lernprozess.

2. Anders planen.
QS kostet Geld, in Summe zwar kein zusätzliches, aber das wenige eben früh sichtbar. Man sollte sich bei Planungs- und Schätzaufgaben daran gewöhnen, dass die Arbeit an einem Stück Code nicht damit abgeschlossen ist, dass der verantwortliche Mitarbeiter "Fertig!" meldet.
Es folgt die QS, die man als eigenes Arbeitspaket direkt an den Anschluss des jeweiligen Arbeitspakets der Entwicklung stellt. Je schneller das Feedback kommt, desto billiger ist seine Berücksichtigung. Durchgeführt wird das QS-Arbeitspaket von einem Entwickler-Kollegen. Die Kosten sollten je nach Baustelle bei 0,5 bis 2 PT liegen. Einen zentralen QS-Verantwortlichen braucht man, wenn das Team sehr groß ist und/oder man als PL das notwendige Grundwissen zu den Methoden nicht mitbringt.

3. Außensicht: Fachliche Funktionalität prüfen.
Was dem Systemtest auffallen könnte, kann ein anderer Kollege möglicherweise durch unsystematisches Blackbox-Testen selbst finden. Das Ziel ist, offensichtliche Fehler aufzudecken und ohne besondere Form an den zuständigen Entwickler zurückzumelden. Die Prüfgrundlage ist das Konzept oder die Feature/Use Case Beschreibung und immer der gesunde Menschenverstand.

4. Innensicht: Code und Unittests prüfen.
Die Funktionalität ("was der Code macht") sollte sich dem Code durch seine Struktur und durch Kommentare entnehmen lassen. Er sollte der konkreten technischen Architektur, anerkannten Design-Prinzipien und einem Code-Styleguide gehorchen. Das lässt sich mithilfe von Werkzeugen (s.u.) und natürlich Sichtung durch Kollegen prüfen.
Die Unittests sollten den Code funktional mindestens soweit abdecken, dass die zentralen Use Cases und deren Szenarien geprüft werden. Diese Beurteilung kann nur ein Mensch vornehmen. Ein Coverage-Werkzeug erlaubt zusätzlich das Identifizieren auffällig unabgedeckter Codestellen, was ein gutes Indiz für fehlende Tests ist. Dass die Unittests grün sind (also fehlerfrei ausführbar) versteht sich von selbst.
Während bei der Außensicht-Prüfung die Kommunikation der Prüfergebnisse in Fire-and-Forget-Manier z.B. per Mail ausreicht, lohnt es sich nach der Innensicht-Prüfung besonders, Prüfer und Code-Autor vor einem Monitor zusammenzubringen. Dadurch entsteht ein wertvoller Erfahrungsaustausch.

5. Messungen durchführen.
Mit Code- und Design-Metriken lassen sich potentielle Schwachstellen aufspüren. Eine hohe CCN (>20) lässt z.B. komplizierten Code vermuten, der sehr anfällig für Defekte ist. Klassen mit nicht-trivialen Aufgaben sollten durch Unittests zumindest in Teilen abgedeckt werden, was man durch Coverage-Messungen sicherstellen kann. Auch das Package-Design kann man mit Maßzahlen zu Instabilität und Abstraktion unter die Lupe nehmen, um gröbere Design-Schnitzer aufzudecken.

6. Build- und IDE-Integration.
Unittest-Ausführung und Messungen, am besten mit Prüfungen gegen Referenzwerte, sollten in den täglich oder gar kontinuierlich auszuführenden Build und die IDE integriert werden, denn je schneller ein Missstand auffällt, desto günstiger ist seine Beseitigung. Hier beginnt dann schon die höhere Kunst, denn es sind einige Werkzeuge wie z.B. Eclipse, Ant oder Maven, CruiseControl, Cobertura, JDepend, JavaNCSS, CheckStyle und ähnliche ins Zusammenspiel zu bringen.

Die oben genannten Elemente reichen aus, um spürbar besser zu werden. Schon die ersten drei helfen, peinliche Ausfälle beim Start des Systemtests zu vermeiden. Die übrigen drei kosten mehr, sind aber im Sinne einer qualitätsoptimierten Entwicklung die logische Konsequenz.

Mehr Formalismus und Kontrolle (z.B. durch definierte Vorgabedokumente, Prüfprotokolle und einen Tool-gestützten Fehlerbehebungsprozess) kann nötig sein, sollte aber beim ersten Start in der Schublade bleiben. Und bei all dem nicht vergessen: lieber erstmal starten, dranbleiben und besser werden, als Perfektion anzustreben und am eigenen Anspruch zu verzweifeln.