pockestrap

Programmer's memo

テストの際にいい感じにbinding.pryするGem PryTestcase を作った

github.com

Rubygems: pry_testcase | RubyGems.org | your community gem host

前置き

# Twitter にメッセージを投稿する
def say(msg, param)
  opt = to_opt(param)
  opt.message = msg

  send_to_twitter(opt)
end
describe '#say' do
  context 'case1' do
    it 'should send to twitter' do
      ...
    end
  end

  context 'case2' do
    it 'should send to twitter' do
      ...
    end
  end
end

上記の様な、say()メソッドと、そのテストがあります。
このテストを書いていると、case2でのみテストが落ちるようです。

デバッグの為say()メソッド内のopt変数を表示したいので、以下のようにsay()メソッドの中にbinding.pryを仕込みました。

# Twitter にメッセージを投稿する
def say(msg, param)
  opt = to_opt(param)
  opt.message = msg

  # ここ
  binding.pry

  send_to_twitter(opt)
end

これでsay()メソッド内でデバッガが起動して、opt変数を参照することが出来ます。

ところが

ひとつ、問題があります。
この状態でこのファイルに対してテストを走らせてしまうと、case1, case2の両方に対してテストが走ってしまいます。
そうするとpryが2回実行されてしまい若干鬱陶しいです。
もしテストケースが大量にあった場合はそれだけ多くpryが起動してしまうため、このデバッグ方法は使いづらくなってしまいます。

解決策

そこで、PryTestcaseを導入します。 以下のようにインストールして下さい。

Gemfile

group :test do
  gem 'pry_testcase'
end
$ bundle install

このGemは次のように使います。まず、先ほど挿入したbinding.pryPryTestcase.pryに置き換えます。

# Twitter にメッセージを投稿する
def say(msg, param)
  opt = to_opt(param)
  opt.message = msg

  # ここ
  PryTestcase.pry

  send_to_twitter(opt)
end

そして、pryを起動したいテストケースにのみ:with_pry_testcaseを付与します。

describe '#say' do
  context 'case1' do
    it 'should send to twitter' do
      ...
    end
  end

  context 'case2', :with_pry_testcase do
    it 'should send to twitter' do
      ...
    end
  end
end

この状態でRSpecを実行するとcase2でのみpryが起動します。 必要な時にのみpryが起動するようになって便利ですね。


以上、PryTestcaseの紹介でした。
テストを書いていてpryを何度もCtrl-Dで殺した覚えがある方は是非一度お試しください。