# Unit Testing
Es gibt nur einen Weg, um funktionierenden Code *garantieren* zu können: ihn exzessiv zu testen. Jedoch bei jeder Änderung den ganzen Code manuell zu testen ist keine vertretbare Strategie. Der richtige Weg ist über eine gute Unit Testing Suite.
Eines der wichtigsten Testing Konzepten um nicht nur funktionierenden aber auch sauberen Code zu schreiben ist das *Test Driven Development (TDD)*.
## Die Gesetze des TDD
Es gibt drei Gesetze im TDD nach denen sich immer gerichtete werden sollte:
1. Produktionscode darf erst geschrieben werden, wenn dafür ein Unit Test geschrieben wurde.
2. Der Unit Test darf nicht mehr Code enthalten, als für das Scheitern des Tests mit erfolgreichem Kompilieren nötig ist.
3. Es darf nur so viel Produktionscode geschrieben werde, wie für das direkte Bestehen des Tests unbedingt nötig ist.
Wenn man diesem Zyklus kompromisslos folgt, geriet man in einen ewigen Zyklus des Tests schreiben und anschliessend Implementieren. Dieser Zyklus dauert einen nicht viel länger las das reine Implementieren.
So hat man zu jeder Zeit eine vollumfängliche Testing Suite mit maximaler Code Coverage.
## Saubere Tests
TDD hilft uns auch dabei die Tests sauber zu halten. Aber was macht einen Test sauber?
Uncle Bob sagt es sehr elegant:
*Drei Dinge: Lesbarkeit, Lesbarkeit und Lesbarkeit.*
Allgemein kann sich an die gleichen Regeln gehalten werden die wir bereits für normalen Code verwenden: Klarheit, Einfachheit und Ausdrucksdichte.
### Build-Operate-Check-Pattern
Das *Build-Operate-Check-Pattern* ist eine Struktur welche für Tests eingehalten werden sollte. Wie der Name bereits verratet, sollte ein Test in drei Teile unterteilt werden:
1. Der erste Teil (*Build*) erstellt die Daten die für den Test verwendet werden,
2. der zweite Teil (*Operate*) manipuliert diese Daten,
3. und der dritte Teil (*Check*) überprüft sie auf ihre Richtigkeit.
### Domänenspezifische Testsprache
Die vorgefertigte Testsprache macht es in vielen Projekten schwierig die Tests verstehen zu können. Die Lesbarkeit kann stark erhöht werden durch die Implementation einer eigenen domänenspezifischen Testsprache.
Es empfiehlt sich also, ein eigenes API mit allen benötigten Utilities bereitzustellen. Diese muss nicht anfangs bereits vorhergesehen werden, sondern entwickelt sich nach und nach.
### Ein Check pro Test
Es gibt Entwickler die darauf bestehen, dass jeder Test nur ein Assert haben sollte. Der Vorteil, der daraus entsteht, ist schnell zu sehen: Wenn nur ein Assert vorhanden ist, kommt man nur zu einer Schlussfolgerung was das Verständnis des Tests stark vereinfacht.
## F. I. R. S. T.
Auch für saubere Tests gibt es ein Regelwerk. Um genau zu sein sind es fünf Regeln:
### Fast (schnell)
Tests sollten immer schnell sein. Das Ziel ist, dass nach jeder Änderung die Tests ausgeführt werden können um sicherzustellen, dass alles noch funktioniert.
Wenn die Tests zu lange brauchen, wird es zu teuer sie überhaupt auszuführen.
### Independent (unabhängig)
Tests sollten in keinem Fall voneinander abhängig sein. Es sollte nie eine Kette geben, in der ein Test die Voraussetzungen für den nächsten setzt. Wenn in so einer Kette ein Test *failed*, sind alle folgenden Tests nicht mehr gültig.
Stattdessen sollten alle Tests unabhängig von einander und alleine funktioniere.
### Repeatable (wiederholbar)
Alle Tests sollten immer in allen Umgebungen laufen. Es sollten keinen Unterschied machen ob die Tests lokal auf einem Laptop, der Produktionsumgebung oder der Testumgebung ausgeführt werden. Die Ergebnisse sollten in allen Szenarien die gleichen sein.
### Self-Validating (selbst validierend)
Tests sollten einen booleschen Output haben. Es macht keinen sinn eine Testumgebung aufzusetzen wenn anschliessend die Testergebnisse manuell validiert werden müssen.
### Timely (zeitgerecht)
Tests müssen rechtzeitig geschrieben werden. Unit Tests sollten möglichst vor dem Code implementiert werden, da nachträgliches Testing erheblich schwieriger sein kann. Produktionscode der nicht testbar ist sollte nie implementiert werden.