Erstellen komplexer Algorithmen mit TDD


8

Ich versuche, TDD in meine tägliche Programmierpraxis aufzunehmen. Ich benutze es bei der Arbeit sehr effektiv, aber ich habe Probleme mit meinen persönlichen Projekten, bei denen ich einige komplexe Algorithmen verwende.

Der spezielle Algorithmus, der mich dazu bringt, diese Frage zu stellen, ist der erweiterte Kalman-Filter. Es ist komplex genug, dass ich nicht sicher bin, welchen Code ich geschrieben habe, aber es ist einfach genug, dass es schwierig ist, sich zu trennen.

Ich könnte einen Test für den Algorithmus mit einer Eingabe und der erwarteten Ausgabe schreiben, aber ich werde in der Mitte viel Thrashing und Shotgun-Codierung durchführen, weil ich kein Vertrauen in diese Zwischenschritte habe.

Was ist Ihr Ansatz, wenn Sie mit vernünftig komplexen Algorithmen gearbeitet und TDD verwendet haben?


1
Überprüfen Sie für das "Transformation Premise" -Prinzip: javacodegeeks.com/2013/01/…
Mik378

2
TDD ist keine Wunderwaffe. Wenn Sie der Meinung sind, dass es nicht anwendbar ist, wenden Sie es nicht an.
Den

@Den Ich glaube, es ist anwendbar, aber ich habe mich gefragt, wie andere es angegangen sind. Da ich versuche, die Praxis zu übernehmen, erscheint es kontraproduktiv, sie für etwas fallen zu lassen, das ich nicht verstehe. Ich möchte lieber wissen, warum es in diesem Fall nicht funktioniert. Dies ist der Vorteil der Übernahme für meine eigenen Projekte.
Munk

Antworten:


13

TDD ist kein Ersatz für Design.

Dies ist ein weit verbreitetes Missverständnis über TDD, dass man aus einem Rot-Grün-Refaktor ein kohärentes Design irgendwie "wachsen" lassen kann. Das kannst du nicht. Ihre Tests müssen sich noch an Ihren Designfähigkeiten orientieren.

Wenn Sie herausfinden möchten, was zwischen der Eingabe und Ausgabe Ihrer zu testenden Methode zu tun ist, bedeutet dies wahrscheinlich, dass Sie versuchen, zu viel in einer einzelnen Methode zu tun. Überlegen Sie, was diese Zwischenschritte bewirken sollen. Schreiben Sie Tests für diese Zwischenschritte und Methoden, die diese Tests bestehen.


2
+1 für "TDD ist kein Ersatz für Design." Auf dieser Seite ( ravimohan.blogspot.de/2007/04/learning-from-sudoku-solvers.html ) finden Sie eine schöne Illustration dessen, was bei der Anwendung von TDD passieren kann, ohne einen Überblick darüber zu haben, was Sie tun.
Giorgio

0

Man kann TDD für komplexe Algorithmen verwenden. Schreiben Sie viele klare und dennoch aussagekräftige Tests und verwenden Sie sie, um Ihr Programm zu entwerfen. Wenn im Algorithmus eine Randomisierung verwendet wird, verwenden Sie eine Art Abhängigkeitsinjektion und testen Sie die Randomisierung separat. TDD ist eine der vielen Methoden, mit denen Sie hochwertige Algorithmen schreiben: Andere sind Codeüberprüfungen, Protokollierung usw.

Ich könnte einen Test für den Algorithmus mit einer Eingabe und der erwarteten Ausgabe schreiben,

Schreiben Sie keinen "a" -Test. TDD schreibt nicht jeweils einen Test. Schreiben Sie zuerst mehrere Tests, die verschiedene Grenzen und Standardeingaben des Algorithmus überprüfen.


0

Ich bin neu in TDD (lesen Sie: Ich mache es wahrscheinlich nicht richtig), aber es scheint besser für leicht zu beschreibende Algorithmen geeignet zu sein, wenn Sie leicht überlegen können, welche Eingänge mit welchen Ausgängen übereinstimmen.

Wenn ich mehr mache "Ich weiß noch nicht, was das Ergebnis sein wird", war TDD für mich nicht sehr nützlich. Was ich stattdessen mache, verwende ich sehr großzügig Asserts für kleine Portionen, von denen ich weiß, dass sie funktionieren, wie sie bisher funktionieren sollten. Auf diese Weise stecke ich nicht fest, wenn ich versuche, auf ein Ziel zu programmieren, von dem ich nicht sicher bin, ob es das gültige Ziel ist, aber ich bekomme einen gewissen Schutz, indem ich die Schmerzbereiche auf kleinere Teile des Codes lokalisiere.

Sobald der Algorithmus nach Korrektheit sortiert ist (wie in mindestens einigen Eingaben -> Ausgaben für die Stichprobenprüfung), gehe ich zurück und schreibe einen Test. Dann ist es viel sicherer, zurück zu gehen und zu überarbeiten oder für Geschwindigkeit oder Ressourcennutzung zu optimieren.


0

Ich würde sagen, dass solche Dinge besser für RDD geeignet sind: Reading-Driven Development.

Hier lesen Sie in einem Buch den Algorithmus für etwas Kompliziertes wie einen Kalman-Filter und übersetzen ihn dann in eine Implementierung in Ihrer Zielumgebung.

Der Nachteil ist, dass Sie auf diese Weise keine kostenlosen Testfälle als Teil des Designprozesses erhalten. Auf der anderen Seite hat etwas, das so bekannt ist, mit ziemlicher Sicherheit eine vorhandene Implementierung (z . B. Commons Math ). Und dann ist es zu verwenden straighforward dass als Testorakel für die neue Implementierung; Alles, worüber Sie sich Sorgen machen müssen, ist, dass Ihre Testfälle alle Pfade in Ihrem Code abdecken.


Das besondere Problem, das ich hier habe, ist, dass ich den erweiterten Kalman-Filter verwende. Ich habe keine gute Referenzimplementierung gefunden, der ich vertraue, wie ich es von Apache Commons tun würde.
Munk
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.