Im ersten Teil der Artikelserie wurde das Konzept von Komponententests ganz allgemein vorgestellt und im zweiten Teil wurde erklärt, wie mit Hilfe von Komponententests und Fehlerlokatoren eine teilautomatische Fehlersuche durchgeführt werden kann. Am Ende des zweiten Artikels habe ich auf ein generelles Problem von Fehlerlokatoren hingewiesen: Diese funktionieren in der Regel nur für einen einzelnen Fehler gut und führen im Mehrfehlerfall – also der Situation, dass sich in einem Programm mehr als ein Fehler befindet, welcher durch Komponententests ausgeführt wird – zu eher unbrauchbaren Ergebnissen. Warum das so ist und was man dagegen tun kann, möchte ich in diesem Artikel darlegen.
Zur Erinnerung: Lokatoren helfen bei der Fehlersuche, indem sie die aufgerufenen Komponenten (Methoden, Statements, …) nach ihrer Wahrscheinlichkeit, einen Fehler zu enthalten, sortieren. Ein bekannter Lokator ist der Tarantula-Lokator mit folgender Formel:
rT(mi) = |
|
||||||
|
Die Bezeichnungen in der Formel hatten die folgenden Bedeutungen (man möge mir den kopierten Textbaustein verzeihen): Der Ausdruck f(mi) bezeichnet die Menge an fehlgeschlagenen Tests, welche die Methode mi aufrufen; f bezeichnet dagegen die Menge aller Tests, die fehlschlagen. Der Term f(mi) / f bezeichnet damit das Verhältnis zwischen den fehlschlagenden Tests, die mi aufrufen, und allen fehlschlagenden Tests. Analog dazu bezeichnet p(mi) die Menge an erfolgreichen Tests, die mi aufrufen und p die Menge aller erfolgreichen Tests.
Die Formel offenbart auch schon das erste Problem von Fehlerlokatoren: Sie sortieren die aufgerufenen Komponenten in Abhängigkeit davon, von wie vielen fehlschlagenden Testfällen in Relation zu allen fehlschlagenden Testfällen sie aufgerufen werden. Mit anderen Worten: Die Komponenten werden danach beurteilt, wie gut sie das Fehlschlagen aller Testfälle erklären. Und wo ist hier das Problem?
Ganz einfach: Die fehlschlagenden Testfälle müssen nicht alle aufgrund desselben Fehlers fehlschlagen! Es ist durchaus denkbar, dass einige Testfälle wegen Fehler A fehlschlagen, wohingegen andere aufgrund Fehlers B fehlschlagen und so weiter. Wenn nun einige wenige Testfälle ausschließlich wegen eines Fehlers in einer Methode m1 fehlschlagen, viele andere Testfälle aber aufgrund eines Fehlers in m2 und keiner der Testfälle die jeweils andere Methode aufruft, so wird m2 durch Tarantula (und auch durch andere Lokatoren) dementsprechend als sehr wahrscheinlich fehlerbehaftet eingestuft, da die Methode eben durch viel mehr fehlschlagende Testfälle als m1 aufgerufen wird. Das ist aber natürlich ein Trugschluss!
Daneben existiert noch eine weitere Problematik: Die Sortierung durch einen Fehlerlokator gibt keinen Hinweis darauf, wie viele Fehler sich eigentlich (beziehungsweise mindestens) im Programm befinden. Wenn die durch einen Lokator vorgeschlagenen Methoden durchsucht und ein Fehler gefunden wurde – woher soll der Programmierer wissen, ob er weiter suchen soll oder nicht? Tarantula gibt hierauf keine Antwort – die Forschung zum Glück aber schon. Und auch ich habe mich in meiner Dissertation mit genau dieser Frage beschäftigt und möchte sie hier beantworten.
Zwei Informationen sind somit interessant: Wie viele Fehler befinden sich (mindestens) in einem Programm und an welchen Stellen sollte nach ihnen gesucht werden. In der akademischen Welt existieren einige teilweise relativ komplizierte, da sehr spezialisierte Algorithmen, um diese Informationen zu sammeln. Glücklicherweise kann man sich jedoch auch mit einigen relativ einfachen Algorithmen aus der Mathematik behelfen, um die gewünschten Informationen zu besorgen.
Betrachten wir zum Beispiel einmal die folgende Abdeckungsmatrix (alle Tests sollen als fehlgeschlagen gelten):
t1 | t2 | t3 | t4 | t5 | t6 | |
m1 | 1 | 1 | ||||
m2 | 1 | 1 | ||||
m3 | 1 | 1 | ||||
m4 | 1 | 1 | ||||
m5 | 1 | 1 |
Kommentare (10)