it-swarm.com.de

Vorher/Nachher Suite bei Verwendung von Ruby MiniTest

Gibt es eine Alternative zu RSpecs before(:suite) und after(:suite) in MiniTest?

Ich vermute, dass ein angepasster Testläufer in Ordnung ist, aber ich kann mir nicht vorstellen, dass dies keine allgemeine Anforderung ist, also hat wahrscheinlich jemand etwas implementiert. :-)

36
Nickolay Kolev

Es stehen setup() und teardown() Methoden zur Verfügung. Die Dokumentation listet auch before() und after() als verfügbar auf.

Bearbeiten: Möchten Sie vor jedem Test etwas ausführen oder vor oder nach Abschluss der gesamten Suite?

25
Caley Woods

Wie bereits in der Antwort und den Kommentaren von Caley erwähnt, enthält MiniTest::Unit die Funktion after_tests. Es gibt keinen before_tests oder gleichwertig, aber jeder Code in Ihrer minitest_helper.rb-Datei sollte vor der Testsuite ausgeführt werden, damit eine solche Funktion ausgeführt werden kann.

Vorbehalt: Noch relativ neu bei Ruby und sehr neu bei Minitest, also wenn ich falsch liege, bitte korrigiere mich! :-)

21
Gert Sønderby

Damit dies mit der aktuellen Version von Minitest (5.0.6) funktioniert, müssen Sie require 'minitest' und Minitest.after_run { ... } verwenden.

warn "MiniTest::Unit.after_tests is now Minitest.after_run. ..."

https://github.com/seattlerb/minitest/blob/master/lib/minitest.rbhttps://github.com/seattlerb/minitest/blob/master/lib/minitest/ unit.rb

19
dereckrx

Um Code vor each test auszuführen, verwenden Sie before. Sie arbeiten hier im Kontext einer Instanz, möglicherweise einer von describe implizit generierten Klasse. Daher sind in before gesetzte Instanzvariablen in jedem Test (z. B. innerhalb eines it-Blocks) verfügbar.

Um Code vor all tests auszuführen, packen Sie die Tests einfach in eine Klasse, eine Unterklasse von MiniTest::Spec oder was auch immer; Jetzt können Sie vor den Tests selbst eine Klasse oder ein Modul erstellen, Klassenvariablen festlegen, eine Klassenmethode aufrufen usw. Diese Funktionen stehen in allen Tests zur Verfügung.

Beispiel:

require "minitest/autorun"

class MySpec < MiniTest::Spec
  class MyClass
  end
  def self.prepare
    puts "once"
    @@prepared = "prepared"
    @@count = 0
  end
  prepare
  before do
    puts "before each test"
    @local_count = (@@count += 1)
  end
  describe "whatever" do
    it "first" do
      p MyClass
      p @@prepared
      p @local_count
    end
    it "second" do
      p MyClass
      p @@prepared
      p @local_count
    end
  end
end

Hier ist die Ausgabe zusammen mit meinen Kommentaren in Klammern, in denen erläutert wird, was jede Zeile der Ausgabe beweist:

once [this code, a class method, runs once before all tests]

Run options: --seed 29618 [now the tests are about to run]
# Running tests:

before each test [the before block runs before each test]
MySpec::MyClass [the class we created earlier is visible in each test]
"prepared" [the class variable we set earlier is visible in each test]
1 [the instance variable from the before block is visible in each test]

before each test [the before block runs before each test]
MySpec::MyClass [the class we created earlier is visible in each test]
"prepared" [the class variable we set earlier is visible in each test]
2 [the instance variable from the before block is visible each test]

(Beachten Sie, dass ich mit dieser Ausgabe keine Garantie für die Reihenfolge der Tests bekomme.)

Ein anderer Ansatz besteht darin, den vorhandenen before zu verwenden, aber Wrap-Code nur einmal in einem Klassenvariablenflag auszuführen. Beispiel:

class MySpec < MiniTest::Spec
  @@flag = nil
  before do
    unless @@flag
      # do stuff here that is to be done only once
      @@flag = true
    end
    # do stuff here that is to be done every time
  end
  # ... tests go here
end
5
matt

Eine einfache Möglichkeit, dies zu tun, besteht darin, eine überwachte Klassenmethode zu schreiben und diese dann in einer begin aufzurufen.

Ein Minitest :: Spec-Beispiel:

describe "my stuff" do
  def self.run_setup_code
    if @before_flag.nil?
      puts "Running the setup code"
      @before_flag = true
    end
  end

  before do
    self.class.run_setup_code
  end

  it "will only run the setup code once" do
    assert_equal 1, 1
  end

  it "really only ran it once" do
    assert_equal 1,1
  end
end

...bekommen 

Run options: --seed 11380

# Running:

Running the setup code
..

Finished in 0.001334s, 1499.2504 runs/s, 1499.2504 assertions/s.

2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
3
Bill Dueber

Das Schöne an Minitest ist seine Flexibilität. Ich habe einen benutzerdefinierten MiniTest Runner mit einem + before_suite + Callback verwendet. Etwas wie in diesem Beispiel - Ruby Minitest: Setup auf Suite- oder Klassenebene?

Und dann sagen Sie minitest, dass Sie den benutzerdefinierten Läufer verwenden sollen 

MiniTest::Unit.runner = MiniTestSuite::Unit.new
0
Laknath

Sie können den Code einfach außerhalb der Klasse platzieren.

Das mache ich, um ein Banner zu haben.

require 'Selenium-webdriver'
require 'minitest/test'
require 'minitest/autorun'

class InstanceTest < Minitest::Test

    def setup
    url     = ARGV.first
    @url    = self.validate_instance(url)
        @driver = Selenium::WebDriver.for :firefox
    end
0
morissette

Sie können auch einen After-Test-Callback hinzufügen, indem Sie Ihre test_helper.rb (oder spec_helper.rb) auf diese Weise aktualisieren

# test_helper.rb

class MyTest < Minitest::Unit
  after_tests do
    # ... after test code
  end
end
0
hoitomt