アーカイブ

‘Ruby’ タグのついている投稿

cucumber で javascript テスト

2011 年 5 月 11 日 Aki コメントはありません

cucumber で javascriptテストなどをする場合はシナリオごとに @javascript タグを付ける。
テストを実行するとなんらかのWebDriver (デフォルトはselenium) がブラウザを起動して
テストを実行するわけだが、alert や confirm が邪魔になる場合がある。
これらの確認をする必要がない場合は単純に alert や confirm を上書きして
なんの挙動もしないようにしてしまえば良い。

さらに web_steps_ja.rb に利用部品として書いて好きな時にユーザが呼び出せるようにしてしまえば良いかな。

web_steps_ja.rb

module NotificationHelpers
  def ignore_notification(page)
    page.evaluate_script("window.alert = function(msg) { return true; }")
    page.evaluate_script("window.confirm = function(msg) { return true; }")
  end
end
World(NotificationHelpers)

前提 /^通知を無視する$/ do
    ignore_notification(page)
end

test.features (サンプル)

     @javascript
     シナリオ: 〜〜〜を登録する
     前提     ログイン名が"xxxxx"、パスワードが"yyyy"のユーザでログインしている
     前提     "〜〜〜登録"ページを表示している
     前提     通知を無視する

     〜以下任意のテスト〜

     もし         〜をクリックする
     ならば     〜が表示されていること

#上記テストを実行するとブラウザが勝手に起動してテスト動いていくので selenium に免疫のない人はびっくりしないように :-)

カテゴリー: Development, Ruby タグ: , , ,

cucumber の paths.rb で DBの値を利用する

2011 年 4 月 26 日 Aki コメントはありません

そもそも paths.rb の中で Model使えるのかとか思ったのですが、なんの事はない。普通に User.find(123) とかできるのですね。ちゃんと理解していないからこんな疑問が発生するのでしょう。

それはさておき。

when /フォロワーが([0-9]+)人いるユーザのプロフィール画面/
    user = Users.find(:first, :conditions => { :follower => $1.to_i} )
    edit_user_info_path(user.id)

([0-9]+) など、正規表現でマッチングさせておきと $1 で値渡してあげれば OK
正規表現のマッチングで () 内にヒットしたものが $1, $2…となるのを知らない人は意外にいるようだ。

paths.rb っていうか、結局 routes.rb の話なんだよね。

カテゴリー: Development, Ruby タグ: , ,

TDD テスト駆動開発 in 第4回勉強会@minami.rb

2011 年 2 月 3 日 Aki コメントはありません

第4回勉強会@minami.rb に参加してきた。
http://qwik.jp/minamirb/57.html

その中での1セッション 『TDD テスト駆動開発入門』(by yalabさん)での課題が時間内に終わらなかったので復習をかねて最後までやり遂げる事に。ruby はそんなに書きなれていない事もあり、なかなか手間取ったがやっと課題の要件はみたす事ができたので、ここに晒しておく。
ruby ではそうじゃないよとか、普通はこうだよね。的なツッコミを入れていただけると有難いです。

時間がかかったポイントとしては ruby の実装不足。慣れてないのが大きいのかなと。
ただコーディングするだけならすぐかもしれないが、いかにrubyっぽく綺麗に書けるのだろうかと考えながらだったからのような気がします。実際このコードが rubyの暗黙の美的センスに乗っ取っているかどうかはわからないのですが、極力そうしたつもり。
for とか while とかでぐるぐるまわして if で条件分岐してどうたらとかいうのは、なるべくしたくないですし。

こういう積み重ねが大切ですね。
まぁ、とりあえずこんな感じで一旦アップしておきます。
ちょっと思うところがあるので、これに手を入れてすぐに第2版をアップしたいと思います。

課題
http://www.slideshare.net/yalab/ss-6749458
・月末を返す last_day メソッドを作ってください。
・第一週の日曜日 (先月の最後の日曜日かもしれない)を返すメソッドを作ってください。
・最終週の土曜日(次月の最初の土曜日かもしれない)を返すメソッドを作ってください。
・各週と各日を操作するeach_weekとeach_dayを作ってください。
・月曜始まりと日曜始まりの両方を使えるようにしてください。

calendar.rb
カレンダー

calendarTest.rb
カレンダーのテストクラス
これが重要。これのおかげで一旦完成した後も躊躇なくリファクタリングを進める事ができる。
常々思っている事なのだが、テストコードは人の為と云うよりも自分の安心の為に書くものだと思う。

実行結果


$ ruby calendarTest.rb
Loaded suite calendarTest
Started
................
Finished in 0.02391 seconds.

16 tests, 16 assertions, 0 failures, 0 errors

Calendar.rb

class Calendar
  attr_reader :first_day
  attr_reader :last_day
  attr_reader :base_cwday

  def initialize(year, month, base_cwday = "Sun")
    @first_day = Date.new(year, month, 1)
