am 28. Juli 2010
Nein, keine zwanzig neuen Active Record basierten Frameworks mit eigenen Template Engines oder was ihr euch sonst so gedacht habt beim Lesen der Überschrift.
Der “CRAP Index” ist eine junge Code-Metrik die versucht nah am Wortschatz und an den Gedankengängen von Entwicklern zu sein. Man könnte auch sagen: “Der WTF-Faktor einer Funktion”.
Die meisten von euch werden einfache Metriken wie die “LOC, Codezeilen” und die “ELOC, Ausführbare Codezeilen” kennen. Treue Leser des Blogs kennen vielleicht auch die “Zyklomatische Komplexität, Anzahl der Verzweigungen in einer Funktion” und die “NPath Complexity, Anzahl der Ausführungspfade durch eine Funktion”. Diese altgedienten Metriken leisten bei der QS gute Dienste sind aber etwas abstrakt. “Die Zyklomatische Komplexität des Codes den du gerade commited hast ist ziemlich hoch” ist ein Satz den man seltener hören wird als, mal ganz unverblümt kommuniziert, “was für ein unverständlicher Mist ist das denn”.
Die CRAP Metrik, übrigens mit dem lange nicht so nett klingenden “Change Risk Analysis and Predictions” ausgeschrieben, kommt aus der Javawelt und wurde vor etwa drei Jahren mit Crap4j jedem einfach zugänglich. Für uns PHPler wird diese Metrik mit dem bevorstehenden Release von PHPUnit 3.5 interessant da sie im neuen “Code Coverage Report” für jede Funktion mit aufgelistet wird. Eine Beta Version bzw. RC1 ist schon einige Zeit verfügbar.
Die Berechnung des CRAP Index ist realtiv trivial und zeigt auch gleich auf wieso wir dafür PHPUnit, bzw. Unittests im allgemeinen, brauchen:
Der Crap Index einer Funktion (f) berechnet sich aus der Zyklomatische Komplexität / “Cyclomatic Complexity” (comp), und der Code Coverage (cc) der Funktion, also dem prozentualen Anteil der Codezeilen die von unseren Unittests durchlaufen werden.
Die Formel sieht nicht trivial aus aber wird hoffentlich durch das folgende Bild deutlich greifbarer.
CRAP-Index(f) = comp(f)^2 * (1 – cc(f)/100)^3 + comp(f)

Auf der X-Achse ist die Code Coverage von 100 bis 0 Prozent, auf der Y-Achse die Zyklomatische Komplexität von 1 bis 30. Mit der Grafik wird, hoffentlich, schnell deutlich das eine Funktion umso besser bewertet wird je einfacher sie ist und je ausführlicher getestet. Der Schwellenwert für “This is Crap” ist hier mit 30 gewählt, aber das soll nur eine Richtlinie sein. Um eine bessere, d.h. niedrige, Bewertung zu erreichen kann man also entweder die Komplexität einer Funktion reduzieren oder sie besser Testen. Gerade beim Implementieren von Algorithmen wird man hier nicht “gezwungen” eine Funktion ggf. unsinniger weiße aufzuteilen sonst kann sie durch Tests “akzeptabel” machen.
Mit dieser Zahl kann man also einfach(er) Aussagen über die Verständlichkeit und Wartbarkeit von Code treffen. Ein einfacher “getter” oder “setter” wird selbst wenn er garnicht getestet ist ziemlich verständlich sein. Es ist nicht sonderlich schwer ihn zu warten. Eine halbwegs komplexe Funktion wird ohne Tests schnell über den Schwellenwert geraten und Änderungen sind dort auch nicht mehr einfach durchzuführen. Gibt es allerdings einige Tests, so was wir uns beim Refactoren darauf verlassen können nichts Kaput zu machen, ist auch der CRAP-Index unter dem Schwellenwert. Funktionen die eine Zyklomatische Komplexität von 30 oder mehr haben können wir allerdings auch mit noch so guter Code Coverage nicht mehr “retten”, sie sind oftmals zu komplex und gut wartbar zu sein.
Wenn also morgen euer Kollege zu euch kommt und sagt “Dein Code ist ganz schön CRAPpy” wisst ihr jetzt was gemeint ist.