83's

Top > Tags > RSpec

RSpec

タイトル一覧を表示 | 本文を表示

rake spec:uncommitted August 23, 2007 02:43

なさそうなのでtest:uncommittedを移植してみた。 test:uncommittedを使った試しがないのでこれも使わない可能性大w

rspec_base = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec/lib')
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
require 'spec/rake/spectask'
require 'spec/translator'

desc "Run specs changed since last checkin (only Subversion)"
Spec::Rake::SpecTask.new("spec:uncommitted" => "db:test:prepare") do |t|
  changed_since_checkin = silence_stderr { `svn status` }.map {|path| path.chomp[7 .. -1] }

  specs = changed_since_checkin.select {|path| path =~ %r{spec/.*_spec\.rb} }
  specs += changed_since_checkin.select {|path| path =~ %r{(app/(models|controllers)|lib)/.*\.rb} } \
            .map {|path| 'spec/' + path.sub(/\Aapp\//, '').sub(/(?=\.rb)/, '_spec') } \
            .select {|path| File.exist?(path) }

  t.spec_files = specs.uniq
  t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
end

これをrspec_uncommitted.rakeみたいな名前にしてlib/tasksに放りこむ。

ちなみにrake spec:recentはRSpec on Rails rake task for Recent Specs にある。 spec:uncommittedの頭のrequireを追加しないと動かないと思うんだけど……。 あとspec/spec.optsを読むようにt.spec_optsのところを変更すると ほかのタスクと同じになっていい感じ。

さて、特定のdescribeitvimから実行するのは確かに便利なんだけど、 その間vimが使えなくて困る。10秒くらい何もできないのが辛い……。

spec:recentがあればscreenの別のwindowで走らせてすかさずvimに戻れるなーと。 rake spec SPEC=spec/controllers/foo_controller_spec.rbなんて いちいち打つのは鬱で仕方ないですよね(ノ∀`)アチャー

あー、どうでもいいけどこのブログのオレオレ記法パーサがヘタレすぎる。 プログラム貼ると記法の記号とかぶってパースエラーになりやすいので 今までエラーになる箇所をいちいちエスケープしてたけど、 もうめんどいからHTML直接書いた。それでもあやしい。

大体なんでpreの中でタグ使うこと想定してんだろう、このオレオレ記法は。 YukiWikiの記法を拡張してるんだけど''なんか空文字列とモロかぶるし、 なまじエスケープなんかができるもんだから予期せぬところでエスケープされておかしなことに。 時々バックスラッシュの数とかおかしい場合があるかもしれないけどそのせいです。

rake specしたらdevelopmentのデータベースがテストに使われて( ゚д゚)ポカーン August 21, 2007 05:10

ここのところ、既存のアプリケーションの大幅なページ構成の変更と機能追加のために がちゃがちゃとソースに手を入れてプロトタイプを作っていた。 インタフェースとデザインに悩んでいるのがほとんどだったけども。 引き出しが少ないんだよなぁ。

イメージが固まるまで追加・削除・変更が続くので テストなんか書いてられないことに気がついて、 久しぶりにテストのことを忘れてとりあえず動くようにコードを書く……あー早い。

rakeしたらきっとFFFFFFFFFFFFFFFFFFFFFFFFFFFってなってるw  でもそんなの関係ねぇ! そんなの関係ねぇ!

で、作業が一段落したところで恐いもの見たさでrake specってやってみたわけだけど、 developmentのデータベースから数百MのデータがごそーとDELETEされて 代わりにfixturesのデータがぽつんと入っているという状態になった(#^ω^)ピキピキ

ちょっと前はこんなことなかったのに。 そう言えばsvn:externalsにしてるrspecとrspec_on_railsが更新されてたなぁ。 そのせいか。

spec_helper.rbを変更したら直った。

- ENV["RAILS_ENV"] ||= "test"
+ ENV["RAILS_ENV"] = "test"

test以外にすることがあるの……?

最近のspec_helper.rbでは修正されてる。 微妙に無駄な時間を過ごしたぜ。そしてこのエントリも久々の更新にしては微妙。

:shared => true July 12, 2007 00:56

またRSpecから離れてた。なかなか触れてない……。

共通のbeforeの抜き出しにはこの前みたいにこざかしいことしなくても :shared => true使って

describe 'setup', :shared => true do
  before do
    @a = 3
  end
end

describe 'aaa' do
  it_should_behave_like 'setup'

  before do
    @b = 4
  end

  it 'a' do
    @a.should == 3
    @b.should == 4
  end
end

describe 'bbb' do
  it_should_behave_like 'setup'

  it 'a' do
    @a.should == 3
    @b.should be_nil
  end
end

でいいのか。itしかshareできないと勝手に思ってた。英語読めてない証拠……。 あとセンスが足りない。

global_fixturesなんてのが June 26, 2007 01:54

見落としてた。

RSpec on RailsでfixturesをDRYに指定する方法がspec/spec_helper.rbに書いてあった。

  # Alternatively, if you prefer to declare them only once, you can
  # do so here, like so ...
  #
  #   config.global_fixtures = :table_a, :table_b
  #
  # If you declare global fixtures, be aware that they will be declared
  # for all of your examples, even those that don't use them.

まーでもこれはやりすぎかも……。遅くなりそう。

RSpecのdescribe内の共通部分 June 25, 2007 18:52

Railsのテスト振る舞いwをRSpecで書き始めたんだけど、 複数のdescribeで共通してる部分(fixturesとかbeforeとか)をDRYにしたかったので、 RSpecにおけるコンテキストをまたぐ共通部分を 激しく参考にさせてもらって、こうしてみた。

spec/spec_helper.rbに以下のように書く。

def common_description(klass, name = nil, &blk)
  name ||= klass.to_s.underscore
  Kernel.class_eval do
    define_method "_describe_#{name}" do |comment, prok|
      describe klass, comment do
        instance_eval &blk
        instance_eval &prok
      end
    end

    eval <<-DEF
      def describe_#{name}(comment, &blk)
        _describe_#{name}(comment, blk)
      end
    DEF
  end
end

で、*_spec.rbではこんな感じ。

require File.dirname(__FILE__) + '/../spec_helper'

common_description FooController do
  fixtures ...

  before do
    ...
  end
  ...
end

describe_foo_controller '#edit' do
  it ...
    ...
  end
end

describe_foo_controller '#create' do
  ...
end

common_descriptionのところでFooControllerクラスの各describeの共通部分を書く。 するとdescribe_foo_controllerが定義されるのでdescribeの代わりにそれを使う。

describe_foo_controller以外の名前を付けたいとか、別に作りたいときには

common_description FooController, 'foo_controller2' do
  ...
end

とすればdescribe_foo_controller2という名前になる。

参考もとのコードからinstance_evalが消せて少しDRYな気分。でもメソッド名がダメな気がする。 あとブロック引数にブロックをとれるときれいになるのになぁ。

何よりみんなはどうやってるんだか気になる。

vimからRSpec on Rails May 06, 2007 03:28

少しずつRSpec on Railsに移行していこうとしてるんだけど、 Test::Unitと違ってrails.vimのサポートがなくて簡単に走らせることができないので moroさんのRSpec用のマクロをベースに ごにょごにょ。

function! Rspec ()
  let rails_spec_pat = '\<spec/\(models\|controllers\|views\|helpers\)/.*_spec\.rb$'
  if expand('%:p') =~ rails_spec_pat
    exe '!rake spec SPEC="'.expand('%:p').'" RSPECOPTS="-fs -c -l '.line('.').'"'
  else
    :!spec -fs -c %
  endif
endfunction

au BufRead,BufNewFile *_spec.rb :command! Rspec :call Rspec()

*_spec.rb開いて:Rspecで実行できる。

違いは

  • rake specを使う
  • 現在のカーソルの行を--lineオプションに使う

--lineオプションのおかげで、実行したいit(specify)の中にカーソル持ってくれば そこだけ実行してくれる。 itの外だとそこのdescribe(context)を実行……するといいんだけど、 カーソルとdescribe行の間にitがある場合、カーソルに1番近い itのみが実行される。まあこれはRSpecの仕様、ということで。

--exampleオプションを使えたら一番いいけど、vimスクリプト書かないとどうしようもないので ひとまずこれでガマン。

それから、spec/spec.optsからオプション読めたらいいんだけど、これもオレには無理。 とりあえず今はRSPECOPTSに書き込む。

一息ついたらvimスクリプト勉強しようと思う。 rails.vimの人がなんとかしてくれたらそれが一番最高ですが。

まだRSpec全然触れてないんだけど、個人的な感想としては describe/itの2段階で括れることと、それらの引数のところで説明が書けるのが好きだな、 コメントより目立つし。 あとTest::Unitのtest_xxxみたいに妙な英語を書く必要もないし……。

shouldなんとかはどうでもいいというか、むしろ慣れるまでキモいんだけど。 あ、Test::Unitではtest_helper.rbに繰り出せば良かったメソッドって、 RSpecではどこにどう書いたらいいんだろう……。

そういえば知らないうちにcontext/specifyからdescribe/itになったみたいだけど、 日本語の場合はちょっと微妙だな……。itなんて動詞ですらない。