2010-09-17 14 views
37

A Rails/Werkzeug bestimmte Version: How deep are your unit tests?BDD mit Gurke und rspec - wann ist das redundant?

Im Moment schreibe ich zur Zeit:

  • Gurke Funktionen (Integrationstests) - diese Prüfung gegen die HTML/JS, die von unserer App zurückgegeben wird, aber testet manchmal auch andere Dinge, wie Anrufe an Drittanbieter-Dienste.
  • RSpec Controller Tests (Funktionstests), ursprünglich nur, wenn die Controller eine sinnvolle Logik haben, aber jetzt mehr und mehr.
  • RSpec Modelltests (Unit-Tests)

Manchmal ist dies unbedingt erforderlich; Es ist erforderlich, das Verhalten im Modell zu testen, das für den Endbenutzer nicht vollständig offensichtlich oder sichtbar ist. Wenn Modelle komplex sind, sollten sie definitiv getestet werden. Aber zu anderen Zeiten scheinen mir die Tests überflüssig. Testen Sie zum Beispiel die Methode foo, wenn sie nur von bar aufgerufen wird und bar getestet wird? Was ist, wenn bar eine einfache Hilfsmethode für ein Modell ist, das in einer Cucumber-Funktion verwendet und leicht getestet werden kann? Testen Sie die Methode sowohl in rspec als auch in Gurke? Ich habe Probleme damit, da das Schreiben von mehr Tests Zeit kostet und mehrere "Versionen" der effektiv gleichen Verhaltensweisen beibehält, was die Wartung der Testsuite zeitintensiver macht, was wiederum die Änderungen verteuert.

Kurz gesagt, glauben Sie, dass es eine Zeit gibt, in der nur das Schreiben von Gurkenfunktionen ausreicht? Oder sollten Sie immer auf allen Ebenen testen? Wenn Sie denken, dass es eine Grauzone gibt, wie hoch ist Ihre Schwelle für "dies benötigt einen funktionalen/Einheitstest". In der Praxis, was machst du zur Zeit und warum (oder warum nicht) hältst du es für ausreichend?


EDIT: Here's an example of what might be "test overkill." Zugegeben, ich konnte dies ziemlich schnell schreiben, aber es war völlig hypothetisch.

+0

kämpfte mit * genau * das gleiche Problem. Das Zeit-Nutzen-Verhältnis zu verwalten ist manchmal schwierig. – brad

+0

Ich bin auch neugierig darauf. Ich versuche nur herauszufinden, wie viele Controller/View-Tests wirklich notwendig sind, wenn ich eine Schicht von Cukes-Tests durch meine App laufen lasse. – wesgarrison

Antwort

27

Gute Frage, eine, mit der ich mich vor kurzem während der Arbeit an einer Rails App, die auch Gurke/RSpec verwendet, beschäftigt habe.Ich versuche auf jeder Ebene so viel wie möglich zu testen, aber ich habe auch festgestellt, dass ich mit der wachsenden Codebasis manchmal das Gefühl habe, dass ich mich unnötig wiederhole.

Mit "Outside-in" -Tests läuft mein Prozess normalerweise so ab: Gurkenszenario -> Controller Spec -> Model Spec. Mehr und mehr überspringe ich die Controller-Spezifikationen, da die Gurken-Szenarien einen Großteil ihrer Funktionalität abdecken. Ich gehe normalerweise zurück und füge die Controllerspezifikationen hinzu, aber es kann sich wie eine lästige Pflicht fühlen.

Ein Schritt, den ich regelmäßig mache, ist rcov auf meine Gurkenfunktionen mit rake cucumber:rcov laufen und nach bemerkenswerten Lücken in der Abdeckung suchen. Dies sind Bereiche des Codes, auf die ich mich konzentrieren muss, damit sie eine angemessene Abdeckung bieten, sei es Unit- oder Integrationstests.

Ich glaube, Modelle/Bibliotheken sollten sofort ausgiebig getestet werden, da es die Kerngeschäftslogik ist. Es muss isoliert arbeiten, außerhalb des normalen Web-Anfrage/Antwort-Prozesses. Wenn ich zum Beispiel über die Rails-Konsole mit meiner App interagiere, arbeite ich direkt mit der Geschäftslogik und möchte sicherstellen, dass Methoden, die ich an meinen Modellen/Klassen anrufe, gut getestet sind.

Am Ende des Tages, jede App ist anders und ich denke, es liegt an den Entwickler (s) zu bestimmen, wie viel Testabdeckung für verschiedene Teile der Codebasis gewidmet sein sollte und das richtige Gleichgewicht finden, so dass Ihr Test Die Suite lässt Sie nicht im Stich, wenn Ihre App wächst.

Hier ist ein interessanter Artikel, den ich von meinen Lesezeichen ausgegraben, die lesenswert ist: http://webmozarts.com/2010/03/15/why-not-to-want-100-code-coverage/

+0

Gute Link + wusste nicht über 'Rake Gurke: RCOV'. Aus Neugier, testen Sie Unit-Test jede Modellmethode, auch einfache Dinge, die Gurkenabdeckung haben? (Siehe mein Beispiel in der Frage) Halten Sie es für wichtig, dass Sie den Code nicht als "fertig" betrachten (d. H. Nicht erlaubt, zu committen oder zu master), bis er auf dieser Ebene getestet wird? – wuputah

+0

