Настройте RSpec для тестирования гема (не Rails)

154

С добавленным генератором rspec-rails легко настроить RSpec для тестирования приложения Rails. Но как насчет добавления RSpec для тестирования гемов в разработке? Я не использую ювелирный или подобные инструменты. Я просто использовал Bundler ( bundle gem my_gem), чтобы настроить структуру для нового драгоценного камня и отредактировать * .gemspec вручную. Я также добавил s.add_development_dependency "rspec", ">= 2.0.0"в gemspec и сделал bundle install.

Есть ли хороший урок, что делать дальше, чтобы заставить работать RSpec?

Zardoz
источник
Думаю, мне нужно написать один :-) ... По крайней мере, есть два драгоценных камня, которые уже хорошо его интегрируют: акты-как-теги-на-полях и акты-акта_as_geocodable.
Зардоз

Ответы:

255

Я обновил этот ответ, чтобы соответствовать текущим лучшим практикам:

Bundler отлично поддерживает разработку гемов. Если вы создаете драгоценный камень, единственное, что вам нужно иметь в своем Gemfile, это следующее:

source "https://rubygems.org"
gemspec

Это говорит Bundler, что нужно искать в вашем файле gemspec зависимости при запуске bundle install.

Далее убедитесь, что RSpec является зависимостью разработки вашего гема. Отредактируйте 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. Когда вы устанавливаете свой собственный гем на свой компьютер, это заставит ваши спецификации использовать ваш текущий код, а не версию, которую вы установили отдельно.

Создайте спецификацию, например spec/foobar_spec.rb:

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

Необязательно: добавьте .rspecфайл для параметров по умолчанию и поместите его в корневой каталог вашего драгоценного камня:

--color
--format documentation

Наконец: запустите спецификации:

$ rspec spec/foobar_spec.rb
Iain
источник
75
Чтобы быть справедливым, вы должны вместо этого вызывать команду инициализации RSpec для генерации файлов скелета спецификации, а не вводить их вручную. Это обеспечит совместимость с используемой версией RSpec: rspec --init
Attila Györffy
12
rspec --initне было доступно, когда я написал это, но хороший момент!
2012 г.
На самом деле, я нашел лучший способ выполнить требования в помощнике спецификаций: требовать 'rubygems' требовать 'bundler / setup' Bundler.require (: default
,:
Как именно три строки кода @ mkon работают иначе, чем три строки кода iain?
Накилон
1
Для строк из @mkon потребуются все драгоценные камни в группах разработки и тестирования, а мой подход заключается в том, чтобы каждый драгоценный камень требовался вручную. Так как при создании драгоценных камней вам нужно требовать каждый драгоценный камень самостоятельно, я думаю, что это лучший / более ясный подход, хотя это может быть немного больше работы.
2016 г.
53

Решение Iain выше прекрасно работает!

Если вы также хотите Rakefile, это все, что вам нужно:

require 'rspec/core/rake_task'

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

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

Проверьте RDoc для RakeTask на наличие различных опций, которые вы можете при желании передать в определение задачи.

Мирко Фрелих
источник
26

Вы можете создать свой новый драгоценный камень с помощью rspec, запустив bundler gem --test=rspec my_gem. Никаких дополнительных настроек!

Я всегда об этом забываю. Это реализовано здесь: https://github.com/bundler/bundler/blob/33d2f67d56fe8bf00b0189c26125d27527ef1516/lib/bundler/cli/gem.rb#L36

StevenNunez
источник
1
Ухоженная! Тем не менее, я думаю, что имя вашего драгоценного камня должно быть указано с подчеркиванием вместо верблюжьего. В противном случае Bundler создает файлы с заглавными буквами (Bundler 1.7.4)
Malte
Бандлер пожаловался --test=rspec, но все равно спросил меня, хочу ли я использовать Rspec при запуске bundler gem my_gem.
Николас Маттиа
7

Вот дешевый и простой (хотя официально не рекомендованный) способ:

Сделайте dir в корне вашего драгоценного камня под названием spec, поместите туда свои спецификации. Возможно, вы уже установили rspec, но если вы этого не сделаете, просто сделайте a 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файл и поместите его в корневой каталог вашего драгоценного камня. Моя выглядит так:

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

Легко, быстро, аккуратно!

Мне это нравится, потому что вам вообще не нужно добавлять никаких зависимостей в ваш проект, и все это остается очень быстрым. bundle execнемного замедляет работу, что вам нужно сделать, чтобы убедиться, что вы используете одну и ту же версию rspec все время. Те 0,56 секунды, которые потребовались для запуска двух тестов, заняли 99% к тому времени, которое потребовалось моему компьютеру для загрузки rspec. Запуск сотен спецификаций должен быть чрезвычайно быстрым. Единственная проблема, с которой вы можете столкнуться, это то, о чем я знаю, если вы измените версии rspec, и новая версия не будет обратно совместима с какой-то функцией, которую вы использовали в своем тесте, вам, возможно, придется переписать некоторые тесты.

Это хорошо, если вы выполняете разовые спецификации или у вас есть веская причина НЕ включать rspec в ваш gemspec, однако это не очень хорошо для обеспечения совместного использования или обеспечения совместимости.

wulftone
источник
Есть ли способ не помещать AwesomeGem :: перед именами классов, когда вы ссылаетесь на объект тестирования? Или когда вы создаете новый тест, как в вашем примере.
Миша Слюсарев
1
Конечно, вы можете установить имя вашего класса равным чему-то более короткому, например, Thing = AwesomeGem::Awesomeили вы можете выполнить тест внутри модуля, напримерmodule AwesomeGem; it 'stuff' do; Awesome.new ... end; end
wulftone