RSpec-Test für Anfänger, Teil 3

In diesem abschließenden Artikel über die RSpec-Grundlagen werden einige wenige nützliche Aspekte behandelt, die Sie vermeiden können und sollten, wie Sie Ihre Tests zusammenstellen sollten, warum Sie die Datenbank möglichst vermeiden sollten und wie Sie Ihre Testsuite beschleunigen können.  

Themen

  • Testgeschwindigkeit
  • Datenbank-Engpässe
  • Spring Preloader
  • Iffy RSpec Convenience
  • Mystery Gäste
  • Inline-Code
  • Extrahieren Sie Methoden

Nachdem Sie nun die Grundlagen in der Hand haben, sollten wir uns die Zeit nehmen, ein paar fette Teile von RSpec und TDD zu besprechen - einige Probleme, die leicht überlastet werden können, und einige Nachteile der Verwendung von Teilen von RSpecs DSL. Ich möchte vermeiden, dass in Ihr frisch geschlüpftes TDD-Gehirn viele fortschrittliche Konzepte gestoppt werden, aber ich denke, dass ein paar Punkte gemacht werden müssen, bevor Sie mit Ihrem ersten Testrausch beginnen. Das Erstellen einer langsamen Testsuite aufgrund von schlechten Gewohnheiten, die leicht zu vermeiden sind, können Sie als Anfänger sofort verbessern.

Sicher, es gibt einige Dinge, die Sie benötigen, um mehr Erfahrung zu sammeln, bevor Sie sich beim Testen wohl und effektiv fühlen werden, aber ich wette, dass Sie sich auch von Anfang an besser fühlen werden, wenn Sie einige der besten Methoden wegnehmen, die Ihr Wissen verbessern Specs Mannigfaltigkeit, ohne Ihre Fähigkeiten im Moment zu sehr zu dehnen. Es ist auch ein kleines Fenster mit fortgeschrittenen Konzepten, die Sie im Laufe der Zeit zum "Master" -Test nutzen müssen. Ich habe das Gefühl, dass ich Sie am Anfang mit diesen nicht allzu sehr belästigen sollte, da es sich nur als verwirrt und verwirrend anfühlt, bevor Sie das größere Bild entwickelt haben, das alles ordentlich zusammenhält.

Testgeschwindigkeit

Beginnen wir mit der Geschwindigkeit. Eine schnelle Suite ist nichts, was zufällig passiert. es handelt sich um eine "ständige" Wartung. Das häufige Anhören Ihrer Tests ist ziemlich wichtig. Zumindest wenn Sie an Bord von TDD sind und seit einiger Zeit Kool-Aid trinken. Schnelle Testsuiten machen es viel sinnvoller, darauf zu achten, wohin die Tests führen Sie.

Testgeschwindigkeit ist etwas, auf das Sie gut aufpassen sollten. Es ist wichtig, dass das Testen regelmäßig zur Gewohnheit wird und Spaß macht. Sie möchten Ihre Tests schnell ausführen können, damit Sie während der Entwicklung schnell ein Feedback erhalten. Je länger es dauert, die Testsuite zu trainieren, desto wahrscheinlicher ist es, dass Sie das Testen immer mehr überspringen, bis Sie es erst am Ende tun, bevor Sie eine neue Funktion ausliefern möchten. 

Das hört sich auf den ersten Blick nicht so schlecht an, ist aber kein unbedeutendes Problem. Einer der Hauptvorteile einer Testsuite besteht darin, dass sie das Design Ihrer Anwendung bestimmt - für mich ist dies wahrscheinlich der größte Gewinn von TDD. Längere Testläufe machen diesen Teil ziemlich unmöglich, da Sie ihn wahrscheinlich nicht ausführen werden, um Ihren Fluss nicht zu beeinträchtigen. Schnelle Tests garantieren, dass Sie keinen Grund haben, Ihre Tests nicht durchzuführen.

