89
What’s culture and tools in Ruby worlds. SHIBATA Hiroshi Eiwa System Management,Inc.

Sapporo rubykaigi03

Embed Size (px)

Citation preview

Page 1: Sapporo rubykaigi03

What’s culture and tools in Ruby worlds.

SHIBATA HiroshiEiwa System Management,Inc.

Page 2: Sapporo rubykaigi03

Profile

Page 3: Sapporo rubykaigi03

SHIBATA Hiroshia.k.a hsbt

tDiary commiter

[email protected]

Page 5: Sapporo rubykaigi03

asakusa.rb

Page 6: Sapporo rubykaigi03
Page 7: Sapporo rubykaigi03

SapporoRubyKaigi

03

Page 8: Sapporo rubykaigi03

SapporoRubyKaigi01

Page 9: Sapporo rubykaigi03

SapporoRubyKaigi02

Page 10: Sapporo rubykaigi03

2010年3月1日永和システムマネジメント入社

Page 11: Sapporo rubykaigi03

今日話すことhsbt が2010年に永和システムマネジメントに入社してから半年間で得られた Ruby と Rails 界隈のテスト事情についてご紹介します。

Page 12: Sapporo rubykaigi03

今日話さないこと

tDiary

Page 13: Sapporo rubykaigi03

今日話さないこと

TDDとか品質

Page 14: Sapporo rubykaigi03

RubyKaigi2010

Page 15: Sapporo rubykaigi03

Conflictsand

Resolutions(衝突と解決)

Page 16: Sapporo rubykaigi03
Page 17: Sapporo rubykaigi03

ThoughtWorks

Page 18: Sapporo rubykaigi03

Rubyには、非常に成熟したテストの文化とツールもあります。Sudhindra Rao

Page 19: Sapporo rubykaigi03

テストを書かなかったら、君は本当にRuby開発者かと言われてしまいますよね。Sudhindra Rao

Page 20: Sapporo rubykaigi03

Culture

Page 21: Sapporo rubykaigi03

人間が社会の成員として獲得する振る舞いの複合された総体

社会組織ごとに固有の文化があるとされ、組織の成員になるということは、その文化を身につけるということでもある

Page 22: Sapporo rubykaigi03

ESMCulture

andTool

Page 23: Sapporo rubykaigi03

中の人たち

Page 24: Sapporo rubykaigi03
Page 25: Sapporo rubykaigi03

テストを書くhttp://www.flickr.com/photos/churl/250235218/

Page 26: Sapporo rubykaigi03

Why?

Page 27: Sapporo rubykaigi03

Ruby World Conference

2010

Page 28: Sapporo rubykaigi03

Rubyを使うとどんどん書ける

http://www.flickr.com/photos/14403423@N05/4979310028

Page 29: Sapporo rubykaigi03

どんどん書ける

Page 30: Sapporo rubykaigi03

書いているコードが正しく動くのか不安

Page 31: Sapporo rubykaigi03

だからテストを書く

Page 32: Sapporo rubykaigi03

RSpec

Page 33: Sapporo rubykaigi03

metric_fu

Page 34: Sapporo rubykaigi03

テストを書くレイヤーを分割する

Page 35: Sapporo rubykaigi03

一般的なシステム

ビジネスロジック DBUI

OS 外部API

テストテスト

Page 36: Sapporo rubykaigi03

Rails

Page 37: Sapporo rubykaigi03

細かいテストが可能なシステム

ビジネスロジック DBUI

OS 外部API

テスト

API ORM

テスト テスト テスト テスト

API API

OS

テスト テスト

Page 38: Sapporo rubykaigi03

GitHub

Page 39: Sapporo rubykaigi03

github explorer

Page 40: Sapporo rubykaigi03

細かいテストが可能なシステム

ビジネスロジック DBUI

OS 外部API

テスト

API ORM

テスト テスト テスト テスト

API APIテスト テスト

Page 41: Sapporo rubykaigi03

mock / stub

Page 42: Sapporo rubykaigi03

rspec-mocksrrmocha

flexmock

Page 43: Sapporo rubykaigi03

rr

Page 44: Sapporo rubykaigi03

stubstub(User).find { 'value' }

any_incetance_of(User) do |u| stub(u).name { ‘alice’ }end

User.find -> ‘value’

@u = [email protected] -> ‘alice’

Page 45: Sapporo rubykaigi03

mockmock(User).find.twice { 'value' }

User.find -> ‘value’

mock(User).all.mock!.count { 10 }

User.all.count -> 10

Page 46: Sapporo rubykaigi03

Expectations

class User self.def import! File.open(‘export.csv’).read endend

Page 47: Sapporo rubykaigi03

Expectationsbefore mock(File).open.with_any_args. mock!.read { ‘alice,bob’ }end

it “#impot!” do User.import!. should eq ‘alice,bob’end

Page 48: Sapporo rubykaigi03

webmock

stub_request(:post, "www.example.com"). with(:body => "alice"). to_return(:status => 200)

stub_request(:post, "www.example.com"). to_timeout

Page 49: Sapporo rubykaigi03

mockオブジェクトのインタラクション(使いすぎ注意)

stub機能にフォーカス

Page 50: Sapporo rubykaigi03

細かいテストが可能なシステム

ビジネスロジック DBUI

OS 外部API

テスト

API ORM

テスト テスト テスト テスト

API APIテスト テスト

Page 51: Sapporo rubykaigi03

Test Fixture# wineries.ymlsunnyside:  name: Sunnyside Vineyards  city: Sonoma  state: CA  country: USA

