Sven Rautenberg: erstes echt großes Projekt

Beitrag lesen

Moin!

Ich beginn diesesmal jedoch mit nem echt großen Projekt (geschätzte Arbeitszeit ca. 300 Stunden. Deshalb die Frage, wie geh ich das am besten an???

Ein Projekt benötigt immer mehr Zeit als veranschlagt. Ist dies bereits berücksichtigt, gilt der erste Satz trotzdem. Oder anders. 90% der Arbeit benötigt 90% der Zeit. Die Rest benötigt die anderen 90% der Zeit.

Diesen Erfahrungswert kann man gar nicht genug betonen.

Es gibt in der Softwareentwicklung Ansätze, die Zeitdauer eines Projekts greifbarer als nur "dauert länger als geplant" zu machen. Ein Ansatz dazu ist, die einzelnen Programmieraufgaben in so kleine Teile zu zerteilen, dass sie der ausführende Programmierer als nicht aufwendiger als zwei Tage einschätzt, und dann für alle Einzelaufgaben vom ausführenden Programmierer eine Zeitschätzung vorzunehmen. Der tatsächliche Zeitaufwand für die Erledigung der Aufgabe wird ebenfalls erfasst. Aufgrund von Erfahrungswerten aus vorherigen Projekten, oder mindestens aus den erledigten Aufgaben des laufenden Projekts ist ermittelbar, wie gut der Programmierer schätzen kann - und daraus kann man dann errechnen, wie wahrscheinlich es ist, dass das Projekt in X, Y oder Z Tagen fertig wird.

Pre-Release-Tests:

  • Standardisierung (Code besser lesbar machen, HTML, JS validieren)

Das sollte von Anfang an geschehen. Hinterher ist keine Zeit oder Lust vorhanden, grundlegende Fehler auszubessern.

  • Hacking- & Hijacking-Tests

Auch das muss von Anfang an berücksichtigt werden, um keine grundlegenden, schwer auszubessernde Lücken einzubauen.

Tests gehören nach meiner Ansicht ganz an den Anfang des Programmierens. Tests sind die zwingende Grundlage für gut funktionierende und einfach debugbare Software. Die Methode heißt "TDD" - Test-driven Design oder meinetwegen auch Test-driven Development.

Die Idee dahinter ist, dass man sich als allererstes einen Test schreibt, und dann erst den Programmcode, der diesen Test positiv erfüllt.

Man schreibt sich also einen Test, der eine neue Klasse instanziiert, und führt den Test aus. Der scheitert natürlich, weil man das Codefile mit der Klasse noch nicht geschrieben hat. Also schreibt man jetzt das Codefile mit der noch leeren Klasse, und erwartet, dass der Test jetzt funktioniert. Wenn ja, hat man alles richtig gemacht, wenn nein, lauert irgendwo schon ein dummer Fehler, den man korrigieren muss.

Dann schreibt man sich einen Test für den Aufruf der ersten Klassenmethode. Der scheitert natürlich auch, weil die Methode noch nicht existiert. Also: Methode in die Klasse reinschreiben, damit überhaupt was aufrufbar ist, und Test erneut ablaufen lassen. Klappt erwartungsgemäß alles, kann es weitergehen, ansonsten: Den Fehler suchen.

Die Methode hat natürlich nicht nur zu existieren, sondern soll aus Eingabedaten irgendwelche Ausgabedaten machen. Das kann man wieder in einer Testfunktion formulieren: Man ruft die Methode mit definierten Eingabedaten auf und formuliert auch, welche Ausgabedaten zurückkommen sollen, und lässt das Testframework vergleichen, ob das auch passiert. Den Test wieder durchlaufen lassen (er muss scheitern, weil die Methode noch nichts tut), dann den Methodencode schreiben, so dass der Test erfolgreich durchläuft, und das wieder verifizieren.

Wenn man diese Methode konsequent für alles anwendet, was man programmiert, erreicht man eine sehr hohe Programmqualität bzw. sehr wenige Bugs, außerdem dokumentieren die geschriebenen Tests automatisch, was der eigentliche Code tun soll, und man erhält bei späteren Veränderungen am Code auch sofort Feedback, wenn man irgendeine Funktionalität unabsichtlich zerstört hat, während man doch eigentlich nur etwas erweitern wollte. Ebenso kann man den Programmcode natürlich auch abgesichert durch die Tests beliebig umschreiben und verbessern und trotzdem sicher sein, dass sich am Ergebnis nichts ändert (aber natürlich nur, sofern man gute Tests geschrieben hat, die so wenig wie möglich Definitionslücken lassen für bislang undefiniertes Verhalten - und wenn man in so eine Lücke tappt, die dann einen Fehler verursacht, schreibt man dafür natürlich wieder einen Test, damit dieses Problem in Zukunft nie mehr auftritt).

  • privatet Kurz-Dokumentation schreiben

Wenn das Projekt umfangreich ist, benötigt man die Dokumentation selbst, wenn man an einem lange nicht angefassten Teil Änderungen vornehmen möchte. Es sei denn, man hat ein so gutes Gedächtnis, dass man sich an alle Details erinnert, die zur jeweiligen Lösung geführt haben. Dann aber hat man am Ende vielleicht keine Zeit mehr, zu dokumentieren. Also am besten gleich die Dokumentation mitschreiben (phpdoc-Stil).

Möglich ist auch, zuerst die öffentlichen Schnittstellen (Funktions/Methodenköpfe) mit Beschreibung zu erstellen und dann erst die Inhalte (samt Programmkommentaren) hinzufügen.

Das TDD-Framework SimpleTest bietet z.B. als Funktionalität an, mit Mock-Objekten zu arbeiten, bei denen man im Prinzip nur den Methodennamen und die Parameter des Aufrufs spezifiziert und dann nur "künstlich" beschreibt, welcher Rückgabewert bei welchem Input auszuliefern ist. Die Mock-Objekte können dabei genau prüfen, ob sie mit den richtigen Parametern aufgerufen werden. Insgesamt ist das sehr hilfreich beim Testen komplexer Verzahnungen von Objekten.

  • Rechtskonformität und Lizenzen prüfen

Das sollte in der Planungsphase angesiedelt sein.

Auf jeden Fall.

Alpha-Tests starten:
Beta-Tests starten:

Ist es ein Auftrag eines Kunden? Dann ist es vorteilhaft, ihn frühzeitig in den Fortschritt einzubinden. Nicht dass er andere Aufgabenstellung formuliert hat als er eigentlich haben will, oder du dich anderweitig mit dem Ergebnis von seinen Vorstellungen entfernst. Andererseits hilft im Zweifelsfall eine detaillierte Aufstellung dessen, was zu erbringen ist (Stichwort: Lasten- und Pflichtenheft).

Standard-Erfahrungswert: Das, was der Kunde bestellt, ist nicht das, was er tatsächlich haben will. Selbst wenn man es bis ins kleinste Detail in einem Lasten- und Pflichtenheft festlegt, von ihm unterschreiben lässt, und auch exakt so realisiert.

Die frühzeitige Mitwirkung des Kunden und die Flexibilität des Entwicklungsprozesses, auf geänderte Kundenwünsche und vor allem geänderte Kundenprioritäten reagieren zu können, ist eigentlich unerlässlich.

- Sven Rautenberg

--
"Love your nation - respect the others."