问题 Ruby Minitest:套件级或类级设置?


使用内置的Ruby Minitest框架,有没有办法在整个套件运行之前运行一些代码,甚至在整个TestClass运行之前运行一次?我在答案中看到了 这个问题 在运行所有测试后,Test :: Unit :: after_tests可用于运行代码;是否有类似的方法在所有测试运行之前运行代码?

我希望在测试运行之前使用此功能初始化测试数据库,并在它们全部运行后将其拆除。

谢谢!


7377
2017-07-20 02:53


起源



答案:


这是从MiniTest修改的 文档 (在可定制的测试运行器类型下)。

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' 使用gem而不是没有的捆绑版本 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 只有一次,这是你想要的,我想。


16
2017-07-20 15:49



D'哦!在文档中完全错过了。谢谢! - Dan Fuchs
不幸的是,版本5的跑步者被删除了...我想它解释了为什么minitest有这么多的叉子,你只需要在它工作之前修补它...


答案:


这是从MiniTest修改的 文档 (在可定制的测试运行器类型下)。

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' 使用gem而不是没有的捆绑版本 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 只有一次,这是你想要的,我想。


16
2017-07-20 15:49



D'哦!在文档中完全错过了。谢谢! - Dan Fuchs
不幸的是,版本5的跑步者被删除了...我想它解释了为什么minitest有这么多的叉子,你只需要在它工作之前修补它...


在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 (!@@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

0
2017-07-10 18:47