Sie können diesen Prozess als einen Dialog zwischen Ihnen und der Testsuite sehen. Wenn dieses Gespräch zu langsam wird, ist es wirklich schmerzhaft, fortzufahren. Wenn Ihr Code-Editor die Möglichkeit bietet, Ihre Tests auch auszuführen, sollten Sie diese Funktion auf jeden Fall verwenden. Dies erhöht die Geschwindigkeit erheblich und verbessert Ihren Arbeitsablauf. Jedes Mal, wenn Sie zwischen Ihrem Editor und einer Shell wechseln, um Ihre Tests auszuführen, wird sehr schnell alt. Da sich diese Artikel jedoch an Neulinge richten, rechne ich nicht damit, dass Sie Ihre Tools sofort so einrichten. Es gibt andere Möglichkeiten, wie Sie diesen Prozess verbessern können, ohne sofort mit Ihrem Editor basteln zu müssen. Es ist jedoch gut zu wissen, und ich empfehle, solche Tools in Ihren Workflow zu integrieren.

Beachten Sie außerdem, dass Sie bereits gelernt haben, wie Sie Ihre Tests schneiden, und dass Sie nicht immer die gesamte Testsuite ausführen müssen. Sie können problemlos einzelne Dateien oder sogar einzelne Dateien ausführen es Blöcke - alles in einem fähigen Code-Editor, ohne ihn für das Terminal zu verlassen. Sie können den Test beispielsweise auf die zu testende Linie fokussieren. Das fühlt sich an wie Magie, um ehrlich zu sein - es wird nie langweilig.

Datenbank-Engpässe

Wenn Sie zu viel in die Datenbank schreiben - oft sehr unnötig -, ist dies eine sichere Methode, um Ihre Testsuite schnell zu verlangsamen. In vielen Testszenarien können Sie die Daten herausfiltern, die Sie zum Einrichten eines Tests benötigen, und sich nur auf die Daten konzentrieren, die gerade getestet werden. Sie müssen nicht die meiste Zeit über die gesamte Datenbank zugreifen - vor allem nicht für Teile, die nicht direkt geprüft werden, und die den Test nur irgendwie unterstützen: einen angemeldeten Benutzer, während Sie den zu zahlenden Betrag testen Checkout zum Beispiel. Der Benutzer ist wie ein Extra, das heraus gefälscht werden kann. 

Sie sollten versuchen, davon auszugehen, dass Sie die Datenbank nicht so oft wie möglich treffen, da dies einen großen Teil einer langsamen Testsuite beißt. Versuchen Sie auch, nicht zu viele Daten einzurichten, wenn Sie sie überhaupt nicht benötigen. Das kann besonders bei Integrationstests sehr leicht vergessen werden. Unit-Tests sind definitionsgemäß oft sehr viel fokussierter. Diese Strategie wird sich als sehr effektiv erweisen, um die Verlangsamung der Testreihen im Laufe der Zeit zu vermeiden. Wählen Sie Ihre Abhängigkeiten mit großer Sorgfalt aus und sehen Sie sich an, welche Datenmenge Ihre Tests am kleinsten sind.

Ich möchte jetzt nicht näher darauf eingehen - es ist wahrscheinlich ein bisschen zu früh, um über Stubs, Spione, Fakes und so weiter zu sprechen. Sie hier mit solchen fortschrittlichen Konzepten zu verwechseln, scheint kontraproduktiv zu sein, und Sie werden bald auf diese stoßen. Es gibt viele Strategien für schnelle Tests, an denen auch andere Tools als RSpec beteiligt sind. Versuchen Sie zunächst, Ihren Kopf mit RSpec und Tests im Allgemeinen rundherum zu umwickeln.

Sie möchten auch alles nur einmal testen, wenn möglich. Testen Sie nicht immer wieder dasselbe - das ist einfach verschwenderisch. Dies geschieht meistens durch Zufall und / oder schlechte Designentscheidungen. Wenn Sie mit langsamen Tests angefangen haben, können Sie dies leicht umgestalten, um einen Geschwindigkeitsschub zu erhalten.

Die Mehrzahl Ihrer Tests sollte sich auch auf der Ebene der Einheiten befinden, um Ihre Modelle zu testen. Dies wird nicht nur die Dinge schnell halten, sondern Ihnen auch den größten Knall für das Geld geben. Integrationstests, bei denen ganze Workflows getestet werden, die das Verhalten des Benutzers bis zu einem gewissen Grad nachahmen, indem mehrere Komponenten zusammengebracht und synchron getestet werden, sollten der kleinste Teil Ihrer Testpyramide sein. Diese sind eher langsam und "teuer". Vielleicht sind 10% Ihrer Tests insgesamt nicht unrealistisch, aber das hängt davon ab, denke ich.

