web-dev-qa-db-fra.com

Avant/Après Suite avec Ruby MiniTest

Existe-t-il une alternative aux before(:suite) et after(:suite) de RSpec dans MiniTest?

Je soupçonne qu'un testeur personnalisé est en ordre, mais je ne peux pas imaginer que ce n'est pas une exigence courante, alors quelqu'un l'a probablement mis en œuvre dans. :-)

36
Nickolay Kolev

Il existe des méthodes setup() et teardown() disponibles. La documentation indique également que before() et after() sont disponibles.

Edit: Souhaitez-vous exécuter quelque chose avant chaque test ou avant ou après la fin de la suite?

25
Caley Woods

Comme indiqué ci-dessus dans la réponse et les commentaires de Caley, MiniTest::Unit contient la fonction after_tests. Il n’existe pas de before_tests ni d’équivalent, mais tout code de votre fichier minitest_helper.rb doit être exécuté avant la suite de tests afin que le bureau puisse remplir cette fonction.

Avertissement: toujours relativement nouveau chez Ruby et très nouveau chez Minitest, alors si je me trompe, s'il vous plaît corrigez-moi! :-)

21
Gert Sønderby

Pour que cela fonctionne avec la version actuelle de Minitest (5.0.6), vous devez require 'minitest' et utiliser Minitest.after_run { ... }.

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

Pour exécuter le code avant each test, utilisez before. Vous opérez ici dans le contexte d'une instance, éventuellement d'une classe générée implicitement par describe, de sorte que les variables d'instance définies dans before sont accessibles dans chaque test (par exemple, à l'intérieur d'un bloc it.).

Pour exécuter le code avant tout tests, enveloppez simplement les tests dans une classe, une sous-classe de MiniTest::Spec ou autre; Maintenant, avant les tests eux-mêmes, vous pouvez créer une classe ou un module, définir des variables de classe, appeler une méthode de classe, etc., et tout cela sera disponible dans tous les tests.

Exemple:

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

Voici le résultat, accompagné de mes commentaires entre accolades, expliquant ce que chaque ligne du résultat prouve:

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]

(Notez que je ne veux pas dire que cette sortie implique aucune garantie sur l'ordre dans lequel les tests seront exécutés.)

Une autre approche consiste à utiliser la variable before existante, mais le code intégré pour ne s'exécuter qu'une seule fois dans un indicateur de variable de classe. Exemple:

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

Une méthode simple consiste à écrire une méthode de classe gardée, puis à l'appeler dans une variable begin.

Un exemple Minitest :: Spec:

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

...obtenir 

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

La bonne chose à propos de minitest est sa flexibilité. J'utilise un MiniTest Runner personnalisé avec un rappel + before_suite +. Quelque chose comme dans cet exemple - Ruby Minitest: Configuration au niveau de la suite ou de la classe?

Et dites ensuite à minitest d'utiliser le coureur personnalisé 

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

Vous pouvez simplement placer le code en dehors de la classe.

C'est ce que je fais pour avoir une bannière.

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

Vous pouvez également ajouter un rappel après test en mettant à jour votre test_helper.rb (ou spec_helper.rb) comme ceci

# test_helper.rb

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