Antes/después de la suite cuando usa Ruby Minitest
-
28-10-2019 - |
Pregunta
¿Hay una alternativa a RSPEC before(:suite)
y after(:suite)
en minitest?
Sospecho que un corredor de prueba personalizado está en orden, sin embargo, no puedo imaginar que no sea un requisito común, por lo que probablemente alguien haya implementado. :-)
Solución
Existen setup()
y teardown()
Métodos disponibles. La documentación también enumera before()
y after()
como estar disponible.
Editar: ¿Está buscando ejecutar algo antes de cada prueba o antes o después de que se termine toda la suite?
Otros consejos
Como se señaló anteriormente en la respuesta y los comentarios de Caley, MiniTest::Unit
contiene la función after_tests
. No hay before_tests
o equivalente, pero cualquier código en su minitest_helper.rb
El archivo debe ejecutarse antes del conjunto de pruebas, por lo que eso hará la oficina de dicha función.
Advertencia: todavía relativamente nuevo en Ruby, y muy nuevo en Minitest, así que si me equivoco, por favor ¡corrígeme! :-)
Para que esto funcione con la versión actual de Minitest (5.0.6), necesita require 'minitest'
y use Minitest.after_run { ... }
.
warn "MiniTest::Unit.after_tests is now Minitest.after_run. ..."
https://github.com/seattlerb/minitest/blob/master/lib/minitest.rb https://github.com/seattlerb/minitest/blob/master/lib/minitest/unit.rb
Para ejecutar código antes cada prueba, usa before
. Estás operando aquí en el contexto de una instancia, posiblemente de una clase generada implícitamente por describe
, entonces variables de instancia establecidas en before
son accesibles en cada prueba (por ejemplo, dentro de un it
bloquear).
Para ejecutar código antes todos pruebas, simplemente envuelva las pruebas en una clase, una subclase de MiniTest::Spec
o lo que sea; Ahora, antes de las pruebas en sí mismas, puede crear una clase o módulo, establecer variables de clase, llamar a un método de clase, etc., y todo eso estará disponible en todas las pruebas.
Ejemplo:
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
Aquí está la salida, junto con mis comentarios en aparatos, explicando lo que prueba cada línea de la salida:
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]
(Tenga en cuenta que no quiero decir que esta salida implique ninguna garantía sobre el orden en que se ejecutarán las pruebas).
Otro enfoque es usar el existente before
Pero envuelva el código para ejecutar solo una vez en un indicador de variable de clase. Ejemplo:
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
Una forma simple de hacer esto es escribir un método de clase vigilado, y luego llamarlo en un begin
.
A Minitest :: Ejemplo de especificación:
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
...Llegar
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
Lo bueno de Minitest es su flexibilidad. He estado usando un corredor Minitest personalizado con A + antes de Callback. Algo como en este ejemplo - Ruby Minitest: ¿Configuración de nivel de suite o clase?
Y luego dígale a Minitest que use el corredor personalizado
MiniTest::Unit.runner = MiniTestSuite::Unit.new
También puede agregar una devolución de llamada posterior a la prueba actualizando su test_helper.rb (o spec_helper.rb) como este
# test_helper.rb
class MyTest < Minitest::Unit
after_tests do
# ... after test code
end
end
Puede colocar el código fuera de la clase.
Esto es lo que hago para tener una pancarta.
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