Die Datenbank so wenig wie möglich zu trainieren, kann schwierig sein, da Sie einige weitere Tools und Techniken erlernen müssen, um dies effektiv zu erreichen. Es ist jedoch wichtig, Testsuiten zu entwickeln, die relativ schnell und schnell genug sind, um Ihre Tests regelmäßig auszuführen.

Spring Preloader

Der Spring-Server ist eine Funktion von Rails und lädt Ihre Anwendung vor. Dies ist eine weitere unkomplizierte Strategie, um Ihre Testgeschwindigkeit deutlich zu erhöhen - direkt nach dem Auspacken, sollte ich hinzufügen. Die Anwendung läuft einfach im Hintergrund, ohne dass sie bei jedem Testlauf neu gestartet werden muss. Gleiches gilt für Rake-Aufgaben und Migrationen. diese werden auch schneller laufen.

Seit Rails 4.1 wurde Spring automatisch in Rails aufgenommen und der Gemfile automatisch hinzugefügt - und Sie müssen nicht viel tun, um diesen Preloader zu starten oder zu stoppen. In der Vergangenheit mussten wir dazu unsere eigenen Werkzeuge zusammenstellen - was Sie natürlich auch tun können, wenn Sie andere Vorlieben haben. Was wirklich nett und nachdenklich ist, ist, dass es automatisch neu startet, wenn Sie einige Edelsteine, Initialisierer oder Konfigurationsdateien ändern - eine nette und praktische Note, da Sie leicht vergessen können, sich selbst darum zu kümmern.

Standardmäßig ist es für die Ausführung konfiguriert Schienen und Rechen Nur Befehle. Also müssen wir es so einrichten, dass es auch mit läuft rspec Befehl zum Ausführen unserer Tests. Sie können wie folgt nach dem Status des Frühlings fragen:

Terminal

Federstatus

Ausgabe

Der Frühling läuft nicht.

Da die Ausgabe uns mitteilt, dass Spring nicht läuft, starten Sie es einfach mit Frühling Server. Wenn du jetzt rennst Federstatus, Sie sollten etwas Ähnliches sehen:

Ausgabe

Spring läuft: 3738 Spring Server | rspec-dummy | vor 21 secs gestartet

Jetzt sollten wir prüfen, welche Feder für die Vorspannung eingestellt ist.

Terminal

spring binstub --all

Ausgabe

* bin / rake: Feder bereits vorhanden * bin / Schienen: Feder bereits vorhanden

Dies sagt uns, dass Spring Rails vorspannt Rechen und Schienen Befehle und sonst nichts. Dass wir uns darum kümmern müssen. Wir müssen den Edelstein hinzufügen Federbefehle -Rspec, und unsere Tests können dann vorab geladen werden.

Gemfile

gem 'spring-command-rspec', Gruppe:: Entwicklung

Terminal

Bundle Install Bundle Exec Spring Binstub Rspec

Ich erspare dir die Ausgabe von Bundle installieren; Ich bin sicher, Sie haben bereits mehr als Ihren gerechten Anteil daran gesehen. Laufen Bündel exec spring binstub rspec, auf der anderen Seite erzeugt ein bin / rspec Datei, die im Grunde hinzugefügt wird, um von Spring vorinstalliert zu werden. Mal sehen, ob das funktioniert hat:

Terminal

spring binstub --all

Dies führte zu einem sogenannten binstub-a-Wrapper für ausführbare Dateien wie Schienen, Rechen, bündeln, rspec und so, dass, wenn Sie die verwenden rspec Befehl wird Spring verwendet. Nebenbei sorgen solche Binstubs dafür, dass Sie diese ausführbaren Dateien in der richtigen Umgebung ausführen. Sie können diese Befehle auch von jedem Verzeichnis in Ihrer App aus ausführen, nicht nur vom Stammverzeichnis aus. Der andere Vorteil von Binstubs ist, dass Sie nicht vorausgehen müssen Bündel exec Mit allem.

Ausgabe

* bin / rake: Feder bereits vorhanden * bin / rspec: Feder bereits vorhanden * bin / Schienen: Feder bereits vorhanden

Sieht A-OK aus! Lassen Sie uns den Spring-Server anhalten und neu starten, bevor wir fortfahren:

Terminal

spring stop spring server

Jetzt führen Sie den Spring-Server in einem dedizierten Terminalfenster aus und führen Ihre Tests mit einer etwas anderen Syntax in einem anderen aus. Wir müssen einfach jeden Testlauf mit dem vorangestellten Frühling Befehl:

