Wir arbeiten testbasiert und fahren damit sehr gut. Wir machen schon Test first, aber wir schreiben in der Regel erstmal nur ein groben Testfall, der die erfolgreiche Funktionalität ungefähr tested. Der Test veraendert sich dann schon während der Implementierung sehr stark, und die tatsächliche Testabdeckung (innerhalb eines Tests) bleibt auch erstmal relativ gering. Die Testabdeckung wächst dann nach und nach beim Bugfixing, Refactoring und beim Erweitern der Unit.
- Geschwindigkeit ist definitiv weit höher als ohne Tests. Und wir verbringen sehr viel Zeit mit der Testpflege. Es ist aber nicht so als währe das Schreiben der Tests eine laestige Zusatzaufgabe beim Entwicklen: Tests schreiben bedeutet Softwarekomponenten designen, und das ist ja auch eigentlich der interessante Teil am programmieren.
- meiner Erfahrung ist es wichtiger, das es fuer jede Komponente einen funktionierenden Test gibt, als das ein einzelner Test möglichst viel Funktionalitaet abdeckt.
- Keine Tests -> kein Refaktoring. Theoretisch kann man immer am Code schrauben, aber praktisch gesehen kann man nicht in vernuepftiger Zeit refaktoren, wenn man keine Tests hat (oder wenn man den Tests nicht vertrauen kann). Wir benutzen im Frontend eine Komponente, die sich ueber kein ausgereiftes Testframework verfuegt. In der Folge gibt es auch keine richtigen Tests. Da kann man den Unterschied ganz deutlich spuehren: Du machst eine Aenderung und dann musst Du das ganze verdammte Projekt anschauen um sicher zu gehen, das noch alles steht. Und das geht natuerlich nur sehr bedingt und kostet sehr viel Zeit.
- Bei groesseren Projekten musst Du ohnehin jedes Modul unabhaengig voneinander testen. Alles andere wuerde viel zu lange dauern. Also warum nicht gleich richtige Unittests schreiben?
- Wir dokumentieren nicht konsequent genug. Das heisst, dass die Tests meistens die beste Dokumentation ist, die wir haben. Der mit Abstand beste Weg um unseren Code zu verstehen ist das Studieren der Tests. Damit geht es dann aber sehr gut: Du kannst den Test benutzen, um zu verstehen was ein Modul macht, ohne gleich das ganze Projekt zu verstehen. Die Tests selber sind dann auch of sehr gut dokumentiert.
- Wichtig ist es, wirkliche Unittests zu machen und die Integrationtests EXTRA. D.h. mann muss Mockups schreiben um alle externen Dependencies aufloesen. In Unittests keine gemeinsame Datenbank verwenden, auf Netzwerkresourcen zugreifen oder auf Resourcen mit einem absoluten Pfadnamen oder was auch immer. Wenn man da nicht stur bleibt und Zeit investiert, dann kann man es gleich bleiben lassen.
- Das Fehlschlagen von Tests darf man auf keinen Fall zulassen! Wenn es nur einen Test gibt, der "halt immer schieflaeuft", dann vertraut niemand mehr dem ganzen Testprozess. Wir verwenden fuer unsere Java projekte Maven, und wenn die Tests (JUnit) nicht erfolgreich sind, kann nicht gebuildet und submitted werden. Das muesste man mit einem extra Parameter umgehen, und jeder weiss das er es nicht tuen soll. Ruby on Rails legt Gerueste fuer unit- und integrationtests automatisch an, inklusive der Datenbank. Fuer Haskell gibt es QuickCheck.