minitest按顺序运行测试而不是并行运行?

时间:2013-08-21 16:25:05

标签: ruby minitest testunit

给出以下代码:

require 'minitest/autorun'
require '<some other stuff>

class test <  MiniTest::Unit::TestCase
  def setup
<setup some stuff>
  end
  def teardown
     <teardown some stuff>
  end

  def test1
    <test1 code>
  end
  def test2
    <test2 code>
  end
end

如何使minitest使用初始设置同时运行test1和test2?我问的原因是因为setup实例化了一个Selenium Webdriver实例并且花了一些时间来进行登录/设置,并且我想使用相同的实例(而不是每次都实例化一个新实例)来缩短它所花费的时间。测试功能。

4 个答案:

答案 0 :(得分:2)

我将尝试解决这个问题中有很多假设。首先,Minitest不会并行运行测试。默认情况下,Minitest以随机顺序运行测试。您可以通过覆盖测试类上的test_order方法来更改运行测试的顺序。

class MyTest <  MiniTest::Unit::TestCase
  def self.test_order
    :sorted # Or :alpha, they both behave the same
  end
end

但是,这不能让你达到我认为你所要求的。这样做只会使test1始终在test2之前运行。这仅在您编写了需要按顺序运行的测试时才有用。 (按字母顺序排列,不一定是在课堂上定义的顺序。)

测试中的实例变量不会在测试之间共享。这意味着,test1运行在MyTest的不同实例上,而不是运行test2。为了在测试之间共享对象,您需要在全局或类变量中设置它们。

class MyTest <  MiniTest::Unit::TestCase
  def setup
    @@this_thing ||= begin
      # Really expensive operation here
    end
  end
end

希望这有帮助。

答案 1 :(得分:0)

您可以通过创建具有前后测试方法的custom test runner type来执行您想要的操作。然后,您可以在所有测试之前创建selenium-webdriver实例,并在所有测试之后将其关闭。

以下是在所有测试之前启动浏览器并访问Google的示例。然后每个测试重新使用相同的浏览器。

require 'minitest/autorun'
require 'selenium-webdriver'

#Add before and after suite hooks using a custom runner
class MyMiniTest
  class Unit < MiniTest::Unit
    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 GoogleTest < MiniTest::Unit::TestCase
  def self.before_suite
    p "before all tests"
    @@driver = Selenium::WebDriver.for :firefox
    @@driver.navigate.to 'http://www.google.com'
  end

  def self.after_suite
    p "after all tests"
    @@driver.quit
  end

  def setup
    p 'setup before each test'
  end

  def teardown
    p 'teardown after each test'
  end

  def test1
    p 'test1'
    assert_equal(0, @@driver.find_elements(:xpath, '//div').length)
  end

  def test2
    p 'test2'
    assert_equal(0, @@driver.find_elements(:xpath, '//a').length)
  end
end

您可以看到输出运行事物的顺序:

"before all tests"
"setup before each test"
"test1"
"teardown after each test"
"setup before each test"
"test2"
"teardown after each test"
"after all tests"

请注意,您希望在测试中共享的变量需要是类变量(即以@@为前缀)。

答案 2 :(得分:0)

从测试的角度来看这是个坏主意,但是

您可以在一次测试中进行两项测试并重复使用设置

或者将其从设置和拆卸中取出并添加一个帮助方法来设置它(如果它还没有) 并从测试中调用它。运行的第一个测试接受命中,其他测试只重用它。

你应该做的是单元测试中的模拟或存根,并将真正的交易留给集成测试。

答案 3 :(得分:0)

您需要Minitest,还是可以更改为测试单元?

使用测试单元,您可以使用'Test :: Unit :: TestCase.startup and Test :: Unit :: TestCase.shutdown':

gem 'test-unit'#, '>= 2.1.1' #startup
require 'test/unit'
#~ require '<some other stuff>

class MyTest <  Test::Unit::TestCase
  def self.startup
    puts '<setup some stuff>'
  end
  def self.shutdown
     puts '<teardown some stuff>'
  end

  def test1
    puts '<test1 code>'
  end
  def test2
    puts '<test2 code>'
  end
end

另见can't get test unit startup to work in ruby 1.9.2