Terminal

Frühjahrsspezifikation

Dies führt natürlich alle Ihre Spezifikationsdateien aus. Aber es ist nicht nötig, dort anzuhalten. Sie können auch einzelne Dateien oder markierte Tests über Spring ausführen - kein Problem! Und alle werden jetzt blitzschnell sein; In kleineren Testreihen wirken sie fast augenblicklich. Darüber hinaus können Sie dieselbe Syntax für Ihre verwenden Schienen und Rechen Befehle. Schön, wie??

Terminal

Federrechen Federschienen g Modell BondGirl Name: String Federrechen db: migrieren… 

Wir bekommen Spring aus der Box, um die Dinge in Rails zu beschleunigen, aber wir dürfen nicht vergessen, diesen kleinen Edelstein hinzuzufügen, damit Spring mit RSpec Ball spielen kann.

Iffy RSpec Convenience

Die in diesem Abschnitt erwähnten Dinge sind wahrscheinlich gut zu vermeiden, solange Sie eine andere Lösung für sie finden. Die Verwendung einiger RSpec-Funktionen kann dazu führen, dass schlechte Testgewohnheiten entwickelt werden. Was wir hier besprechen werden, ist an der Oberfläche bequem, könnte Sie aber später beißen.

Sie sollten nicht als AntiPatterns-Dinge betrachtet werden, die man sofort meiden sollte, sondern eher als „Gerüche“, Dinge, bei denen Sie vorsichtig sein sollten und die möglicherweise erhebliche Kosten verursachen, die Sie oft nicht bezahlen möchten. Die Begründung dafür beinhaltet einige weitere Ideen und Konzepte, mit denen Sie als Anfänger wahrscheinlich noch nicht vertraut sind - und ehrlich gesagt könnte es an diesem Punkt noch etwas über Ihrem Kopf sein -, aber ich sollte Sie zumindest mit ein paar nach Hause schicken rote Fahnen, über die man jetzt nachdenken und sich daran erinnern kann.

  • Lassen

Viel zu haben Lassen Referenzen können auf den ersten Blick sehr bequem erscheinen - vor allem, weil sie die Dinge ziemlich trocken machen. Es scheint eine ziemlich gute Extraktion zu sein, zum Beispiel sie oben in Ihren Dateien zu haben. Auf der anderen Seite können Sie sich leicht schwer damit befassen, Ihren eigenen Code zu verstehen, wenn Sie bestimmte Tests später einige Zeit später besuchen. Die Daten sind nicht in Ihrem Computer eingerichtet Lassen Blöcke helfen dem Verständnis Ihrer Tests nicht zu sehr. Das ist nicht so unbedeutend, wie es auf den ersten Blick klingen mag, besonders wenn andere Entwickler involviert sind, die auch Ihre Arbeit lesen müssen.

Diese Art von Verwirrung wird umso teurer, je mehr Entwickler beteiligt sind. Es ist nicht nur zeitaufwändig, wenn Sie auf die Jagd gehen müssen Lassen Referenzen immer wieder, es ist auch dumm, weil es mit sehr wenig Aufwand vermeidbar gewesen wäre. Klarheit ist König, daran besteht kein Zweifel. Ein weiteres Argument, um diese Daten inline zu halten, ist, dass Ihre Testsuite weniger spröde ist. Sie wollen nicht ein Kartenhaus bauen, das mit jedem instabiler wird Lassen Das bedeutet, dass Details vor jedem Test versteckt werden. Sie haben wahrscheinlich gelernt, dass die Verwendung globaler Variablen keine gute Idee ist. In diesem Sinne, Lassen ist semi-global in Ihren Spec-Dateien.

Ein weiteres Problem ist, dass Sie viele verschiedene Variationen und verschiedene Zustände für ähnliche Szenarien testen müssen. Ihnen wird bald der Name des vernünftigen Namens ausgehen Lassen Anweisungen, die alle verschiedenen Versionen abdecken, die Sie möglicherweise benötigen - oder am Ende einen Heuhaufen von Tonnen gleichartiger Zustandsvariationen enthalten. Wenn Sie die Daten in jedem Test direkt einrichten, haben Sie dieses Problem nicht. Lokale Variablen sind billig, gut lesbar und verwirren sich nicht mit anderen Bereichen. Sie können sogar noch ausdrucksvoller sein, da Sie nicht viele andere Tests berücksichtigen müssen, bei denen möglicherweise ein Problem mit einem bestimmten Namen auftritt. Sie möchten vermeiden, dass auf dem Framework ein weiteres DSL erstellt wird, das jeder für jeden verwendeten Test entschlüsseln muss Lassen. Ich hoffe, das fühlt sich sehr an wie eine Verschwendung von Zeit für alle.

  • Vor & nach dem