#    @last_day = (Date.new(year, month, 1) >> 1) - 1
    @last_day = (Date.new(year, month, -1))
    @base_cwday = Date::ABBR_DAYNAMES.index(base_cwday)
  end

  # カレンダー表示上の最初の日を返す
  def display_first_day
    return @first_day - @first_day.cwday + @base_cwday
  end

  # カレンダー表示上の最後の日を返す
  def display_last_day
    return @last_day + (6 - @last_day.cwday + @base_cwday)
  end

  # 当月すべての日を週ごとに配列にして返す
  def each_week
    weeks = Array.new()
    display_first_day.step(display_last_day, 7) {|wd|
      week = Array.new()
      wd.step(wd + 6, 1) {|d|
        week < < d if first_day.month == d.month
      }
      weeks << week
    }
    return weeks
  end

  # 当月すべての日を配列にして返す
  def each_day
    days = Array.new()
    @first_day.step(@last_day, 1) {|date|
      days << date
    }
    return days
  end
end

CalendarTest

require 'test/unit'
require 'date'
require './calendar'

class CalendarTest  < Test::Unit::TestCase

  # 基本パターン
  def test_first_day_201101
    actual = Calendar.new(2011, 1)
    assert_equal Date.new(2011, 1, 1), actual.first_day
  end

  # 固定値で返してないか別の月で確認
  def test_first_day_201102
    actual = Calendar.new(2011, 2)
    assert_equal Date.new(2011, 2, 1), actual.first_day
  end

  # 日数 31日
  def test_last_day_201101
    actual = Calendar.new(2011, 1)
    assert_equal Date.new(2011, 1, 31), actual.last_day
  end

  # 日数 28日
  def test_last_day_201102
    actual = Calendar.new(2011, 2)
    assert_equal Date.new(2011, 2, 28), actual.last_day
  end

  # 日数 29日
  def test_last_day_201002
    actual = Calendar.new(2012, 2)
    assert_equal Date.new(2012, 2, 29), actual.last_day
  end

  # 日数 30日
  def test_last_day_201004
    actual = Calendar.new(2010, 4)
    assert_equal Date.new(2010, 4, 30), actual.last_day
  end

  ## display_first_sunday
  # カレンダー上の最初日曜が前月にあるパターン
  def test_display_first_day_feb
    feb = Calendar.new(2011, 2)
    assert_equal Date.new(2011, 1, 30), feb.display_first_day
  end

  # カレンダー上の最初日曜が前月にあるパターン(月曜始まり)
  def test_display_first_day_feb_Mon
    feb = Calendar.new(2011, 2, "Mon")
    assert_equal Date.new(2011, 1, 31), feb.display_first_day
    puts feb.base_cwday
  end

  # カレンダー上の最初日曜が前年前月にあるパターン
  def test_display_first_day_jan
    feb = Calendar.new(2011, 1)
    assert_equal Date.new(2010, 12, 26), feb.display_first_day
  end

  ## display_last_saturday
  # カレンダー上の最終土曜が翌月にあるパターン2
  def test_display_last_day_201101
    actual = Calendar.new(2011, 1)
    assert_equal Date.new(2011, 2, 5), actual.display_last_day
  end

  # カレンダー上の最終土曜が翌年翌月にあるパターン
  def test_display_last_day_201012
    actual = Calendar.new(2010, 12)
    assert_equal Date.new(2011, 1, 1), actual.display_last_day
  end

  # カレンダー上の最終土曜が翌年翌月にあるパターン(月曜始まり)
  def test_display_last_day_201012_mon
    actual = Calendar.new(2010, 12, "Mon")
    assert_equal Date.new(2011, 1, 2), actual.display_last_day
  end

  # カレンダー上の最終日が当月にあるパターン
  def test_display_last_day_201104
    actual = Calendar.new(2011, 4)
    assert_equal Date.new(2011, 4, 30), actual.display_last_day
  end

  # カレンダー上の最終日が当月にあるパターン(月曜始まり)
  def test_display_last_day_201107_mon
    actual = Calendar.new(2011, 7, "Mon")
    assert_equal Date.new(2011, 7, 31), actual.display_last_day
  end

  def test_each_week
    actual = Calendar.new(2011, 1)
    expect = [
    	Array.new(1) { |i| i+1 },
    	Array.new(7) { |i| i+2 },
    	Array.new(7) { |i| i+9 },
    	Array.new(7) { |i| i+16 },
    	Array.new(7) { |i| i+23 },
    	Array.new(2) { |i| i+30 },
    	]
    weeks = Array.new()
    expect.each { |e|
      week = Array.new()
      e.each { |d|
        week << Date.new(2011,1,d)
      }
      weeks << week
    }
    assert actual.each_week == weeks
  end

  def test_each_day
    actual = Calendar.new(2011, 1)

    array = Array.new([])
    (1..31).each { |day|
      array << Date.new(2011,1,day)
    }
    assert actual.each_day == array
  end

end
カテゴリー: 未分類 タグ: , ,