【问题标题】:RSpec before blocks not being called before contexts or describes在上下文或描述之前未调用块之前的 RSpec
【发布时间】:2017-12-14 13:21:37
【问题描述】:

给定以下代码:

RSpec.configure do |config|
  config.before(:all) { puts 'before all' }
  config.before(:suite) { puts 'before suite'}
  config.before(:context) { puts 'before context'}
  config.before(:each) { puts 'before each'}
end


RSpec.describe "SomeClass" do
  it 'matches some regex' do
    puts 'in first it block'
    expect('some string').to match(/.*/)
  end

  describe 'some group of tests' do
    puts 'in some group'

    context 'when some thing happens' do
      puts 'in context'
      it 'does something' do
        expect(true).to be_truthy
      end
    end
  end
end

我希望得到以下输出:

before suite
before all
before context
before each
in some group
in context
in first it block
.before each

但是我得到了:

in some group
in context
before suite
before all
before context
before each
in first it block
.before each

意味着contextdescribe 在我设置之前的任何配置之前运行。

我希望它是第一个输出,因为我读过 herehere

如果我绝对需要在测试文件中的任何其他内容之前运行代码,我该怎么办?包括(嵌套)上下文或描述?为什么它没有按我预期的方式工作?

注意:当我将 before :something 语句包含在最上面的 describe 范围内时,我会看到相同的行为。

(这个问题类似于this question,但不一样。我想知道为什么我的测试以这种方式运行,以及正确的 RSpec 约定是在绝对其他任何事情之前运行一段代码。)

版本信息:

RSpec 3.6
  - rspec-core 3.6.0
  - rspec-expectations 3.6.0
  - rspec-mocks 3.6.0
  - rspec-support 3.6.0

更新:

了解一些上下文可能会有所帮助:我正在使用 selenium-webdriver gem 编写 selenium 前端自动化测试。在任何和所有 it 块运行之前,我需要调用一个名为 navigate() 的函数(为了将我带到我正在为其编写测试的网页,这个函数需要大约 30 秒才能运行,因为它需要我在到达它需要去的地方之前通过两个登录页面)被调用并在其他任何事情发生之前完成。在我的 RSpec 文件中,我正在使用 before 块来尝试实现这一点,但是 rspec 在 before 块之前一直运行测试,并且失败了。

【问题讨论】:

    标签: ruby selenium-webdriver rspec tdd


    【解决方案1】:

    如果您将 puts "in some group"puts "in context" 放入 before(:all) 块中,则输出更接近您的预期。

    RSpec.configure do |config|
      config.before(:all) { puts 'before all' }
      config.before(:suite) { puts 'before suite'}
      config.before(:context) { puts 'before context'}
      config.before(:each) { puts 'before each'}
    end
    
    
    RSpec.describe "SomeClass" do
      it 'matches some regex' do
        puts 'in first it block'
        expect('some string').to match(/.*/)
      end
    
      describe 'some group of tests' do
        before(:all) { puts 'in some group' }
    
        context 'when some thing happens' do
          before(:all) { puts 'in context' }
    
          it 'does something' do
            expect(true).to be_truthy
          end
        end
      end
    end
    

    输出

    before suite
    before all
    before context
    before each
    in first it block
    .in some group
    in context
    before each
    .
    

    或者,如果你这样做了before(:each),你会得到

    before suite
    before all
    before context
    before each
    in first it block
    .before each
    in some group
    in context
    .
    

    当前输出的原因是您在解析文件时正在执行“在某个组中”和“在上下文中”的 puts 语句,根本不等待 RSpec。如果我们举一个不同的例子,没有 Rspec 混合,想象我们有一个文件,只有

    class SomeClass
      puts "in class"
    
      def do_something
        puts "doing something"
      end
    end
    

    如果我们将该文件加载到irb 会话中或使用ruby 在命令行上运行它,即使我们没有对该类进行任何操作,我们也会在控制台中看到“类中”输出。

    【讨论】:

    • 希望我解释得足够好,如果您仍然对任何事情感到困惑,请告诉我,我可以再试一次。
    • 我明白了。谢谢你的解释。
    • 所以,我明白为什么它的行为方式如此。我最初的问题是:“当我绝对需要在测试文件中的任何其他内容之前运行代码时,我该怎么办?包括(嵌套)上下文或描述?”我是否只需要在每个子上下文中都有一个 before :all/:each 块?我希望能够在它阻止的任何代码运行之前调用一段代码。
    猜你喜欢
    • 1970-01-01
    • 2015-09-14
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    相关资源
    最近更新 更多