Speichern Sie Dinge wie Vor, nach dem und seine Variationen für besondere Anlässe und verwenden Sie es nicht die ganze Zeit und überall. Sehen Sie es als eine der großen Waffen, die Sie für Meta-Sachen herausziehen. Das Bereinigen Ihrer Daten ist ein gutes Beispiel, das für jeden einzelnen Test zu groß ist. Das wollen Sie natürlich herausholen.

Mystery Gäste

Oft stellst du die Lassen Diese Informationen befinden sich am oberen Rand einer Datei und verbergen diese Details vor anderen Tests, bei denen sie in der Datei gespeichert werden. Sie möchten, dass die relevanten Informationen und Daten so nahe wie möglich an dem Teil liegen, an dem Sie den Test tatsächlich ausführen, und nicht meilenweit entfernt, wodurch einzelne Tests dunkler werden. 

Am Ende fühlt es sich an wie zu viel Seil zum Aufhängen, weil Lassen führt weit verbreitete Fixtures ein. Dies führt im Wesentlichen zu Dummy-Testdaten, deren Umfang nicht eng genug ist. 

Dies führt leicht zu einem Hauptgeruch namens "Mystery Guest". Das bedeutet, dass Sie Testdaten haben, die aus dem Nichts auftauchen oder einfach angenommen werden. Sie müssen sie häufig zuerst aufspüren, um einen Test zu verstehen - insbesondere, wenn seit dem Schreiben des Codes einige Zeit vergangen ist oder wenn Sie eine Codebase noch nicht kennen. Es ist viel effektiver, Ihre Testdaten genau dort zu definieren, wo Sie sie benötigen - im Setup eines bestimmten Tests und nicht in einem viel größeren Bereich.

Agent Spec

… Beschreiben Agent, '#print_favorite_gadget' do it 'druckt den Agentennamen, den Rang und das Favoriten-Gadget' erwartet aus (agent.print_favorite_gadget) .to eq ('Commander Bond hat etwas für Aston Martins')

Wenn Sie sich das anschauen, liest es ganz gut, richtig? Es ist knapp, ein Einzeiler, ziemlich sauber, nein? Machen wir uns nichts vor. Dieser Test sagt uns nicht viel über das Agent fraglich, und es erzählt uns nicht die ganze Geschichte. Die Details zur Implementierung sind wichtig, aber wir sehen nichts davon. Der Agent scheint an einem anderen Ort geschaffen worden zu sein, und wir müssten ihn zuerst aufspüren, um vollständig zu verstehen, was hier vor sich geht. Auf den ersten Blick sieht es vielleicht elegant aus, aber es hat einen gewaltigen Preis.

Ja, Ihre Tests sind in dieser Hinsicht vielleicht nicht immer super TROCKEN, aber dies ist ein kleiner Preis dafür, ausdrucksvoller und verständlicher zu sein, denke ich. Sicher gibt es Ausnahmen, aber sie sollten eigentlich nur auf außergewöhnliche Umstände angewendet werden, nachdem Sie die Möglichkeiten von Ruby sofort ausgeschöpft haben. 

Mit einem Mystery-Gast müssen Sie herausfinden, woher die Daten kommen, warum sie wichtig sind und was ihre Besonderheiten wirklich sind. Wenn Sie die Implementierungsdetails in einem bestimmten Test selbst nicht sehen, wird Ihr Leben nur schwieriger, als es sein muss. Ich meine, tun Sie so, wie Sie sich fühlen, wenn Sie an Ihren eigenen Projekten arbeiten, aber wenn andere Entwickler involviert sind, wäre es schöner, darüber nachzudenken, wie sie ihre Erfahrung mit Ihrem Code so reibungslos wie möglich gestalten. 

Wie bei vielen Dingen liegt das Wesentliche natürlich in den Details, und Sie möchten sich und andere nicht im Dunkeln lassen. Lesbarkeit, Prägnanz und die Bequemlichkeit von Lassen sollte nicht mit dem Verlust von Klarheit in Bezug auf Implementierungsdetails und Fehlleitung einhergehen. Sie möchten, dass jeder einzelne Test die gesamte Geschichte erzählt und den gesamten Kontext bereitstellt, um sie sofort zu verstehen.

