Bedenken Sie:
public function polynominal($a, $b, $c, $d)
{
return $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}
Angenommen, Sie schreiben verschiedene Tests für die obige Funktion und beweisen sich und anderen, dass "es funktioniert".
Warum dann nicht diese Tests entfernen und glücklich für immer leben? Mein Punkt ist, dass einige Funktionen nicht kontinuierlich getestet werden müssen, nachdem nachgewiesen wurde, dass sie funktionieren. Ich suche Kontrapunkte, die besagen, ja diese Funktionen müssen noch getestet werden, weil: ... oder dass ja diese nicht getestet werden müssen ...
php
unit-testing
testing
tdd
Dennis
quelle
quelle
override_function('pow', '$a,$b', 'return $a * $b;');
bei klarem Verstand schreiben ... oder versuchen, es umzuschreiben, um mit komplexen Zahlen umzugehen.(($a*$x + $b)*$x + $c)*$x + $d
die leicht falsch ist, aber oft erheblich schneller ist. Nur weil du denkst, dass es sich nicht ändern wird, heißt das nicht, dass es sich nicht ändern wird.Antworten:
Regressionstests
Es geht nur um Regressionstests .
Stellen Sie sich vor, der nächste Entwickler betrachtet Ihre Methode und merkt, dass Sie magische Zahlen verwenden. Ihm wurde gesagt, dass magische Zahlen böse sind, also erstellt er zwei Konstanten, eine für die Nummer zwei, die andere für die Nummer drei - es ist nichts Falsches daran, diese Änderung vorzunehmen; Es ist nicht so, als würde er Ihre bereits korrekte Implementierung modifizieren.
Abgelenkt kehrt er zwei Konstanten um.
Er schreibt den Code fest, und alles scheint gut zu funktionieren, da nach jedem Festschreiben keine Regressionstests ausgeführt werden.
Eines Tages (könnte Wochen später sein) bricht irgendwo etwas zusammen. Und anderswo meine ich den völlig entgegengesetzten Ort der Codebasis, der nichts mit
polynominal
Funktion zu tun zu haben scheint . Stunden schmerzhaftes Debuggen führen zum Täter. Während dieser Zeit fällt die Anwendung in der Produktion weiterhin aus, was Ihren Kunden viele Probleme bereitet.Das Beibehalten der ursprünglichen Tests, die Sie geschrieben haben, kann solche Schmerzen verhindern. Der abgelenkte Entwickler gab den Code ein und stellte fast sofort fest, dass er etwas kaputt gemacht hatte. Ein solcher Code wird nicht einmal die Produktion erreichen. Unit-Tests werden außerdem den Ort des Fehlers sehr genau beschreiben . Es wäre nicht schwierig, es zu lösen.
Ein Nebeneffekt...
Tatsächlich basieren die meisten Umgestaltungen stark auf Regressionstests. Nehmen Sie eine kleine Änderung vor. Prüfung. Wenn es geht, ist alles in Ordnung.
Der Nebeneffekt ist, dass, wenn Sie keine Tests haben, praktisch jedes Refactoring ein großes Risiko darstellt, den Code zu brechen. Da dies in vielen Fällen der Fall ist, ist es bereits schwierig, dem Management zu erklären, dass das Refactoring durchgeführt werden sollte. Dies ist sogar noch schwieriger, nachdem bei Ihren vorherigen Refactoring-Versuchen mehrere Fehler aufgetreten sind.
Wenn Sie über eine vollständige Testsuite verfügen, fördern Sie das Refactoring und damit einen saubereren Code. Ohne Risiko wird es sehr verlockend, regelmäßig mehr zu refactern.
Änderungen der Anforderungen
Ein weiterer wesentlicher Aspekt ist, dass sich die Anforderungen ändern. Möglicherweise werden Sie aufgefordert , komplexe Zahlen zu verarbeiten , und plötzlich müssen Sie in Ihrem Versionskontrollprotokoll nach den vorherigen Tests suchen, diese wiederherstellen und neue Tests hinzufügen.
Warum all diese Probleme? Warum Tests entfernen, um sie später hinzuzufügen? Sie hätten sie an erster Stelle behalten können.
quelle
Denn nichts ist so einfach, dass es keine Bugs geben kann.
Ihr Code scheint auf den ersten Blick fehlerfrei zu sein. Es ist in der Tat eine einfache programmatische Darstellung einer Polynomfunktion.
Außer es hat einen Bug ...
$x
ist nicht als Eingabe für Ihren Code definiert. Abhängig von der Sprache, der Laufzeit oder dem Gültigkeitsbereich funktioniert Ihre Funktion möglicherweise nicht, führt möglicherweise zu ungültigen Ergebnissen oder stürzt ein Raumschiff ab .Nachtrag:
Während Sie Ihren Code für jetzt für fehlerfrei halten können, ist es schwer zu sagen, wie lange das so bleibt. Man könnte argumentieren, dass es sich nicht lohnt, einen Test für ein so triviales Stück Code zu schreiben. Wenn Sie jedoch den Test bereits geschrieben haben, ist die Arbeit erledigt, und das Löschen dieses Tests löscht einen greifbaren Schutz.
Bemerkenswert sind auch Code-Coverage-Services (wie coveralls.io), die einen guten Hinweis auf die Coverage geben, die eine Testsuite bietet. Indem Sie jede Codezeile abdecken, geben Sie eine angemessene Metrik für die Quantität (wenn nicht die Qualität) der von Ihnen durchgeführten Tests an. In Kombination mit vielen kleinen Tests sagen Ihnen diese Dienste zumindest, wo Sie nicht nach einem Fehler suchen müssen, wenn er auftritt.
Wenn Sie bereits einen Test geschrieben haben, behalten Sie diesen . Weil die Zeit- oder Platzersparnis beim Löschen wahrscheinlich viel geringer ist als die technische Verschuldung, wenn später ein Fehler auftritt.
quelle
Ja. Wenn wir mit 100% iger Sicherheit sagen könnten: Diese Funktion wird niemals bearbeitet und wird niemals in einem Kontext ausgeführt, der zum Fehlschlagen führen könnte. Wenn wir das sagen könnten, könnten wir die Tests verwerfen und bei jedem Vorgang ein paar Millisekunden sparen CI bauen.
Aber wir können nicht. Oder wir können nicht mit vielen Funktionen. Und es ist einfacher, eine Regel zu haben, nach der alle Tests die ganze Zeit ausgeführt werden, als genau zu bestimmen, mit welcher Vertrauensschwelle wir zufrieden sind und wie viel Vertrauen wir in die Unveränderlichkeit und Unfehlbarkeit einer bestimmten Funktion haben.
Und die Bearbeitungszeit ist günstig. Diese Millisekunden, die gespart und sogar um ein Vielfaches vervielfacht wurden, reichen nicht aus, um sich bei jeder Funktion die Zeit zu nehmen und zu fragen: Sind wir sicher genug, dass wir sie nie wieder testen müssen?
quelle
Alles, was in den anderen Antworten gesagt wurde, ist richtig, aber ich werde noch eine hinzufügen.
Dokumentation
Unit-Tests können einem Entwickler, wenn sie gut geschrieben sind, genau erklären, was eine Funktion tut, welche Eingabe- / Ausgabeerwartungen sie hat und was noch wichtiger ist, welches Verhalten von ihr erwartet werden kann.
Dies kann das Erkennen eines Fehlers erleichtern und die Verwirrung verringern.
Nicht jeder merkt sich Polynome, Geometrie oder sogar Algebra :) Aber ein guter Komponententest, der zur Versionskontrolle eingecheckt wurde, wird sich für mich daran erinnern.
Ein Beispiel dafür, wie nützlich es als Dokumentation sein kann, finden Sie in der Jasmine-Einführung: http://jasmine.github.io/edge/introduction.html Nehmen Sie sich ein paar Sekunden Zeit zum Laden und scrollen Sie dann nach unten. Sie sehen die gesamte Jasmine-API als Unit-Test-Ausgabe.
[Aktualisierung basierend auf dem Feedback von @Warbo] Tests sind garantiert ebenfalls auf dem neuesten Stand, da sie sonst fehlschlagen, was im Allgemeinen zu einem Build-Fehler führt, wenn CI verwendet wird. Die externe Dokumentation ändert sich unabhängig vom Code und ist daher nicht unbedingt auf dem neuesten Stand.
quelle
Reality-Check
Ich war in herausfordernden Umgebungen, in denen das Testen "Zeitverschwendung" während der Budgetierung und des Zeitplans ist, und dann "ein grundlegender Teil der Qualitätssicherung", sobald der Kunde mit Fehlern zu tun hat. Meine Meinung ist also flüssiger als die anderer.
Sie haben ein Budget. Ihre Aufgabe ist es, das bestmögliche Produkt für dieses Budget zu erhalten, unabhängig von der Definition des "besten", das Sie zusammenkratzen können (es ist kein leicht zu definierendes Wort). Ende der Geschichte.
Testen ist ein Werkzeug in Ihrem Inventar. Sie sollten es verwenden, weil es ein gutes Werkzeug ist , mit einer langen Geschichte des Sparens von Millionen oder vielleicht sogar Milliarden von Dollar. Wenn Sie eine Chance haben, sollten Sie diesen einfachen Funktionen Tests hinzufügen. Es kann Ihre Haut eines Tages retten.
In der realen Welt kann dies jedoch aufgrund von Budget- und Zeitplanbeschränkungen nicht passieren. Machen Sie sich nicht zum Sklaven des Verfahrens. Testfunktionen sind nett, aber irgendwann sollten Sie die Entwicklerdokumentation besser in Worten als in Code schreiben, damit der nächste Entwickler nicht so viele Tests benötigt. Oder es könnte besser sein, die Codebasis umzugestalten, damit Sie nicht so schwierig wie ein Biest bleiben müssen. Oder vielleicht ist es besser, diese Zeit damit zu verbringen, mit Ihrem Chef über das Budget und den Zeitplan zu sprechen, damit er oder sie besser versteht, worum es bei der nächsten Finanzierungsrunde geht.
Softwareentwicklung ist ein Gleichgewicht. Zählen Sie immer die Opportunitätskosten für alles, was Sie tun, um sicherzustellen, dass es keinen besseren Weg gibt, Ihre Zeit zu verbringen.
quelle
Ja, halten Sie die Tests aufrecht, lassen Sie sie weiterlaufen und bestehen Sie sie.
Unit-Tests sollen Sie (und andere) vor sich selbst (und sich selbst) schützen.
Warum ist es eine gute Idee, die Tests beizubehalten?
quelle
Entwicklerdokumentation
Benutzerdokumentation
quelle