在rspec-rails中,如何创建自定义排序以便我可以根据自己的订单运行规范?

时间:2017-05-05 06:13:45

标签: ruby-on-rails ruby rspec rspec-rails

我是RSpec的新手,我想创建一个运行规格的自定义订单,我希望首先运行最重要的规格,然后是不太重要的规格,依此类推至最不重要的规格。 Rspec已经默认全局排序为:defined,但是我想重写它并创建我自己的自定义排序。我看过一份文件(“ https://www.relishapp.com/rspec/rspec-core/docs/configuration/overriding-global-ordering“)这个但是无法理解如何实现它。如果你们能发布一些带有解释的示例代码,将不胜感激。

这是我的spec_helper.rb文件: -

RSpec.configure do |config|
  #config.register_ordering :global do |examples|
  # model, other = examples.partition do |example|
  # example.metadata[:type] == :model
  # example.metadata[:type] == :controller
  # end
  #  model + other 
  # end
  config.register_ordering(:global) do |items|
    arr = [RSpec::ExampleGroups::User]
    items.sort_by &arr.method(:index)
  end

 =begin
  config.register_ordering(:global) do |items|
    items.sort_by do |group|
      case group.metadata[:type]
      when :feature then 3
      when :controller then 2
      when :model  then 1
      else 4
      end
    end
  end
 =end

config.expect_with :rspec do |expectations|
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

config.mock_with :rspec do |mocks|
  mocks.verify_partial_doubles = true
end

例如,这是我想在运行rspec时首先执行的spec文件: - 规格/模型/ user_spec_.rb

require 'rails_helper'
require  'spec_helper'

describe User do
  describe 'must fill in user name' do
    it { expect(User.new(:name => "")).not_to be_valid }
  end

  describe "must fill in email" do
    it { expect(User.new(:email => "")).not_to be_valid }
  end
  describe "when email address is already taken, do not allow duplication" do
    it "should not allow duplication" do
      @user = User.new(name: "Example User", email: "user12@example.com")
      # dup_user = @user.dup
      @user.save

      expect(@user.dup).not_to be_valid
    end
  end
end

当我尝试将这种类型的配置与数组一起使用时出现的错误是: -

        /spec/spec_helper.rb:29:in `sort_by': comparison of Fixnum with nil 
        failed (ArgumentError)
       from C:/RoR/rspec_demo/spec/spec_helper.rb:29:in `block (2 levels) in 
       <top (required)>'
       from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/lib/rspec/core/ordering.rb:151:in `block in register_ordering'
       from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/lib/rspec/core/ordering.rb:69:in `order'
       from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/lib/rspec/core/world.rb:34:in `ordered_example_groups'
       from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/lib/rspec/core/runner.rb:87:in `run'
       from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/lib/rspec/core/runner.rb:71:in `run'
       from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/lib/rspec/core/runner.rb:45:in `invoke'
       from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/exe/rspec:4:in `<top (required)>'
       from C:/Ruby23-x64/bin/rspec:22:in `load'
       from C:/Ruby23-x64/bin/rspec:22:in `<main>'

如果我使用以下代码覆盖: -

        config.register_ordering(:global) do |items|
        items = [RSpec::ExampleGroups::User]
        #items.sort_by &arr.method(:index)
        end

然后spec文件运行,测试没有通过,返回以下错误: -

      1) User must fill in user name
      Failure/Error: super

       NoMethodError:
       undefined method `inspect_output' for 
       RSpec::ExampleGroups::User:Class
       # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
       3.5.4/lib/rspec/core/example_group.rb:732:in `method_missing'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/example_group.rb:625:in `block in run_examples'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/example_group.rb:623:in `map'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/example_group.rb:623:in `run_examples'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/example_group.rb:589:in `run'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:113:in `block (3 levels) in run_specs'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:113:in `map'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:113:in `block (2 levels) in run_specs'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/configuration.rb:1835:in `with_suite_hooks'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:112:in `block in run_specs'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/reporter.rb:77:in `report'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:111:in `run_specs'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:87:in `run'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:71:in `run'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/lib/rspec/core/runner.rb:45:in `invoke'
      # C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/rspec-core-
      3.5.4/exe/rspec:4:in `<top (required)>'
      # C:/Ruby23-x64/bin/rspec:22:in `load'
      # C:/Ruby23-x64/bin/rspec:22:in `<main>'
      #
      #   Showing full backtrace because every line was filtered out.
      #   See docs for RSpec::Configuration#backtrace_exclusion_patterns and
      #   RSpec::Configuration#backtrace_inclusion_patterns for more 
          information.
       Failed examples:

        rspec ./spec/models/user_spec.rb:9 # User must fill in user name

我还阅读了关于自定义排序的讨论(“https://github.com/rspec/rspec-core/issues/547”),但无法理解如何实现它。

如何实现以下目标?或者甚至如果我必须首先执行此文件中的单个示例,首先在运行RSpec时首先执行“不应允许复制”。我怎样才能成功呢?

1 个答案:

答案 0 :(得分:0)

要定义自定义订单,您只需在配置中设置自己的规则。由于您要专门定义重要和非重要,您需要使用所需的顺序创建自己的列表,然后使用它对实际文本列表进行排序。以下是您在spec/spec_helper.rb中添加的粗略工作示例:

  config.register_ordering(:global) do |items|
    arr = [RSpec::ExampleGroups::ImportantText, RSpec::ExampleGroups::NotImportant]
    items.sort_by &arr.method(:index)
  end