2013-04-30 17 views
16

Spesso, quando un test fallisce, passo un bel po 'cercando di capire cosa ha causato il fallimento. Sarebbe utile se RSpec potesse avviare un debugger di Ruby quando il test fallisce, in modo da poter controllare immediatamente le variabili locali per approfondire la causa.Avvia il debugger ruby ​​se fallisce il test rspec

Il work-around che sto utilizzando in questo momento sembra qualcosa di simile:

# withing some test 
debugger unless some_variable.nil? 
expect(some_variable).to be_nil 

Tuttavia, questo approccio è ingombrante, perché ho attendere per un fallimento del test, quindi aggiungere la riga debugger, fissare il problema e quindi rimuovere la riga del debugger, mentre voglio che funzioni più come gdb che ha la possibilità di avviare quando si verifica un'eccezione, senza che sia necessario aggiungere il codice base alle istruzioni debugger.

Modifica: Ho provato Plymouth. Non ha funzionato abbastanza in modo affidabile per me. Anche la storia dello sviluppo sembra indicare che non è una gemma molto ben supportata, quindi preferirei non fare affidamento su di essa.

Aggiornamento: Ho provato pry-rescue e lo trovo pulito. Tuttavia, io uso molto lo zeus e mi chiedevo se c'era un modo per farlo funzionare con pry-rescue.

risposta

20

Usa pry-rescue, è il successore spirituale a Plymouth:

Dal Leggimi:

Se stai usando RSpec o respec, è possibile aprire una sessione di leva su ogni fallimento del test utilizzando rspec salvataggio o di soccorso 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)> 
+0

grazie - darò uno scatto. – Vighnesh

+3

C'è un modo per farlo funzionare con 'zeus'? – Vighnesh

+1

Ho appena provato con la nuova versione di zeus e di pry-rescue, non funziona – 23tux

0

È possibile utilizzare plymouth gemma https://github.com/banister/plymouth per quello. Sta usando pry però, un'alternativa (migliore) a irb.

HTH

+0

Ho provato Plymouth. Non ha funzionato abbastanza in modo affidabile per me. Anche la storia dello sviluppo sembra indicare che non è una gemma molto ben supportata, quindi preferirei non fare affidamento su di essa. – Vighnesh

1

È necessario intercettare l'eccezione ExpectationNotMatched mentre è in fase di costruzione. Includi il codice seguente nei tuoi helper da qualche parte e RSpec si fermerà quando verrà costruita l'eccezione. Ci saranno diversi livelli nelle profondità dei matcher, quindi nel debugger dirai "where", quindi "up 5" o "up 6" e sarai all'interno dell'istanza_exec del tuo blocco. Il debugger non mostra correttamente il codice nella versione che sto usando, ma puoi "risalire" ancora una volta e ottenere il codice in esecuzione nello stesso contesto in cui viene valutato il test, in modo da poter controllare le variabili di istanza (ma non le variabili locali, sembra).

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 
+0

Questo sembra molto promettente. Ci proverò. Grazie, Clifford! – Vighnesh

-1

Si può provare hammertime. Si fermerà e richiederà di portarti in una sessione di debug interattiva ogni volta che viene sollevata un'eccezione.

+1

[pry-rescue] (https://github.com/conradirwin/pry-rescue) (un plugin pry) è di gran lunga superiore a hammertime, ti lascia nel contesto effettivo dell'eccezione e ti consente di camminare nello stack – horseyguy

+0

I dovrei davvero passare a fare leva su uno di questi giorni ... – davogones

+0

Lo controllerò. Grazie per il consiglio. – Vighnesh

5

Non si ottiene l'accesso a variabili locali (facilmente) senza debugger essere nel campo di applicazione del blocco, tuttavia RSpec vi dà intorno ganci che ti permette di fare questo:

config.around(:each) do |example| 
    result = example.run 
    debugger if result.is_a?(Exception) 
    puts "Debugging enabled" 
end 

È quindi avere accesso a @ivars e subject/let(:var) contenuto a questo punto.

+0

Interessante. Questo però non colmerebbe i fallimenti dei test, vero? – Vighnesh

2

mi piace @ soluzione di Jon-Rowe (senza gemme aggiuntivi necessari) con una lieve modifica: davvero non mi importa di altri errori per quanto RSpec::Expectations::ExpectationNotMetError.

config.around(:each) do |example| 
    example.run.tap do |result| 
     debugger if result.is_a?(RSpec::Expectations::ExpectationNotMetError) 
    end 
    end 
Problemi correlati