Richten Sie RSpec ein, um einen Edelstein zu testen (nicht Rails).

154

Mit dem hinzugefügten Generator von rspec-Rails ist es ziemlich einfach, RSpec zum Testen einer Rails-Anwendung einzurichten. Aber wie wäre es mit RSpec zum Testen eines Edelsteins in der Entwicklung? Ich benutze keinen Juwelier oder solche Werkzeuge. Ich habe gerade Bundler ( bundle gem my_gem) verwendet, um die Struktur für das neue Juwel einzurichten und die * .gemspec manuell zu bearbeiten. Ich habe auch s.add_development_dependency "rspec", ">= 2.0.0"zu gemspec hinzugefügt und a bundle install.

Gibt es ein nettes Tutorial, was als nächstes zu tun ist, damit RSpec funktioniert?

Zardoz
quelle
Ich muss wohl eines schreiben :-) ... Zumindest gibt es zwei Juwelen, die es bereits gut integrieren: Acts-as-Taggable-On und Acts_as_geocodable.
Zardoz

Antworten:

255

Ich habe diese Antwort aktualisiert, um den aktuellen Best Practices zu entsprechen:

Bundler unterstützt die Edelsteinentwicklung perfekt. Wenn Sie ein Juwel erstellen, die nur Sie , was Sie brauchen in Ihrem Gemfile zu haben , ist folgendes:

source "https://rubygems.org"
gemspec

Dies weist Bundler an, beim Ausführen in Ihrer gemspec-Datei nach den Abhängigkeiten zu suchen bundle install.

Stellen Sie als Nächstes sicher, dass RSpec eine Entwicklungsabhängigkeit Ihres Edelsteins ist. Bearbeiten Sie die gemspec so, dass sie lautet:

spec.add_development_dependency "rspec"

Erstellen spec/spec_helper.rbund fügen Sie als Nächstes Folgendes hinzu:

require 'bundler/setup'
Bundler.setup

require 'your_gem_name' # and any other gems you need

RSpec.configure do |config|
  # some (optional) config here
end

Die ersten beiden Zeilen weisen Bundler an, nur die Edelsteine ​​in Ihre Edelsteinspezifikation zu laden. Wenn Sie Ihr eigenes Juwel auf Ihrem eigenen Computer installieren, werden Ihre Spezifikationen gezwungen, Ihren aktuellen Code zu verwenden, nicht die Version, die Sie separat installiert haben.

Erstellen Sie eine Spezifikation, zum Beispiel spec/foobar_spec.rb:

require 'spec_helper'
describe Foobar do
  pending "write it"
end

Optional: Fügen Sie eine .rspecDatei für die Standardoptionen hinzu und fügen Sie sie in den Stammpfad Ihres Edelsteins ein:

--color
--format documentation

Schließlich: Führen Sie die Spezifikationen aus:

$ rspec spec/foobar_spec.rb
iain
quelle
75
Um fair zu sein, sollten Sie stattdessen den Befehl init von RSpec aufrufen, um die Spezifikationsskelettdateien zu generieren, anstatt sie manuell eingeben zu müssen. Dies würde die Kompatibilität mit der von Ihnen verwendeten Version von RSpec sicherstellen: rspec --init
Attila Györffy
12
rspec --initwar nicht verfügbar, als ich das schrieb, aber guter Punkt!
iain
Eigentlich habe ich festgestellt, dass der beste Weg, um die Anforderungen im Spezifikationshelfer zu erfüllen, folgender ist: 'rubygems' erfordern 'bundler / setup' Bundler.require (: default ,: development)
mkon
Wie genau funktionieren die drei Codezeilen von @ mkon anders als die drei Codezeilen von iain?
Nakilon
1
Die Zeilen von @mkon erfordern alle Edelsteine ​​in den Entwicklungs- und Testgruppen, während mein Ansatz darin besteht, jeden Edelstein manuell zu benötigen. Da Sie bei der Herstellung von Edelsteinen jeden Edelstein selbst benötigen müssen, ist dies meiner Meinung nach der bessere / klarere Ansatz, auch wenn dies möglicherweise etwas mehr Arbeit bedeutet.
iain
53

Iains obige Lösung funktioniert großartig!

Wenn Sie auch ein Rakefile möchten, ist dies alles, was Sie brauchen:

require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

# If you want to make this the default task
task default: :spec

Überprüfen Sie das RDoc für RakeTask auf verschiedene Optionen, die Sie optional an die Aufgabendefinition übergeben können.

