Ruby Minitest: настройка уровня Suite или уровня?
Используя встроенную среду Ruby Minitest, есть ли способ запустить некоторый код один раз перед запуском всего пакета или даже один раз до запуска всего TestClass? Я вижу в ответе этот вопрос, что Test:: Unit:: after_tests может использоваться для запуска кода после выполнения всех тестов; есть ли аналогичный метод для запуска кода до запуска всех тестов?
Я хотел бы использовать эту функциональность для инициализации тестовой базы данных до запуска тестов и срывания их после их запуска.
Спасибо!
Ответы
Ответ 1
Это изменено из MiniTest docs (в разделе "Настраиваемые типы тестового запуска" ).
class Burger
def initialize
puts "YOU CREATED A BURGER"
end
def has_cheese?
true
end
def has_pickle?
false
end
end
gem 'minitest'
require 'minitest/unit'
MiniTest::Unit.autorun
class MyMiniTest
class Unit < MiniTest::Unit
def before_suites
# code to run before the first test
p "Before everything"
end
def after_suites
# code to run after the last test
p "After everything"
end
def _run_suites(suites, type)
begin
before_suites
super(suites, type)
ensure
after_suites
end
end
def _run_suite(suite, type)
begin
suite.before_suite if suite.respond_to?(:before_suite)
super(suite, type)
ensure
suite.after_suite if suite.respond_to?(:after_suite)
end
end
end
end
MiniTest::Unit.runner = MyMiniTest::Unit.new
class BurgerTest < MiniTest::Unit::TestCase
def self.before_suite
p "hi"
end
def self.after_suite
p "bye"
end
def setup
@burger = Burger.new
end
def test_has_cheese
assert_equal true, @burger.has_cheese?
end
def test_has_pickle
assert_equal false, @burger.has_pickle?
end
end
Обратите внимание, что я включил gem 'minitest'
для использования драгоценного камня вместо поставляемой в комплекте версии, у которой не было метода MiniTest::Unit.runner
. Здесь вывод.
Run options: --seed 49053
# Running tests:
"Before everything"
"hi"
YOU CREATED A BURGER
.YOU CREATED A BURGER
."bye"
"After everything"
Finished tests in 0.000662s, 3021.1480 tests/s, 3021.1480 assertions/s.
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
Таким образом, он дважды вызывает #setup
, но .before_suite
и .after_suite
только один раз, и это то, что вы ищете, я думаю.
Ответ 2
Альтернативный способ получить дескриптор в момент времени до и после всех тестов в пакете MiniTest должен состоять в том, чтобы поместить блоки if
в методы setup
и teardown
для управления тем, что эти блоки только вызываются один раз.
Таким образом, вы можете загрузить браузер и другие зависимости, такие как объекты страницы, только один раз в начале набора тестов, а затем закрыть браузер в конце, когда все тесты будут завершены.
Вот пример этого использования MiniTest 5.5.1 и Watir:
class CoolTests < Minitest::Test
@@setupComplete = false # tracks whether 1-time setup has completed, so we only instantiate a browser and dependent pages/modules one time per suite run
@@testsRun = 0 # tracks how many tests have run so we can close the browser when all tests complete
def setup # Minitest#setup runs before every #test method
@@testsRun+=1 # increment tetsRun indicating that a test has run
if ([email protected]@setupComplete) # we load the browser and necessary page objects here one-time if we haven't already
@@driver = Watir::Browser.new :chrome # instantiate new chrome browser
@@driver.window.maximize # maximize the browser window so we expect to test against Desktop UI/UX rather than Mobile UI/UX
@@setupComplete = true # setupComplete is now true as we've loaded up everything we need for our tests
end
end
def teardown # Minitest#teardown runs after every #test method
if (@@testsRun == CoolTests.runnable_methods.length) # if we've run all the tests in the suite we are finished and can then close the browser
@@driver.quit
end
end
#Tests
def test_one
p __method__
@@driver.goto('www.google.com')
assert_equal 'Google', @@driver.title, 'browser should be at google.com'
end
def test_two
p __method__
@@driver.goto('www.bing.com')
assert_equal 'Bing', @@driver.title, 'browser should be at bing.com'
end