Rspecでfailするとデスメタルが流れるようにした
あまりにもテスト通らないのでデスメタル聴き始めた
— ⁰⁰⁰⁰null (@yuroyoro) 2015, 7月 2
このような事があったので自動化した。
Mac限定。
こんな感じ。successだとレベルがアガる。
事前にbash-itunes というコマンドラインツールを入れておく。
iTunesを日本語で使ってる場合、patchを当てる必要がある。
こちらを山椒
コードはこれな。
class PlayItunesReporter attr_accessor :success_track, :failure_track def initialize(options = {}) @success_track = options[:success] @failure_track = options[:failure] end def dump_summary(notification) return unless notification.examples.length > 0 if notification.failed_examples.length == 0 play!(success_track) else play!(failure_track) end end def play!(track) `itunes play "#{track}"` end end RSpec.configure do |config| itunes = PlayItunesReporter.new(success: "レベル・アップ", failure: 'Nemesis') config.reporter.register_listener itunes, :dump_summary end
正直、曲は好きなの使えばいい。なんならこれでもいい
inspired by : コンパイル中に音楽を流せる sbt プラグインを作りました。 - tototoshi の日記
rspecの--tagオプションを利用して任意のコマンドライン引数をspec側に渡すという邪悪なhack
今まで、rspecコマンドでは任意の引数を渡すことはできなかったので、環境変数経由で引き渡すという方法をとっていた。
( ;゚皿゚)ノシΣ フィンギィィーーッ!!!
MY_OPT1=true rspec spec/my_spec.rb
環境変数で渡すのはダルいのでなんとかしたいと思い、`--tag`オプション経由で値を渡すというダーティなhackを書いた。
仕掛けは、helper.rbなどで、以下のように`Rspec.world.filter_manager.incusions`から引数を切り出してクラス変数に保持しておくようなアレをホゲる。
helper.rb
class MyOptions class << self OPTION_KEYS = [:my_opt1, :my_opt2] attr_accessor :options def parse(world) @options = world.filter_manager.inclusions.slice(*OPTION_KEYS) end end end RSpec.configure do |config| # filterをonに config.filter_run :focus => true config.run_all_when_everything_filtered = true # --tagから独自の引数を切り出して保持しておく MyOptions.parse(RSpec.world) end
あとは、`MyOptions.options[:my_opt1]`のように参照できる。
my_options_spec.rb
require File.join(File.dirname(__FILE__), 'helper') describe "MyOptions" do subject { MyOptions.options } it { should include(:my_opt1) } it { should include(:my_opt2) } end
実行すると、`--tag`経由で引数が渡っていることが確認できる。
$ rspec spec/my_options_spec.rb -t my_opt1 -t my_opt2 Run options: include {:focus=>true, :my_opt1=>true, :my_opt2=>true} All examples were filtered out; ignoring {:focus=>true, :my_opt1=>true, :my_opt2=>true} MyOptions should include :my_opt1 should include :my_opt2 Top 2 slowest examples (0.0029 seconds, 100.0% of total time): MyOptions should include :my_opt1 0.00205 seconds ./spec/my_options_spec.rb:6 MyOptions should include :my_opt2 0.00085 seconds ./spec/my_options_spec.rb:7 Finished in 0.0034 seconds 2 examples, 0 failures
`--tag`渡さないとfailする。
$ rspec spec/my_options_spec.rb Run options: include {:focus=>true} All examples were filtered out; ignoring {:focus=>true} MyOptions should include :my_opt1 (FAILED - 1) should include :my_opt2 (FAILED - 2) Failures: 1) MyOptions should include :my_opt1 Failure/Error: it { should include(:my_opt1) } expected {} to include :my_opt1 Diff: @@ -1,2 +1 @@ -[:my_opt1] # ./spec/my_options_spec.rb:6:in `block (2 levels) in <top (required)>' 2) MyOptions should include :my_opt2 Failure/Error: it { should include(:my_opt2) } expected {} to include :my_opt2 Diff: @@ -1,2 +1 @@ -[:my_opt2] # ./spec/my_options_spec.rb:7:in `block (2 levels) in <top (required)>' Top 2 slowest examples (0.00381 seconds, 100.0% of total time): MyOptions should include :my_opt1 0.00282 seconds ./spec/my_options_spec.rb:6 MyOptions should include :my_opt2 0.00099 seconds ./spec/my_options_spec.rb:7 Finished in 0.00432 seconds 2 examples, 2 failures Failed examples: rspec ./spec/my_options_spec.rb:6 # MyOptions should include :my_opt1 rspec ./spec/my_options_spec.rb:7 # MyOptions should include :my_opt2
ちょっとの手間でRSpecの出力をキレイにするnamed_letをrubygems.orgに登録した
以前書いた、「 ちょっとの手間でRSpecの出力をキレイにするためにnamed_letというのを書いてみた - ゆろよろ日記」を、
ちゃんとしたGemにしてrubygems.orgに登録しました。
named_let | RubyGems.org | your community gem host
ソースコードはGithubにあります。
ですが、ひとつ問題があります。このissueをご覧ください。
Issue #1: Very poor English!!!! · yuroyoro/named_let · GitHub
pull requestお待ちしております!!!!!
ちょっとの手間でRSpecの出力をキレイにするためにnamed_letというのを書いてみた
RSpecの話です。
RSpecは、テストコードがそのまま仕様を記述するドキュメントになる、というのが大きな利点の一つです。
しかし、rspecコマンドに-dオプションを渡して出力されるドキュメントは、必ずしも読める文章になっているとは限りません。
例として、以下のようなCanCanのspecを見てみます。
require 'spec_helper' require "cancan/matchers" describe Ability do context 'an user' do let(:user) { Factory.create(:user) } let(:article) { Factory.create(:article) } let(:own_article) { Factory.create(:article, :user => user) } subject { Ability.new(user) } it { should be_able_to(:read, article) } it { should be_able_to(:update, own_article) } end end
Userは、ある記事をreadする権限を持っていて、自分が書いた記事はupdateすることができる、という記述です。
'should be_able_to(:read, article)'や' should be_able_to(:update, own_article) 'は、そのままの文章になってます。
では、これをrspec -dで実行してみます。
アルェ?
'should be able to :read #
describe Ability do context 'an user' do let(:user) { Factory.create(:user) } named_let(:article) { Factory.create(:article) } named_let(:own_article, "own article") { Factory.create(:article, :user => user) } subject { Ability.new(user) } it { should be_able_to(:read, article) } it { should be_able_to(:update, own_article) } end end
さっきのspecで、letで定義されていたarticleを、named_letを利用するように変更しました。named_letでは、第一引数のSymbolを表示の際に利用します。第二引数に別名を渡すことも出来ます。
named_let(:article) { Factory.create(:article) } named_let(:own_article, "own article") { Factory.create(:article, :user => user) }
あらためて実行してみます。
ちゃんと意図した文章になって出力されていますね。やったー。