Ich bin ein großer Verfechter der testgetriebenen Entwicklung im wissenschaftlichen Rechnen. Die Nützlichkeit in der Praxis ist einfach umwerfend und lindert die klassischen Probleme, die Codeentwickler kennen. Das Testen von wissenschaftlichen Codes, die bei der allgemeinen Programmierung nicht vorkommen, ist jedoch mit gewissen Schwierigkeiten verbunden. Daher sind TDD-Texte als Tutorials nicht besonders nützlich. Beispielsweise:
Im Allgemeinen kennen Sie keine genaue Antwort auf ein bestimmtes komplexes Problem von vornherein. Wie können Sie also einen Test schreiben?
Der Grad der Parallelität ändert sich; Ich bin kürzlich auf einen Fehler gestoßen, bei dem die Verwendung von MPI-Aufgaben als Vielfaches von 3 fehlschlug, aber ein Vielfaches von 2 funktionierte. Darüber hinaus scheinen gängige Test-Frameworks aufgrund der Natur von MPI nicht sehr MPI-freundlich zu sein. Sie müssen eine Test-Binärdatei erneut ausführen, um die Anzahl der Tasks zu ändern.
Wissenschaftliche Codes haben oft viele eng gekoppelte, voneinander abhängige und austauschbare Teile. Wir haben alle den alten Code gesehen und wissen, wie verlockend es ist, auf gutes Design zu verzichten und globale Variablen zu verwenden.
Häufig ist eine numerische Methode ein "Experiment", oder der Codierer versteht nicht vollständig, wie sie funktioniert, und versucht, sie zu verstehen. Daher ist es unmöglich, Ergebnisse vorwegzunehmen.
Einige Beispiele für Tests, die ich für wissenschaftlichen Code schreibe:
Verwenden Sie für Zeitintegratoren eine einfache ODE mit einer genauen Lösung, und prüfen Sie, ob Ihr Integrator diese mit einer bestimmten Genauigkeit löst. Die Reihenfolge der Genauigkeit ist korrekt, indem Sie mit verschiedenen Schrittgrößen testen.
Nullstabilitätstests: Stellen Sie sicher, dass eine Methode mit 0 Rand- / Anfangsbedingungen bei 0 bleibt.
Interpolationstests: Bei gegebener linearer Funktion stellen Sie sicher, dass eine Interpolation korrekt ist.
Legacy-Validierung: Isolieren Sie einen Teil des Codes in einer Legacy-Anwendung, von der bekannt ist, dass sie korrekt ist, und ziehen Sie einige diskrete Werte zum Testen heraus.
Es kommt immer noch oft vor, dass ich nicht herausfinden kann, wie man einen bestimmten Codeabschnitt richtig testet, abgesehen von manuellen Versuchen und Irrtümern. Können Sie einige Beispiele für Tests angeben, die Sie für numerischen Code schreiben, und / oder allgemeine Strategien zum Testen von wissenschaftlicher Software?
Antworten:
Methode der hergestellten Lösungen .
Stellen Sie durch Verfeinerungsstudien sicher, dass die Methode die theoretische Genauigkeitsordnung erreicht.
Bewahrung der Antwort. Bit- und normgerechte Wiedergabe von Lösungen.
quelle
Bill hat bereits einige Methoden aufgelistet, die auf Ihre Bedenken eingehen.
Wenn Sie Ihren dritten Punkt ansprechen, nein, es gibt keinen Grund, eine starke Kopplung zwischen Teilen einzuführen. Im Gegenteil: Wenn Ihre Funktionen oder Klassen gut definierte Schnittstellen haben, ist es viel einfacher, beispielsweise einen linearen Löser gegen einen anderen oder ein Zeitschrittschema auszutauschen. Einfach widerstehen, und dann können Sie diese Komponenten separat testen. Wir haben dies mit deal.II seit Jahrzehnten getan.
Zu Ihrem vierten Punkt: Wenn Ihre Methode ein Experiment ist, sind Ihre Experimente mit der Methode ein Test. Solange Sie keine Analyse haben, müssen Sie diese Testergebnisse als am besten verfügbar ansehen. Aber normalerweise haben Sie eine Erwartung zum Beispiel für die Reihenfolge einer Methode, oder Sie würden wissen, dass sie für eine bestimmte Klasse von Lösungen genau ist, zum Beispiel Polynome bis zu einem gewissen Grad. Die Überprüfung sollte Teil Ihrer Experimente sein. Wenn sich die Analyse verbessert, können Tests hinzugefügt werden.
quelle
Ich habe kürzlich diese Dissertation über TDD in Computational Science gefunden. Ich habe es noch nicht gelesen, daher habe ich keine Ahnung, ob es etwas Gutes ist, aber hoffentlich kann es hilfreich sein.
http://cyber.ua.edu/files/2014/12/u0015_0000001_0001551.pdf
quelle