Normalerweise ziele ich auf Unit-Testabdeckung der meisten Modelle/Bibliotheken. Es passiert jedoch nicht immer, wenn ich voll im Fluss bin, Code schreibe, manchmal mache ich kurze Schnitte. Ich versuche regelmäßig auf erkennbare Lücken in meiner Testabdeckung zu prüfen, sei es manuell oder mit Tools wie rcov, und schließe dann diese Lücken. Und ich halte mich nicht an eine harte und schnelle Regel, als würde ich Code, der auf Geräteebene nicht getestet wurde, nicht begehen. Einfache boolesche Methoden wie in Ihrem Beispiel würde ich nicht befürchten, wenn sie keine Einheitentestabdeckung hätten, sondern Methoden mit irgendeiner Art von Komplexität, die ich versuche zu testen. – Sidane

0

Ich teste komplexe Modell/lib-Methoden mit rspec dann die Hauptgeschäftslogik im Web mit Gurke, also bin ich mir sicher, dass die Hauptfunktionen des Webs 100% funktionieren, wenn ich mehr Zeit und Ressourcen habe, teste ich alles andere.

+0

Ich habe die gleichen Gefühle, aber ich würde gerne mehr über Ihren Ansatz hören. Wie würden Sie andere davon überzeugen, dass dies der richtige Weg ist? – wuputah

+0

Der Hauptgrund, warum ich das tue, ist, weil ich nicht alles testen kann, also muss ich priorisieren und von wichtiger zu weniger testen. Um mehr von der Webseite abzudecken, schlage ich vor, einfache Spezifikationen für alle Modelle zu erstellen, um zu sehen, ob alles speichert/validiert, dann Spezifikationen für alle komplexen Methoden und zuletzt Gurke für alle Formen, Hauptansichten. Und wenn Sie mehr Zeit/Ressourcen haben, können Sie nicht so wichtige Dinge testen. – Gacha

2

Rails hat eine gut getestete Codebase, daher würde ich es vermeiden, Dinge, die in diesen Schritten behandelt werden, erneut zu testen.

Zum Beispiel, wenn es sich nicht um benutzerdefinierten Code handelt, ist es sinnlos, die Ergebnisse der Validierungen auf Einheiten- und Funktionsebene zu testen. Ich würde sie jedoch auf der Integrationsebene testen. Gurken-Features dienen als Spezifikationen für Ihr Projekt. Daher ist es sinnvoll anzugeben, dass Sie eine Validierung für x und y benötigen, selbst wenn es sich bei der Implementierung um eine einzeilige Deklaration im Modell handelt.

+0

Ja, aber: Während es mit Shoulda leicht genug ist, Validierungen in rspec zu testen, glaubst du, dass du Validierungen sowohl in Cucumber als auch in rspec testen solltest? Der Punkt ist nicht, dass Dinge getestet werden sollten oder nicht, sondern ob die Dinge auf mehreren Ebenen getestet werden sollten. Validierungen sind nicht gerade das, woran ich denke (besonders, weil Shoulda es so einfach macht), aber es ist ein vernünftiges Beispiel. Tun Sie so, als müssten Sie diese rspec-Tests von Hand schreiben! – wuputah

+2

Um es anders auszudrücken, was ich meinte war, dass Sie Ihren Originalcode auf allen Ebenen testen und alles auf der obersten Ebene testen sollten. Betrachten Sie beispielsweise ActiveRecord Lifecycle Callbacks. Sie müssen sich keine Gedanken darüber machen, ob die Callbacks beim Speichern aufgerufen werden. Sie müssen sich Gedanken darüber machen, ob das Ergebnis, das Sie von diesem Rückruf erwarten, im Datensatz enthalten ist oder nicht. – edgerunner

0

Es ist einfacher, einfache Spezifikationen für einfache Methoden zu schreiben. Es ist viel einfacher als Cukes zu schreiben.

Wenn Sie Ihre Methoden einfach halten - und Ihre Spezifikationen einfach halten - indem Sie nur die Logik innerhalb dieser Methode testen, werden Sie Freude an Komponententests haben.

Wenn etwas überflüssig ist, testet seine Gurke. Wenn Sie gut getestete Modelle und Lib getestet haben, sollte Ihre Software funktionieren.

+3

Bis Sie merken, dass Sie vergessen haben, einen Absenden-Button auf Ihrem Formular zu setzen, und Sie können nicht von A -> B in Ihrer App bekommen. Die fraglichen Methoden funktionieren möglicherweise isoliert und alle Ihre Komponententests bestehen, aber wenn sie in einer realen Situation verwendet werden, wird Ihre Anwendung nicht funktionieren. Integrationstests sind genauso wichtig wie Unit Tests imo und sollten nicht als redundant betrachtet werden. – Sidane

+0

Ja, das ist eine Perspektive. – Vojto

+0

Die Frage ist zu einem gewissen Grad subjektiv und eine über Best Practices.Ich verstehe definitiv die Idee, dass Integrationstests redundant erscheinen können, wenn Sie gut abgegrenzte Tests haben. Ich komme meistens aus dem anderen Blickwinkel, dass bei gegebenen Integrationstests der Rest manchmal überflüssig erscheint. Ich persönlich denke, dass dies ein besserer Ansatz ist, da Sidane darauf hinweist, dass Sie das "große Bild" verpassen können, wenn Sie keine Integrationstests haben. Ich denke, beide Meinungen haben jedoch ihren Wert. – wuputah

0

Sie in der Regel nicht wollen beide Gurke Geschichten und RSpec Controller specs/Integrationstests haben. Wählen Sie eine (in der Regel ist Gurke die bessere Wahl, außer für bestimmte Sonderfälle). Dann verwenden Sie RSpec für Ihre Modelle, und das ist alles was Sie brauchen.