【问题标题】:Set up RSpec to test a gem (not Rails)设置 RSpec 以测试 gem(不是 Rails)
【发布时间】:2011-05-22 20:19:04
【问题描述】:

使用添加的 rspec-rails 生成器来设置 RSpec 以测试 Rails 应用程序非常容易。但是添加 RSpec 来测试开发中的 gem 怎么样? 我没有使用珠宝商或此类工具。我刚刚使用 Bundler (bundle gem my_gem) 来设置新 gem 的结构并手动编辑 *.gemspec。 我还在 gemspec 中添加了s.add_development_dependency "rspec", ">= 2.0.0" 并做了一个bundle install

是否有一些很好的教程来让 RSpec 正常工作?

【问题讨论】:

  • 我想我必须写一个:-) ...至少有两个 gem 已经很好地集成了它:acts-as-taggable-on 和acts_as_geocodable。

标签: testing rspec rubygems rspec2


【解决方案1】:

我已更新此答案以符合当前的最佳做法:

Bundler 完美支持 gem 开发。如果您正在创建一个 gem,那么您在 Gemfile 中需要的唯一内容如下:

source "https://rubygems.org"
gemspec

这告诉 Bundler 在您运行 bundle install 时查看您的 gemspec 文件中的依赖项。

接下来,确保 RSpec 是您的 gem 的开发依赖项。编辑 gemspec,使其显示为:

spec.add_development_dependency "rspec"

接下来,创建spec/spec_helper.rb 并添加如下内容:

require 'bundler/setup'
Bundler.setup

require 'your_gem_name' # and any other gems you need

RSpec.configure do |config|
  # some (optional) config here
end

前两行告诉 Bundler 只加载 gemspec 中的 gem。当您在自己的机器上安装自己的 gem 时,这将强制您的规范使用您当前的代码,而不是您单独安装的版本。

创建规范,例如spec/foobar_spec.rb

require 'spec_helper'
describe Foobar do
  pending "write it"
end

可选:为默认选项添加一个.rspec 文件并将其放在gem 的根路径中:

--color
--format documentation

最后:运行规范:

$ rspec spec/foobar_spec.rb

【讨论】:

  • 公平地说,您应该调用 RSpec 的 init 命令来生成规范框架文件,而不是手动输入它们。这将确保与您正在使用的 RSpec 版本兼容:@987654331 @
  • rspec --init 在我写这篇文章时不可用,但很好!
  • 实际上我发现在规范助手中执行需求的最佳方法是:require 'rubygems' require 'bundler/setup' Bundler.require(:default, :development)
  • @mkon 的三行代码与 iain 的三行代码有何不同?
  • @mkon 的行将需要开发和测试组中的所有 gem,而我的方法是手动需要每个 gem。由于您在制作宝石时需要自己要求每颗宝石,我认为这是更好/更清晰的方法,即使它可能需要更多工作。
【解决方案2】:

Iain 的上述解决方案效果很好!

如果您还想要一个 Rakefile,这就是您所需要的:

require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

# If you want to make this the default task
task default: :spec

查看RakeTask 的 RDoc 以了解您可以选择传递到任务定义中的各种选项。

【讨论】:

    【解决方案3】:

    您可以通过运行bundler gem --test=rspec my_gem 使用rspec 生成新的gem。无需额外设置!

    我总是忘记这一点。它在这里实现:https://github.com/bundler/bundler/blob/33d2f67d56fe8bf00b0189c26125d27527ef1516/lib/bundler/cli/gem.rb#L36

    【讨论】:

    • 整洁!但是,我认为您的 gem 名称应该用下划线而不是驼峰式大小写来指定。否则 Bundler 会创建带有大写字母的文件 (Bundler 1.7.4)
    • Bundler 抱怨了--test=rspec,但是当我运行bundler gem my_gem 时它仍然问我是否想使用Rspec。
    【解决方案4】:

    这是一种便宜又简单(虽然不是官方推荐)的方法:

    在您的 gem 的根目录中创建一个名为 spec 的目录,将您的规格放在那里。您可能已经安装了 rspec,但如果您没有安装,只需执行 gem install rspec 并忘记 Gemfiles 和 bundler。

    接下来,您将制定一个规范,您需要告诉它您的应用在哪里,您的文件在哪里,并包含您要测试的文件(以及它所具有的任何依赖项):

    # spec/awesome_gem/awesome.rb
    APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
    $: << File.join(APP_ROOT, 'lib/awesome_gem') # so rspec knows where your file could be
    require 'some_file_in_the_above_dir' # this loads the class you want to test
    
    describe AwesomeGem::Awesome do
      before do
        @dog = AwesomeGem::Awesome.new(name: 'woofer!')
      end
      it 'should have a name' do
        @dog.name.should eq 'woofer!'
      end
      context '#lick_things' do
        it 'should return the dog\'s name in a string' do
          @dog.lick_things.should include 'woofer!:'
        end
      end
    end
    

    打开终端并运行 rspec:

    ~/awesome_gem $ rspec
    ..
    
    Finished in 0.56 seconds
    2 examples, 0 failures
    

    如果您想要一些.rspec 选项的爱,请创建一个.rspec 文件并将其放在您的gem 的根路径中。我的看起来像这样:

    # .rspec
    --format documentation --color --debug --fail-fast
    

    简单、快速、整洁!

    我喜欢这样,因为您根本不需要向项目添加任何依赖项,而且整个过程仍然非常快。 bundle exec 使事情变慢了一点,这是您必须做的,以确保您始终使用相同版本的 rspec。运行两个测试所需的 0.56 秒在我的计算机加载 rspec 时占用了 99%。运行数百个规范应该非常快。我知道您可能遇到的唯一问题是,如果您更改 rspec 的版本并且新版本与您在测试中使用的某些功能不向后兼容,您可能需要重新编写一些测试。

    如果您正在做一次性规范或有充分的理由不在您的 gemspec 中包含 rspec,这很好,但它对于启用共享或强制兼容性不是很好。

    【讨论】:

    • 有没有办法在你引用测试对象时不把 AwesomeGem:: 放在类名之前?或者当您像示例中那样创建新测试时。
    • 当然,您可以将类名设置为更短的名称,例如Thing = AwesomeGem::Awesome,或者您可以在模块内进行测试,例如module AwesomeGem; it 'stuff' do; Awesome.new ... end; end
    猜你喜欢
    • 2019-08-12
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2018-03-10
    • 2012-07-28
    • 2014-05-18
    相关资源
    最近更新 更多