Inline-Code

Um es kurz zu machen: Sie möchten Tests haben, die leicht zu lesen sind und sich auf Test-by-Test-Basis besser erklären lassen. Versuchen Sie, alles anzugeben, was Sie im eigentlichen Test benötigen - und nicht mehr. Diese Art von Müll riecht wie jede andere Art Müll. Dies bedeutet auch, dass Sie die Details, die Sie für bestimmte Tests benötigen, so spät wie möglich hinzufügen sollten, wenn Sie Testdaten generell erstellen, und zwar innerhalb des tatsächlichen Szenarios und nicht an einem entfernten Ort. Die vorgeschlagene Verwendung von Lassen bietet eine andere Art von Bequemlichkeit, die dieser Idee zu widersprechen scheint.

Lassen Sie uns noch einmal mit dem vorherigen Beispiel fortfahren und es ohne das Mystery Guest-Problem implementieren. In der folgenden Lösung finden Sie alle relevanten Informationen für den Test inline. Wir können in dieser Spezifikation richtig bleiben, wenn sie versagt und an anderer Stelle keine zusätzlichen Informationen suchen muss.

Agent Spec

… Beschreiben Agent, '#print_favorite_gadget' do it 'druckt Namen, Rang und Lieblings-Gadget der Agenten' do agent = Agent.new (Name: 'James Bond', Rang: 'Commander', favorite_gadget: 'Aston Martin') erwarten (agent.print_favorite_gadget) .to eq ('Commander Bond hat etwas für Aston Martins') end end

Es wäre schön wenn Lassen Sie können Barebones-Testdaten einrichten, die Sie bei jedem Test nach Bedarf verbessern können. Dies ist jedoch nicht der Fall Lassen rollt. So nutzen wir heutzutage Fabriken über Factory Girl. 

Ich werde Ihnen die Details ersparen, zumal ich bereits ein paar Stücke darüber geschrieben habe. Hier sind meine neulich zugeschnittenen Artikel 101 und 201 über das, was Factory Girl zu bieten hat - wenn Sie schon neugierig sind. Es ist auch für Entwickler ohne viel Erfahrung geschrieben.

Schauen wir uns ein weiteres einfaches Beispiel an, das die inline eingerichteten Testdaten gut unterstützt:

Agent Spec

beschreiben Agent, '#current_mission' do it 'gibt den aktuellen Status der Mission und ihr Ziel aus. do doo_octopussy = Mission.new (Name:' Octopussy ', Ziel:' Stop bad white dude ') bond = Agent.new (name : 'James Bond', Status: 'Undercover-Vorgang', Abschnitt: '00', licence_to_kill: true) bond.missions << mission_octopussy expect(bond.current_mission).to eq ('Agent Bond is currently engaged in an undercover operation for mission Octopussy which aims to stop bad white dude') end end

Wie Sie sehen, haben wir alle Informationen, die dieser Test benötigt, an einem Ort und müssen an keiner anderen Stelle nach Besonderheiten suchen. Es erzählt eine Geschichte und ist nicht dunkel. Wie bereits erwähnt, ist dies nicht die beste Strategie für DRY-Code. Die Auszahlung ist jedoch gut. Klarheit und Lesbarkeit wiegt dieses kleine Stück repetitiven Code bei weitem auf, insbesondere in großen Codebases.

Angenommen, Sie schreiben ein neues, scheinbar nicht zusammenhängendes Feature, und dieser Test schlägt plötzlich als Kollateralschaden fehl und Sie haben diese Spezifikationsdatei seit Ewigkeiten nicht berührt. 

Glauben Sie, Sie würden sich freuen, wenn Sie zuerst die Setup-Komponenten entschlüsseln müssen, um diesen fehlgeschlagenen Test zu verstehen und zu beheben, bevor Sie mit einer völlig anderen Funktion fortfahren können, an der Sie gerade arbeiten? Ich denke nicht! Sie möchten so schnell wie möglich aus dieser "nicht verwandten" Spezifikation herauskommen und das andere Feature beenden. 

