RSpec + RCov でテストしたい。 その2
昨日 RSpec + RCov でテストしたい。 - 日々此妄想 のつづき
要はrails以外のスクリプトで RSpec でテストしつつ、RCovでカバレッジ測定したいという要望
昨日は。。。
specファイルに
require 'rubygems' require 'spec'
って書いておいて
$ rcov spec/hoge_spec.rb
で通るじゃーん。
と思ってたんだけど、それは間違いで
./spec/hoge_spec.rb:7: undefined method `describe' for main:Object (NoMethodError)
というエラーがでなくなるだけ。
実際にはテストは起動されてない。したがってカバレッジもちゃんと測定できていない。
あきらめて先人の知恵を借りる。
rakeファイルで一発じゃん。
という情報多数。
なんかrakeってよくわかんないので避けてたけど使ってみるか。
先人の知恵は
require "rake" require "spec/rake/spectask" desc "Run with rcov" Spec::Rake::SpecTask.new("spec_with_rcov") do |t| t.spec_files = FileList["spec/**/*_spec.rb"] t.rcov = true t.spec_opts = ["-c"] t.rcov_opts = ["-x", "spec"] end
とかいうRakefileを用意して
$ rake spec_with_rcov
するというモノ。
実際やってみるとすんなり行った。うむ。めでたしめでたし。
で、気がついた事
そんなこんなでテストを書いてごにょごにょしていると。。。こんな出力に遭遇
$ rake spec_with_rcov (in /home/hana-da/work/hoge) rm -r coverage ......Frake aborted! Command /usr/bin/ruby -I"lib" -S rcov -x spec -o "coverage" "/usr/lib/ruby/gems/1.8/gems/rspec-1.2.9/bin/spec" -- "spec/hoge_spec.rb" -c failed
おおっ。何これ何これ???
テストに失敗するとカバレッジ測定も行われないっぽい。
ってのは、どうでもいいんだけど、最後の1行。これ!! これですよ求めてたの!!!
なるほどねー。こうなってなのか。
オプションを調べてみる
ruby | -I"lib" | ファイルをロードするパスを指定(追加)します。指定されたディレ クトリはRubyの配列変数($:)に追加されます。 | ||
---|---|---|---|---|
-S | スクリプト名が`/'で始まっていない場合, 環境変数 PATHの値を使ってスクリプトを探すことを指定しま す。 | |||
rcov | -x spec | Don't generate info for files matching a pattern (comma-separated regexp list) | ||
-o "coverage" | Destination directory. | |||
/usr/lib/ruby/gems/1.8/gems/rspec-1.2.9/bin/spec | spec/hoge_spec.rb | スペックファイル | ||
-c | Show coloured (red/green) output |
おお。そうか rcov で spec のカバレッジを測定するんだけど -x で spec がファイル名に含まれているものは除外される。
ほんでもって spec のオプションではスペックファイルが指定されているので、テスト対象のスクリプトをテストできて、しかもカバレッジも測定できるとな!!!
なっとくー。
という事は?
$ which spec alias spec='spec -c' /usr/bin/spec
なので
$ rcov -x spec -o "coverage" "/usr/bin/spec" -- "spec/hoge_spec.rb" -c
でもいいって事???
とりあえず /usr/bin/specと gemsの下にあるspecのdiffをとってみる。
$ diff /usr/bin/spec /usr/lib/ruby/gems/1.8/gems/rspec-1.2.9/bin/spec --- /usr/bin/spec 2009-12-02 14:17:08.000000000 +0900 +++ /usr/lib/ruby/gems/1.8/gems/rspec-1.2.9/bin/spec 2009-12-02 14:17:07.000000000 +0900 @@ -1,19 +1,5 @@ -#!/usr/bin/ruby -# -# This file was generated by RubyGems. -# -# The application 'rspec' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'rubygems' - -version = ">= 0" - -if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then - version = $1 - ARGV.shift -end - -gem 'rspec', version -load Gem.bin_path('rspec', 'spec', version) +#!/usr/bin/env ruby +rspec_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +$LOAD_PATH.unshift(rspec_dir) unless $LOAD_PATH.include?(rspec_dir) +require 'spec/autorun' +exit ::Spec::Runner::CommandLine.run
全く別物です。
でも、見た感じどっちでも行けそうだなぁ。。。
$ rcov -x spec -o coverage /usr/lib/ruby/gems/1.8/gems/rspec-1.2.9/bin/spec -- spec/hoge_spec.rb -c
動いた。
$ rcov -x spec -o coverage /usr/bin/spec -- spec/hoge_spec.rb -c
動いた。
ふーむ。
という事で。
昨日までは「おとなしくrakeしとくか。」と思ってたけどこういうaliasを切ってみた。
alias spec_with_rcov="rcov -x spec /usr/bin/spec -- `ruby -e 'puts Dir.glob("spec/**/*_spec.rb").join(" ")'` -c"
ふむ快適。*1
追記: とおもったけど、aliasだとaliasが定義された時にrubyの部分が展開されてしまって意図した動作にはならんですね。だめですね。シェルスクリプトにしますかね。←だったらrakeでいいじゃん。2009-12-09 13:48:32
*1:ちょっとスマートじゃない気はしている。。。