Есть ли альтернатива RSpec before(:suite)
и after(:suite)
в MiniTest?
Я подозреваю, что пользовательский тестовый бегун в порядке, однако я не могу себе представить, что это не общее требование, поэтому кто-то, возможно, реализовал его.: -)
Есть ли альтернатива RSpec before(:suite)
и after(:suite)
в MiniTest?
Я подозреваю, что пользовательский тестовый бегун в порядке, однако я не могу себе представить, что это не общее требование, поэтому кто-то, возможно, реализовал его.: -)
Доступны методы setup()
и teardown()
. В документации также перечислены before()
и after()
как доступные.
Изменить: вы хотите запустить что-то перед каждым тестом или до или после завершения всего пакета?
Как отмечено выше в ответе и комментариях Калей, MiniTest::Unit
содержит функцию after_tests
. Существует не before_tests
или эквивалент, но любой код в вашем файле minitest_helper.rb
должен быть запущен перед набором тестов, так что он будет выполнять офис такой функции.
Предостережение: все еще относительно новое в Ruby, и очень новое в Minitest, поэтому, если я ошибаюсь, пожалуйста, поправьте меня!: -)
Чтобы заставить это работать с текущей версией Minitest (5.0.6), вам нужно require 'minitest'
и использовать 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
Чтобы запустить код перед каждым тестом, используйте before
. Вы работаете здесь в контексте экземпляра, возможно, из класса, созданного неявно с помощью describe
, поэтому переменные экземпляра, установленные в before
, доступны в каждом тесте (например, внутри блока it
).
Чтобы запустить код перед всеми тестами, просто оберните тесты в классе, подклассом MiniTest::Spec
или любым другим; теперь перед самими испытаниями вы можете создать класс или модуль, задать переменные класса, вызвать метод класса и т.д., и все это будет доступно во всех тестах.
Пример:
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
Здесь вывод вместе с моими комментариями в фигурных скобках объясняет, что каждая строка вывода доказывает:
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]
(Обратите внимание: я не имею в виду, что этот вывод подразумевает какую-либо гарантию порядка, в котором будут выполняться тесты.)
Другой подход заключается в том, чтобы использовать существующий before
, но wrap-код для запуска только один раз в флагом переменной класса. Пример:
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
Один простой способ сделать это - написать метод защищенного класса, а затем вызвать его в begin
.
A Minitest:: Пример использования:
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
... получить
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
Хорошая вещь о минитете - это ее гибкость. Я использовал пользовательский Runner MiniTest с обратным вызовом + before_suite+. Что-то вроде этого примера - Ruby Minitest: настройка на уровне Suite или уровня?
И затем скажите minitest использовать пользовательский бегун
MiniTest::Unit.runner = MiniTestSuite::Unit.new
Вы также можете добавить обратный вызов после теста, обновив test_helper.rb(или spec_helper.rb), как этот
# test_helper.rb
class MyTest < Minitest::Unit
after_tests do
# ... after test code
end
end
Вы можете просто поместить код вне класса... Это то, что я делаю, чтобы иметь баннер.
#!/usr/bin/ruby
require 'selenium-webdriver'
require 'minitest/test'
require 'minitest/autorun'
sep = "***************************************************************************\n";
puts sep;
puts sep;
puts sep;
puts <<'EOF';
* _____ _ _______ _ *
* |_ _| | | |__ __| | | *
* | | _ __ ___| |_ __ _ _ __ ___ ___ | | ___ ___| |_ ___ _ __ *
* | | | '_ \/ __| __/ _` | '_ \ / __/ _ \ | |/ _ \/ __| __/ _ \ '__| *
* _| |_| | | \__ \ || (_| | | | | (_| __/ | | __/\__ \ || __/ | *
* |_____|_| |_|___/\__\__,_|_| |_|\___\___| |_|\___||___/\__\___|_| *
* *
* Matt Harris *
EOF
puts sep;
puts sep;
puts sep;
class InstanceTest < Minitest::Test
def setup
url = ARGV.first
@url = self.validate_instance(url)
@driver = Selenium::WebDriver.for :firefox
end