Запустите ruby отладчик, если тест rspec не пройден
Часто, когда тест не проходит, я провожу довольно много времени, пытаясь выяснить причину его провала. Было бы полезно, если бы RSpec мог запустить отладчик Ruby при неудачном завершении теста, чтобы я мог сразу же проверить локальные переменные, чтобы выяснить причину.
Обходной путь, который я сейчас использую, выглядит примерно так:
# withing some test
debugger unless some_variable.nil?
expect(some_variable).to be_nil
Однако такой подход обременителен, потому что сначала я подожду, пока тест не пройдёт, затем добавлю строку отладчика, исправлю проблему и затем должен удалить строку отладчика, тогда как я хочу, чтобы она работала больше как gdb
который имеет возможность срабатывать при возникновении исключения, не требуя приправить вашу базу кода debugger
заявления.
Изменить: я пробовал Плимут. Это не сработало достаточно надежно для меня. Также история развития, кажется, указывает на то, что это не очень хорошо поддерживаемый гем, поэтому я бы предпочел не полагаться на него.
Обновление: я попробовал pry-rescue
и найти его аккуратным. Тем не менее, я часто использую Zeus, и мне было интересно, есть ли способ заставить его работать с pry-rescue
,
7 ответов
Используйте спасение, это духовный преемник Плимута:
Из файла Readme:
Если вы используете RSpec или respec, вы можете открыть сеанс pry при каждом сбое теста, используя rescue rspec или rescue respec:
$ rescue rspec
From: /home/conrad/0/ruby/pry-rescue/examples/example_spec.rb @ line 9 :
6:
7: describe "Float" do
8: it "should be able to add" do
=> 9: (0.1 + 0.2).should == 0.3
10: end
11: end
RSpec::Expectations::ExpectationNotMetError: expected: 0.3
got: 0.30000000000000004 (using ==)
[1] pry(main)>
Мне нравится решение @jon-rowe (дополнительные гемы не нужны) с небольшим редактированием: я действительно не забочусь о других ошибках так, как RSpec::Expectations::ExpectationNotMetError
,
config.around(:each) do |example|
example.run.tap do |result|
debugger if result.is_a?(RSpec::Expectations::ExpectationNotMetError)
end
end
Вы не получите доступ к локальным переменным (легко) без debugger
находясь в области блока, однако RSpec
предоставляет вам вокруг хуков, которые позволят вам сделать это:
config.around(:each) do |example|
result = example.run
debugger if result.is_a?(Exception)
puts "Debugging enabled"
end
Затем у вас есть доступ к @ivars
а также subject
/ let(:var)
содержание на данный момент.
Из документации Rspec:
RSpec пытается предоставить полезные сообщения об ошибках, но для случаев, когда вам нужна более конкретная информация, вы можете определить собственное сообщение прямо в примере. Это работает для любого сопоставителя, кроме сопоставления операторов.
Что я делаю, так это вызываю любопытство в этом сообщении. См. Пример:
describe "failing" do
context "test" do
it "should start pry" do
a = 3
b = 1
expect(a).to be == b, "#{require 'pry';binding.pry}"
end
end
end
Удачной отладки!
Вам нужно перехватить исключение ExpectationNotMatched во время его создания. Включите в свои помощники следующий код, и RSpec остановится при создании исключения. Это будет несколько уровней глубоко внутри совпадений, поэтому в отладчике скажите "где", затем "до 5" или "до 6", и вы будете внутри instance_exec вашего блока. Отладчик некорректно отображает код в используемой версии, но вы можете еще раз "подняться" и перейти к коду, работающему в том же контексте, где оценивается ваш тест, так что вы можете проверить переменные экземпляра (но не локальные переменные, кажется).
require 'debugger'
require 'rspec'
Debugger.start
class RSpec::Expectations::ExpectationNotMetError
alias_method :firstaid_initialize, :initialize
def initialize *args, &b
send(:firstaid_initialize, *args, &b)
puts "Stopped due to #{self.class}: #{message} at "+caller*"\n\t"
debugger
true # Exception thrown
end
end
describe "RSpec" do
it "should load use exceptions on should failure" do
@foo = :bar # An instance variable I can examine
1.should == 2
end
end
Для этого вы можете использовать камень Плимута https://github.com/banister/plymouth. Это использует pry, хотя (лучшая) альтернатива irb.
НТН
Вы можете попробовать время молотка. Он остановится и предложит вам принять участие в интерактивном сеансе отладки при возникновении исключения.