Ich erweitere mein Ruby-Verständnis, indem ich ein Äquivalent von Kent Becks xUnit in Ruby codiere. Python (in das Kent schreibt) hat eine assert () -Methode in der Sprache, die häufig verwendet wird. Ruby nicht. Ich denke, es sollte einfach sein, dies hinzuzufügen, aber ist Kernel der richtige Ort, um es zu platzieren?
Übrigens, ich kenne die Existenz der verschiedenen Unit-Frameworks in Ruby - dies ist eine Übung, um die Ruby-Redewendungen zu lernen, anstatt "etwas zu erledigen".
Antworten:
Nein, es ist keine bewährte Methode. Die beste Analogie zu assert () in Ruby ist nur das Erhöhen
raise "This is wrong" unless expr
und Sie können Ihre eigenen Ausnahmen implementieren, wenn Sie eine spezifischere Ausnahmebehandlung bereitstellen möchten
quelle
fail if [expr]
Wenn Sie möchten, können Sie auch einen Laufzeitfehler verwenden.fail
ist ein Alias fürraise
, nicht wahr? Sie geben beideRuntimeError
. (Vielleicht ist einer idiomatischer?)Ich denke, es ist absolut gültig, Asserts in Ruby zu verwenden. Aber Sie erwähnen zwei verschiedene Dinge:
assert
Methoden zur Überprüfung Ihrer Testerwartungen. Sie sollen in Ihrem Testcode verwendet werden, nicht in Ihrem Anwendungscode.assert
Konstruktion, die im Code Ihrer Programme verwendet werden soll, um die von Ihnen getroffenen Annahmen über deren Integrität zu überprüfen. Diese Überprüfungen werden im Code selbst erstellt. Sie sind kein Dienstprogramm zur Testzeit, sondern ein Dienstprogramm zur Entwicklungszeit.Ich habe kürzlich solid_assert geschrieben: eine kleine Ruby-Bibliothek, die ein Ruby-Assertion-Dienstprogramm implementiert, sowie einen Beitrag in meinem Blog, in dem die Motivation erläutert wird .
assert some_string != "some value" assert clients.empty?, "Isn't the clients list empty?" invariant "Lists with different sizes?" do one_variable = calculate_some_value other_variable = calculate_some_other_value one_variable > other_variable end
Und sie können so deaktiviert
assert
undinvariant
als leere Anweisungen ausgewertet werden. Auf diese Weise können Sie Leistungsprobleme in der Produktion vermeiden. Beachten Sie jedoch, dass die Pragmatischen Programmierer davon abraten, sie zu deaktivieren. Sie sollten sie nur deaktivieren, wenn sie sich wirklich auf die Leistung auswirken.In Bezug auf die Antwort, dass der idiomatische Ruby-Weg eine normale
raise
Aussage verwendet, denke ich, dass es an Ausdruckskraft mangelt. Eine der goldenen Regeln der durchsetzungsfähigen Programmierung besteht darin, keine Zusicherungen für die normale Ausnahmebehandlung zu verwenden. Das sind zwei völlig verschiedene Dinge. Wenn Sie für beide dieselbe Syntax verwenden, wird Ihr Code meiner Meinung nach dunkler. Und natürlich verlieren Sie die Fähigkeit, sie zu deaktivieren.Sie können davon überzeugt sein, dass die Verwendung von Behauptungen eine gute Sache ist, da zwei klassische Bücher wie The Pragmatic Programmer From Journeyman to Master und Code Complete ihnen ganze Abschnitte widmen und ihre Verwendung empfehlen. Es gibt auch einen schönen Artikel mit dem Titel Programmieren mit Behauptungen , die sehr gut veranschaulichen, worum es bei durchsetzungsfähiger Programmierung geht und wann sie verwendet werden soll (sie basiert auf Java, aber Konzepte gelten für jede Sprache).
quelle
Was ist Ihr Grund, die Assert-Methode zum Kernel-Modul hinzuzufügen? Warum nicht einfach ein anderes Modul namens
Assertions
oder so verwenden?So was:
module Assertions def assert(param) # do something with param end # define more assertions here end
Wenn Sie wirklich möchten, dass Ihre Behauptungen überall verfügbar sind, gehen Sie wie folgt vor:
class Object include Assertions end
Haftungsausschluss: Ich habe den Code nicht getestet, aber im Prinzip würde ich es so machen.
quelle
Object
Klasse.assert
Methode wirklich global verfügbar machen müssen. Ich würde jedoch niemandem raten, solche Affen-Patches in Nicht-Spielzeug-Projekten zu verwenden.Es ist nicht besonders idiomatisch, aber ich denke, es ist eine gute Idee. Besonders wenn es so gemacht wird:
def assert(msg=nil) if DEBUG raise msg || "Assertion failed!" unless yield end end
Auf diese Weise hat dies keine Auswirkungen, wenn Sie sich entscheiden, nicht mit DEBUG (oder einem anderen praktischen Schalter, den ich in der Vergangenheit mit Kernel.do_assert verwendet habe) zu arbeiten.
quelle
Meines Wissens nach schreiben Sie Ihre eigene Testsuite, um sich mit Ruby vertraut zu machen. Während Test :: Unit als Leitfaden nützlich sein kann, ist es wahrscheinlich nicht das, wonach Sie suchen (weil es die Arbeit bereits erledigt hat).
Das heißt, Pythons Behauptung ist (zumindest für mich) analoger zu Cs Behauptung (3) . Es wurde nicht speziell für Unit-Tests entwickelt, sondern um Fälle zu erfassen, in denen "dies niemals passieren sollte".
Rubys integrierte Komponententests sehen das Problem in der Regel so, dass jede einzelne Testfallklasse eine Unterklasse von TestCase ist und eine "assert" -Anweisung enthält , die die Gültigkeit der übergebenen Tests überprüft und aufzeichnet Berichterstattung.
quelle