Agile Web Development with Rails and Cucumber

Preview:

DESCRIPTION

at NagoyaRubyKaigi01

Citation preview

Agile Web Developmentwith

Rails and Cucumber株式会社永和システムマネジメントサービスプロバイディング事業部

浦嶌 啓太

✓(株)永和システムマネジメント

✓Rubyプログラマ

✓三重県出身で名古屋の大学に通っていました

浦嶌 啓太 (id:ursm)http://d.hatena.ne.jp/ursm/http://twitter.com/ursm

http://ruby.agile.esm.co.jp/

よろしくお願いします

✓RubyとRailsは顧客との対話によって駆動されるインクリメンタルな開発を実現した

✓一方、成長し続けるシステムの今の姿を把握するのはどんどん難しくなっていく

✓開発を持続していくためにシステムの振る舞いを何らかの形で表現しなければならない

Cucumber

1. キュウリ

2. 特定の形式で記述されたフィーチャ(要求)を元に、システムが期待通りに振る舞うかをテストするフレームワーク

【名】

フィーチャ: ユーザを管理する シナリオ: ユーザを追加する 前提 "New user"ページを表示している もし "Name"に"user1"と入力する かつ "Create"ボタンをクリックする ならば "user1"と表示されていること

✓フィーチャ✓シナリオ✓ステップ

ステップ✓Given

前提 "New user"ページを表示している

✓Whenもし "Name"に"user1"と入力する

✓Thenならば "user1"と表示されていること

シナリオ✓あるフローを構成するステップの

集まり

シナリオ: ユーザを追加する 前提 "New user"ページを表示している もし "Name"に"user1"と入力する かつ "Create"ボタンをクリックする ならば "user1"と表示されていること

✓ある要求を構成するシナリオの集まり

フィーチャ

フィーチャ: ユーザを管理する シナリオ: ユーザを追加する … シナリオ: ユーザを削除する …

✓フィーチャ✓シナリオ✓ステップ

Step DefinitionsGiven /^"([^\"]*)"ページを表示している$/ do |page_name|

  visit path_to(page_name)end

When /^"([^\"]*)"に"([^\"]*)"と入力する$/ do |field, value|  fill_in(field, :with => value)end

Then /^"([^\"]*)"と表示されていること$/ do |regexp|

  regexp = Regexp.new(regexp)  response.should_not contain(regexp)end

これ}

Given /^"([^\"]*)"ページを表示している$/ do |page_name|  visit path_to(page_name)end

前提 "New user"ページを表示している

✓簡単なことは簡単に✓ 標準のStep definitionが用意されている

✓ リンクを辿る, フィールドに入力する, etc...

✓難しいこともそれなりに✓ 自分でStep definitionを書く

✓ Rubyでできることなら大体できる

✓ 複雑な画面をXPathで切り出して検証する, 別システムに問い合わせる, etc...

1. フィーチャを書く

2. Step definitionsを書く

3. プロダクションコードを書く

4. Cucumberで検証する

Cucumberのうれしさ

フィーチャ: ユーザを管理する シナリオ: ユーザを追加する 前提 "New user"ページを表示している もし "Name"に"user1"と入力する かつ "Create"ボタンをクリックする ならば "user1"と表示されていること

誰でも読める

✓お客様が仕様を確認する

✓テスト担当者がシナリオの不足をチェックする

✓開発を引き継いだ担当者がシステムの概要を調べる

もちろん開発者にとっても読みやすく書きやすい

システムに関わる人みんなの共通言語になる

ユーザ視点

フィーチャ: ユーザを管理する シナリオ: ユーザを追加する 前提 "New user"ページを表示している もし "Name"に"user1"と入力する かつ "Create"ボタンをクリックする ならば "user1"と表示されていること

✓ユーザから見たシステムの振る舞いが記述される

✓1つ変更を加えるとテストが軒並み落ちる

✓テストが足枷になってしまう

➡実装をテストしている

テストにありがちなこと

ユーザの視点に立ってシステムをブラックボックステストする

RSpec Cucumber

ターゲット

エンドポイント

視点

オブジェクト システム

メソッド UI

開発者 エンドユーザ

ユーザにとっての振る舞いが変化しない限り、安心してコードを変更できる

資産価値の高いテストコード

✓RSpecはオブジェクトの振る舞いを表現する

✓Cucumberはシステムの振る舞いを表現する

"When you get down to nitty gritty details, drop down one

abstraction level and use RSpec, or any Ruby testing framework,

to write some specs/tests for your classes."

キュウリが育つ土壌をつくる

✓Cucumberも放っておくと荒廃する

✓キュウリが育つ土壌づくりが大切

✓エンドユーザになりきる

✓フィーチャをリファクタリングする

✓プロジェクトに特化した語彙を作る

✓"お客様はそれを知っているか?"

✓主語に注意する

エンドユーザになりきる

シナリオ: 記事を投稿する  前提 "articles"テーブルが空である  もし "/artiles/new"に"body=hoge"をPOSTで送る  ならば "Article.count"が1であること かつ フィードを生成すること

フィーチャのリファクタリング

✓フィーチャはドキュメントです

✓常に推敲を心がけましょう

フィーチャ: 記事を管理する  シナリオ: 記事を投稿する    # ログイン処理    前提 "ログイン"ページを表示している    もし "ユーザ名"に"hoge"と入力する    ...    もし "新規記事"ページを表示する    かつ "本文"に"こんにちは"と入力する    ...  シナリオ: 記事を削除する    # ログイン処理 ...

フィーチャ: 記事を管理する  背景:    前提 "ログイン"ページを表示している    もし "ユーザ名"に"hoge"と入力する    ...

  シナリオ: 記事を投稿する    もし "新規記事"ページを表示する    かつ "本文"に"こんにちは"と入力する    ...

Background

プロジェクトに特化した語彙

✓ある用語で表わされる一連のステップを、独立したステップとして括り出す

Given /^ユーザ"([^\"]*)"としてログインしている$/ do |name|

  Given %("ログイン"ページを表示している)  When %("ユーザ名"に"#{name}"と入力する)  ...end

Calling Steps from Step Definitions

フィーチャ: 記事を管理する  シナリオ: 記事を投稿する    前提 ユーザ"hoge"としてログインする    もし "新規記事"ページを表示する    かつ "本文"に"こんにちは"と入力する    ...

まとめ

Cucumberは開発者とお客様の双方に価値を提供します

✓実装に依存しない資産価値の高いテスト

✓変化し続ける勇気

開発者として

お客様として

✓システムの今の姿を正確に表わした、自分で読めるドキュメント

✓それに支えられたシステム

Happy Developmentwith Cucumber!

ご清聴ありがとうございました

Recommended