# wines.ymlmerlot:  name: Sunnyside Reserve  year: 2003  family: Merlot  winery: sunnyside

rake db:fixtures:load

Page 52: Sapporo rubykaigi03

harmful

Page 53: Sapporo rubykaigi03

fixture replacement

Page 54: Sapporo rubykaigi03

factory_girlFactoryGirl.define do factory :user do first_name 'John' last_name 'Doe' admin false endend

user = Factory.build(:user)user = Factory.create(:user)

Page 55: Sapporo rubykaigi03

factory_girl

FactoryGirl.sequence :email do |n| "person#{n}@example.com"end

Factory.next :email# => "[email protected]"

Page 56: Sapporo rubykaigi03

MachinistPost.blueprint do author title { "Post #{sn}" } body { "Lorem ipsum..." }end

post = Post.makepost = Post.make!(:body => ‘bob’)

Page 57: Sapporo rubykaigi03

Fabrication

mongodb support

Machinist Mongo

Page 58: Sapporo rubykaigi03

細かいテストが可能なシステム

ビジネスロジック DBUI

OS 外部API

テスト

API ORM

テスト テスト テスト テスト

API APIテスト テスト

Page 59: Sapporo rubykaigi03

Capybara

Page 60: Sapporo rubykaigi03

acceptance test

integration test

end-to-end test

Page 61: Sapporo rubykaigi03

DSLfeature '日記を読む' do background do setup_tdiary end scenario '最新の日記の表示' do visit '/' within('title') do page.should have_content('【日記】') } end within('h1') do page.should have_content('【日記】') end page.should have_css('a[href="update.rb"]')! endend

Page 62: Sapporo rubykaigi03

Selenium Webdriver

Page 63: Sapporo rubykaigi03

RSpec.configure do |config| config.include Capybara, :type => :acceptance

Capybara.register_driver :selenium do |app| Capybara::Driver::Selenium.new(app, :browser => :chrome) end

config.before(:all, :selenium => true) do Capybara.current_driver = :selenium endend

Page 64: Sapporo rubykaigi03

動かないテストを放置しない

http://www.flickr.com/photos/mfp/4186901873

Page 65: Sapporo rubykaigi03

よくある例

•月末をまたいだらテストが落ちる•他の環境で実行すると落ちる•rake spec だと落ちる

Page 66: Sapporo rubykaigi03

Continuous Integration

Page 67: Sapporo rubykaigi03

paralell_tests

Page 68: Sapporo rubykaigi03

% rake parallel:spec/Users/hsbt/.gem/ruby/1.8/gems/parallel_tests-0.4.9/lib/parallel_tests.rb:6: warning: already initialized constant VERSION2 processes for 63 specs, ~ 31 specs per processNo DRb server is running. Running in local process instead ...No DRb server is running. Running in local process instead ................................................................................................................

Page 69: Sapporo rubykaigi03

バグを再現するテストを書いてから直す

Page 70: Sapporo rubykaigi03

テストの高速化とリズム

http://www.ne.jp/asahi/t/wada/articles/Refactoring_and_Test.pdf

Page 71: Sapporo rubykaigi03

実行が0.1sec以上のunit testは全て遅い

Page 72: Sapporo rubykaigi03

Spork

Page 73: Sapporo rubykaigi03

require 'rubygems'require 'spork'

Spork.prefork do ENV["RAILS_ENV"] ||= 'test' require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment')) require 'email_spec' require 'database_cleaner'end

Page 74: Sapporo rubykaigi03

Guard::RSpec/Zentest

Page 75: Sapporo rubykaigi03

spec の更新時に自動実行

Page 76: Sapporo rubykaigi03

Continuous Integration

Page 77: Sapporo rubykaigi03

継続課題

Page 78: Sapporo rubykaigi03

DRY

Page 79: Sapporo rubykaigi03

意図を明確にするコードget_number → number

if not item → unless item

size or count

nil? or empty?

map

flatten

Page 80: Sapporo rubykaigi03

テストコードも同じ

Page 81: Sapporo rubykaigi03

多段ネストやべた書きをやめる

Page 82: Sapporo rubykaigi03

実行が0.1sec以上のunit testは全て遅い

Page 83: Sapporo rubykaigi03

Custom Matchers を使う

RSpec::Matchers.define :be_encoded_sjis do match do |actual| NKF.guess(actual) == NKF::SJIS end

description do "be encoded with Shift_JIS" endend

Page 84: Sapporo rubykaigi03

あまりできてない

Page 85: Sapporo rubykaigi03

継続課題

Page 86: Sapporo rubykaigi03

まとめhsbt が2010年に永和システムマネジメントに入社してから半年間で得られた永和システムマネジメントのテスト事情についてご紹介しました。

Page 87: Sapporo rubykaigi03

まとめ

•テストを書く•テストを書くレイヤーを分割する•動かないテストを放置しない•バグを再現するテストを書いてから直す•DRY

Page 88: Sapporo rubykaigi03

•http://github.com/rspec/rspec•http://github.com/jscruggs/metric_fu•http://github.com/btakita/rr•http://github.com/bblimke/webmock•http://github.com/thoughtbot/factory_girl•http://github.com/notahat/machinist•http://github.com/nmerouze/machinist_mongo•http://github.com/paulelliott/fabrication•http://github.com/jnicklas/capybara•http://code.google.com/p/selenium/•http://hudson-ci.org/•http://github.com/grosser/parallel_tests•http://github.com/timcharper/spork•http://github.com/guard/guard-rspec

Page 89: Sapporo rubykaigi03

Good Ruby Life