使用 Ruby MiniTest 之前/之后套件

发布于 2024-11-05 10:10:44 字数 151 浏览 1 评论 0原文

MiniTest 中是否有 RSpec 的 before(:suite)after(:suite) 的替代方案?

我怀疑自定义测试运行程序是合适的,但是我无法想象这不是一个常见的要求,所以有人可能已经实现了。:-)

Is there an alternative to RSpec's before(:suite) and after(:suite) in MiniTest?

I suspect that a custom test runner is in order, however I cannot imagine it is not a common requirement, so somebody has probably implemented in. :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

兔姬 2024-11-12 10:10:45

minitest 的优点在于它的灵活性。我一直在使用带有 +before_suite+ 回调的自定义 MiniTest Runner。类似于此示例 - Ruby Minitest:Suite- 或 Class-级别设置?

然后告诉 minitest 使用自定义运行器

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

Nice thing about minitest is its flexibility. I've been using a custom MiniTest Runner with a +before_suite+ callback. Something like in this example - Ruby Minitest: Suite- or Class- level setup?

And then tell minitest to use the custom runner

MiniTest::Unit.runner = MiniTestSuite::Unit.new
左秋 2024-11-12 10:10:45

您还可以通过更新 test_helper.rb (或 spec_helper.rb)来添加测试后回调,如下所示

# test_helper.rb

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

You can also add an after test callback by updating your test_helper.rb (or spec_helper.rb) like this

# test_helper.rb

class MyTest < Minitest::Unit
  after_tests do
    # ... after test code
  end
end
浅暮の光 2024-11-12 10:10:44

setup()teardown() 方法可用。该文档还列出了可用的 before()after()

编辑:您是否希望在每次测试之前或整个套件完成之前或之后运行一些东西?

There are setup() and teardown() methods available. The documentation also lists before() and after() as being available.

Edit: Are you looking to run something before each test or before or after the whole suite is finished?

や三分注定 2024-11-12 10:10:44

正如上面 Caley 的回答和评论中所述,MiniTest::Unit 包含函数 after_tests。没有 before_tests 或等效项,但 minitest_helper.rb 文件中的任何代码都应在测试套件之前运行,以便执行此类功能。

警告:在 Ruby 中仍然相对较新,在 Minitest 中也很新,所以如果我错了,纠正我! :-)

As noted above in Caley's answer and comments, MiniTest::Unit contains the function after_tests. There is no before_tests or equivalent, but any code in your minitest_helper.rb file should be run before the test suite, so that will do the office of such a function.

Caveat: Still relatively new at Ruby, and very new at Minitest, so if I'm wrong, please correct me! :-)

橘虞初梦 2024-11-12 10:10:44

要使其适用于当前版本的 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

To get this to work with the current version of Minitest (5.0.6) you need to require 'minitest' and 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

留一抹残留的笑 2024-11-12 10:10:44

要在每个测试之前运行代码,请使用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,但将代码包装在类变量标志中仅运行一次。例子:

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

To run code before each test, use before. You're operating here in the context of an instance, possibly of a class generated implicitly by describe, so instance variables set in before are accessible in each test (e.g. inside an it block).

To run code before all tests, simply wrap the tests in a class, a subclass of MiniTest::Spec or whatever; now, before the tests themselves, you can create a class or module, set class variables, call a class method, etc., and all of that will be available in all tests.

Example:

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

Here's the output, along with my comments in braces explaining what each line of the output proves:

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]

(Note that I do not mean this output to imply any guarantee about the order in which tests will run.)

Another approach is to use the existing before but wrap code to run only once in a class variable flag. Example:

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
贪恋 2024-11-12 10:10:44

一种简单的方法是编写一个受保护的类方法,然后在 begin 中调用该方法。

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

...得到

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

One simple way to do this is to write a guarded class method, and then call that in a begin.

A Minitest::Spec example:

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

...to get

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
未蓝澄海的烟 2024-11-12 10:10:44

您可以将代码放在类之外。

这就是我为了拥有一面横幅所做的事情。

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

You can just place the code outside of the class.

This is what I do to have a banner.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文