重用最小的集成测试

yi0zb3m4  于 2022-10-15  发布在  Ruby
关注(0)|答案(3)|浏览(195)

我在Rails中有三个页面,它们都显示相同的标题,因此需要完全相同的集成测试。
与其重复我自己并编写看起来几乎完全相同的单独测试,这里最好的方法是什么?我尝试将共享Assert放到一个模块中,但没有成功地将其加载到每个测试场景中。
联合国开发计划署:

class IntegrationTest
  describe "page one" do

    before { visit page_one_path }

    it "should have a home page link" do
      page.find_link "Home"
    end
  end

  describe "page two" do

    before { visit page_two_path }

    it "should have a home page link" do
      page.find_link "Home"
    end
  end

  describe "page three" do

    before { visit page_three_path }

    it "should have a home page link" do
      page.find_link "Home"
    end
  end
end

试图把它弄干的尝试失败了。
模块:

/lib/tests/shared_test.rb

module SharedTest

  def test_header
    it "should have a home page link" do
      page.find_link "Home"
    end
  end
end

测试:

class IntegrationTest
  include SharedTest

  describe "page one" do
    before { visit page_one_path }
    test_header
  end

  describe "page two" do
    before { visit page_two_path }
    test_header        
  end

  describe "page three" do
    before { visit page_three_path }
    test_header
  end
end

我还没有完全弄清楚如何编写模块,所以这不起作用也就不足为奇了。有谁能给我指个方向吗?

j13ufse2

j13ufse21#

在使用Minitest的规范DSL时,在不同的describe块之间共享测试的方法是将模块包括在您希望在其中运行测试的每个describe块中。

module SharedTest
  def test_header
    assert_link "Home"
  end
end

class IntegrationTest < ActiveDispatch::IntegrationTest
  describe "page one" do
    include SharedTest
    before { visit page_one_path }
  end

  describe "page two" do
    include SharedTest
    before { visit page_two_path }
  end

  describe "page three" do
    include SharedTest
    before { visit page_three_path }
  end
end

Minitest的测试API与Minitest Spec DSL的不同之处之一是它们在被继承时的行为方式。请考虑以下事项:

class PageOneTest < ActiveDispatch::IntegrationTest
  def setup
    visit page_one_path
  end

  def test_header
    assert_link "Home"
  end
end

class PageTwoTest < PageOneTest
  def setup
    visit page_two_path
  end
end

class PageThreeTest < PageOneTest
  def setup
    visit page_three_path
  end
end

PageTwoTest和PageThreeTest测试类继承自PageOneTest,因此它们都有test_header方法。Minitest将进行所有三项测试。但是,当使用规范DSL实现时,不会继承test_header方法。

class PageOneTest < ActiveDispatch::IntegrationTest
  def setup
    visit page_one_path
  end

  def test_header
    assert_link "Home"
  end

  describe "page two" do
    before { visit page_two_path }
  end

  describe "page three" do
    before { visit page_three_path }
  end
end

在这种情况下,只运行一个测试。由describe "page two"创建的测试类将继承自PageOneTest,但将删除所有测试方法。为什么?因为Minitest的规范DSL是基于RSpec的,这就是RSpec的工作方式。Minitest不遗余力地破坏在使用SPEC DSL时继承的测试方法。因此,在使用SPEC DSL时共享测试的唯一方法是将模块包括在您希望它们所在的每个describe块中。所有其他非测试方法,包括beforeafter挂钩以及let访问器,都将被继承

mbyulnm0

mbyulnm02#

这里有一种在使用MiniTest的规范DSL时重用测试的干净方法--在一个函数中定义测试,并在您想要包含测试的地方调用该函数。
示例:

def include_shared_header_tests
  it "should be longer than 5 characters" do
    assert subject.length > 5
  end

  it "should have at least one capital letter" do
    assert /[A-Z]/ =~ subject
  end
end

# This block will pass

describe "A good header" end
  subject { "I'm a great header!" }

  include_shared_header_tests
end

# This block will fail

describe "A bad header" end
  subject { "bad" }

  include_shared_header_tests
end
m2xkgtsf

m2xkgtsf3#

如果要在模块中继续使用等级库样式,可以使用Module::included挂钩。

module SharedTests
  def self.included spec
    spec.class_eval do

      # Your shared code here...

      let(:foo) { 'foo' }

      describe '#foo' do
        it { foo.must_equal 'foo' }
      end

    end
  end
end

class MyTest < Minitest::Spec
  include SharedTests
end

class MyOtherTest < Minitest::Spec
  include SharedTests
end

# It also works in nested describe blocks.

class YetAnotherTest < Minitest::Spec
  describe 'something' do
    describe 'when it acts some way' do
      include SharedTests
    end
  end
end

重复性测试的另一种方法是迭代。

class IntegrationTest < Minitest::Spec
  {
    'page one'   => :page_one_path,
    'page two'   => :page_two_path,
    'page three' => :page_three_path,
  }.each do |title, path|
    describe title do
      before { visit send(path) }

      it 'should have a home page link' do
        page.find_link 'Home'
      end
    end
  end
end

相关问题