Mirko Froehlich
quelle
26

Sie können Ihren neuen Edelstein mit rspec generieren, indem Sie ausführen bundler gem --test=rspec my_gem. Kein zusätzliches Setup!

Ich vergesse das immer. Es ist hier implementiert: https://github.com/bundler/bundler/blob/33d2f67d56fe8bf00b0189c26125d27527ef1516/lib/bundler/cli/gem.rb#L36

StevenNunez
quelle
1
Ordentlich! Ich denke jedoch, dass Ihr Edelsteinname mit Unterstrichen anstelle des Kamelkastens angegeben werden sollte. Andernfalls erstellt Bundler Dateien mit Großbuchstaben (Bundler 1.7.4)
Malte
Bundler beschwerte sich --test=rspec, fragte mich aber trotzdem, ob ich Rspec beim Laufen verwenden wollte bundler gem my_gem.
Nicolas Mattia
7

Hier ist ein billiger und einfacher (wenn auch nicht offiziell empfohlener) Weg:

Machen Sie ein Verzeichnis in der Wurzel Ihres Edelsteins spec, geben Sie Ihre Spezifikationen dort ein. Sie haben wahrscheinlich bereits rspec installiert, aber wenn Sie dies nicht tun, machen Sie einfach eine gem install rspecund vergessen Sie Gemfiles und Bundler.

Als Nächstes erstellen Sie eine Spezifikation und müssen angeben, wo sich Ihre App befindet, wo sich Ihre Dateien befinden und die zu testende Datei (zusammen mit den vorhandenen Abhängigkeiten) angeben:

# spec/awesome_gem/awesome.rb
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
$: << File.join(APP_ROOT, 'lib/awesome_gem') # so rspec knows where your file could be
require 'some_file_in_the_above_dir' # this loads the class you want to test

describe AwesomeGem::Awesome do
  before do
    @dog = AwesomeGem::Awesome.new(name: 'woofer!')
  end
  it 'should have a name' do
    @dog.name.should eq 'woofer!'
  end
  context '#lick_things' do
    it 'should return the dog\'s name in a string' do
      @dog.lick_things.should include 'woofer!:'
    end
  end
end

Öffnen Sie das Terminal und führen Sie rspec aus:

~/awesome_gem $ rspec
..

Finished in 0.56 seconds
2 examples, 0 failures

Wenn Sie einige .rspecOptionen lieben möchten , .rspecerstellen Sie eine Datei und legen Sie sie im Stammpfad Ihres Edelsteins ab. Meins sieht so aus:

# .rspec
--format documentation --color --debug --fail-fast

Einfach, schnell, ordentlich!

Ich mag das, weil Sie Ihrem Projekt überhaupt keine Abhängigkeiten hinzufügen müssen und das Ganze sehr schnell bleibt. bundle execverlangsamt die Dinge ein wenig, was Sie tun müssen, um sicherzustellen, dass Sie immer dieselbe Version von rspec verwenden. Die 0,56 Sekunden, die zum Ausführen von zwei Tests benötigt wurden, waren zu 99% belegt, als mein Computer zum Laden von rspec benötigte. Das Ausführen von Hunderten von Spezifikationen sollte extrem schnell sein. Das einzige Problem, auf das Sie stoßen könnten, ist, dass Sie möglicherweise einige Tests neu schreiben müssen, wenn Sie die Versionen von rspec ändern und die neue Version nicht abwärtskompatibel mit einer Funktion ist, die Sie in Ihrem Test verwendet haben.

Dies ist hilfreich, wenn Sie einmalige Spezifikationen ausführen oder einen guten Grund haben, rspec NICHT in Ihre gemspec aufzunehmen. Es ist jedoch nicht sehr gut, um das Teilen zu ermöglichen oder die Kompatibilität zu erzwingen.

Wulftone
quelle
Gibt es eine Möglichkeit, AwesomeGem :: nicht vor Klassennamen zu setzen, wenn Sie auf ein Testobjekt verweisen? Oder wenn Sie einen neuen Test wie in Ihrem Beispiel erstellen.
Mischa Slyusarev
1
Sicher, Sie können entweder Ihren Klassennamen gleich etwas kürzer setzen, wie Thing = AwesomeGem::Awesomeoder Sie können den Test innerhalb eines Moduls durchführen, wiemodule AwesomeGem; it 'stuff' do; Awesome.new ... end; end
Wulftone