【问题标题】:RSpec: Always execute before(:all) in begin/rescueRSpec:总是在开始/救援中执行 before(:all)
【发布时间】:2023-04-08 18:49:01
【问题描述】:

我正在使用 Watir-Webdriver 和 RSpec 编写 Selenium 测试,它们在刚开始开发时可能会有点参差不齐。我遇到了一种情况,我想在之前的 UI 上创建一些东西:all,但是它可以抛出异常(基于时间或加载不良)。发生这种情况时,我想截屏。

这是我所拥有的:

 RSpec.configure do |config|
   config.before(:all) do |group| #ExampleGroup
     @browser = Watir::Browser.new $BROWSER

     begin
       yield #Fails on yield, there is no block
     rescue StandardError => e
       Utilities.create_screenshot(@browser)
       raise(e)
     end
   end
 end

我运行它并得到一个错误:

LocalJumpError: 没有给出块(产量)

我认为 yielding 会起作用的原因是 RSpec 对 before 的定义:

def before(*args, &block)
  hooks.register :append, :before, *args, &block
end

如何将我在 before :all 中的代码封装在开始/救援块中,而不必在每个套件上都这样做?

提前致谢。

【问题讨论】:

    标签: ruby selenium rspec watir-webdriver


    【解决方案1】:

    您在 before 钩子中编写的代码是您在 RSpec::Hooks#before 中引用的 &block。钩子让出你的代码,然后在让出完成后运行你的测试。

    至于如何使这项工作,我认为应该这样做:

    RSpec.configure do |config|
      # ensures tests are run in order
      config.order = 'defined'
    
      # initiates Watir::Browser before all tests
      config.before(:all) do
        @browser = Watir::Browser.new $BROWSER
      end
    
      # executes Utilities.create_screenshot if an exception is raised by RSpec 
      # and the test is tagged with the :first metadata
      config.around(:each) do |example|
        example.run
        Utilities.create_screenshot(@browser) if example.exception && example.metadata[:first]
      end
    end
    

    此配置需要使用元数据标记第一个测试:

    describe Thing, :first do
      it "does something" do
        # ...
      end
    end
    

    这样,您只会在运行开始时为失败的测试截屏,而不是在每次失败的测试后截屏。如果您不想弄乱元数据(或者希望您的测试以随机顺序运行),您可以这样做:

    RSpec.configure do |config|
      # initiates Watir::Browser before all tests
      config.before(:all) do
        @test_count = 0
        @browser = Watir::Browser.new $BROWSER
      end
    
      # executes Utilities.create_screenshot if an exception is raised by RSpec 
      # and the test is the first to run
      config.around(:each) do |example|
        @test_count += 1
        example.run
        Utilities.create_screenshot(@browser) if example.exception && @test_count == 1
      end
    end
    

    【讨论】:

    • 已编辑。当我的意思是example.metadata[:first]时,我写了example[:first]
    • 我需要在 :all 之前有截图,而不是在 :each 之前。我在之前有导航:all 故意的。它需要在那里消除一些重复性。我可以将 example.exception 用于特定测试,但在 :all 之前给出的是 example_group 而不是 example。
    • 好的,所以您已经有了需要在所有测试之前运行一次的设置代码。如果出现故障,您是否需要在第一次测试后截取屏幕截图,或者如果出现故障,您需要在所有测试后截取屏幕截图吗?还是我完全错过了其他东西?
    • 我已经能够使用 example.exception 在测试期间拍摄快照。我需要在 before :all 阶段拍摄快照。这是我登录并导航到我正在测试的页面的地方。目前,其中调用的方法被包装在一个有点笨重的大开始/救援块中。如果我基本上可以描述上面的内容,我认为这都是不必要的代码。
    【解决方案2】:

    这对我有用。而不是before :all钩子中的begin/rescue

    config.after :each do
      example_exceptions = []
      RSpec.world.example_groups.each do |example_group|
        example_group.examples.each do |example|
          example_exceptions << !example.exception.nil?
          end
        end
      has_exceptions = example_exceptions.any? {|exception| exception}
      #Handle if anything has exceptions
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-13
      相关资源
      最近更新 更多