Wenn Sie alle Testdaten genau dort finden, wo Ihre Tests Ihnen sagen, wo sie versagen, erhöhen Sie Ihre Chancen, indem Sie eine lange Korrektur durchführen, ohne schnell einen völlig anderen Teil der App in Ihr Gehirn zu laden.

Extrahieren Sie Methoden

Sie können Ihren Code erheblich bereinigen und TROCKNEN, indem Sie Ihre eigenen Hilfsmethoden schreiben. Es ist nicht notwendig, RSpec DSL zu verwenden, um so billig wie eine Ruby-Methode zu sein. 

Nehmen wir an, Sie haben ein paar sich wiederholende Spiele gefunden, die sich langsam schmutzig anfühlen. Anstatt mit einem zu gehen Lassen oder ein Gegenstand, Definieren Sie eine Methode am unteren Rand eines Beschreibungsblocks (eine Konvention) und extrahieren Sie die Gemeinsamkeiten darin. Wenn es in einer Datei etwas breiter verwendet wird, können Sie es auch am Ende der Datei platzieren. 

Ein schöner Nebeneffekt ist, dass Sie sich nicht mit semi-globalen Variablen befassen. Sie sparen sich auch die ganze Reihe von Änderungen, wenn Sie die Daten etwas anpassen müssen. Sie können jetzt zu einem zentralen Ort gehen, an dem die Methode definiert ist, und alle Bereiche gleichzeitig beeinflussen. Nicht schlecht!

Agent Spec

Agent beschreiben, '#current_status', do it 'spekuliert über die Wahl des Agents durch den Agent, wenn der Status "Urlaub" ist : true) erwarten (bond.current_status) .to eq ('Commander Bond ist im Urlaub, wahrscheinlich auf den Bahamas'). Ende 'spekuliert er über die Wahl des Quartiermeisters, wenn der Status Urlaub ist'. q = Agent.new (Name: 'Q', Status: 'In Urlaub', Abschnitt: '00', licence_to_kill: true) Erwarte (q.current_status) .to eq ('Der Quartiermeister ist im Urlaub, wahrscheinlich bei DEF CON'). Ende

Wie Sie sehen, gibt es etwas repetitiven Setup-Code, und wir möchten vermeiden, dass dieser Code immer wieder geschrieben wird. Stattdessen möchten wir nur das Wesentliche für diesen Test sehen und eine Methode haben, die den Rest des Objekts für uns erstellt.

Agent Spec

Beschreibe Agent, '#current_status', do it 'spekuliert über die Wahl des Agenten durch den Agenten, wenn der Status Urlaub ist' ist im Urlaub, wahrscheinlich auf den Bahamas). "Es spekuliert über die Wahl des Quartiermeisters, wenn der Status" Urlaub "ist. do q = build_agent_on_vacation ('Q', 'On Vacation') erwarten (q.current_status). Der Quartiermeister ist im Urlaub, wahrscheinlich bei DEF CON ') end def build_agent_on_vacation (Name, Status) Agent.new (Name: Name, Status: Status, Abschnitt:' 00 ', licence_to_kill: true) end end

Nun kümmert sich unsere extrahierte Methode um die Sektion und Lizenz zum töten Zeug und lenkt uns dadurch nicht vom Wesentlichen ab. Natürlich ist dies ein Dummy-Beispiel, aber Sie können die Komplexität beliebig skalieren. Die Strategie ändert sich nicht. Es ist eine sehr einfache Refactoring-Technik - deshalb führe ich sie so früh ein, aber eine der effektivsten. Außerdem ist es fast ein Kinderspiel, die Extraktionswerkzeuge von RSpecs zu umgehen.

Was Sie auch beachten sollten, ist, wie ausdrucksstark diese Hilfsmethoden sein können, ohne einen zusätzlichen Preis zu zahlen.

Abschließende Gedanken

Wenn Sie einige Teile des RSpec DSL vermeiden und gute alte Prinzipien von Ruby und objektorientiertes Programmieren nutzen, können Sie Ihre Tests gut schreiben. Sie können das Wesentliche frei verwenden, beschreiben, Kontext und es, Na sicher. 

Finden Sie einen guten Grund, andere Teile von RSpec zu verwenden, und vermeiden Sie diese so lange wie möglich. Nur weil die Dinge praktisch erscheinen und ausgefallen sind, ist dies kein Grund genug, sie einzusetzen - es ist besser, die Dinge einfacher zu halten. 

Einfach ist gut; Es hält Ihre Tests gesund und schnell.