æè¿ãã£ã¦ãRailsããã¸ã§ã¯ãã®ãã¹ãæ¹æ³
Railsã¨ã³ã¸ãã¢ã«ãªã£ã¦ãã1å¹´åããããçµã¡ã社å ã®Railsã®ããã¸ã§ã¯ããå ¨é¨ã§5ã¤ããã触ã£ã¦ãä»ãã£ã¦ãAbilie*1ã§ãããã人並ã¿ã«ãã¹ããæ¸ãã¦ãæ°ããã¦ããã®ã§ãç¾æç¹ã§ãã£ã¦ããã¹ãã®æ¹æ³ãã¾ã¨ãã¦ããã
ãã¹ãã®ã«ã¼ã«çãªã®
rspecã§ã¯å¿
ãã¢ãã«ã®ãã¹ãã¯æ¸ãããã«ãã¦ãããã«ãã¼ã大ä½æ¸ãã¦ããã©ãã³ã³ããã¼ã©ãã«ã¼ãã£ã³ã°ã®ãã¹ãã¯ãã¾ãæ¸ãã¦ãªãã
ã¨ããã®ããã³ã³ããã¼ã©ã¼ã®ã³ã¼ãã極åçããã¦ã¢ãã«ã太ããã¦ããã®ã§ã³ã³ããã¼ã©ã®ãã¹ãã¯ããã¾ãæå³ãç¡ãæ°ããã¦ãã¦ããã®ä»£ããã«Capybaraã§ãã¹ããæ¸ãã¦ããã°ååãªããããªãããªã¨æã£ã¦ãããããCapybaraã¯æ¸ãã¦ãã®ã§ãããããæå³ã§ã¯æ¸ãã¦ãã¨ãè¨ããã
社å
ã®ç®¡çè
ã ãã使ãã管çç»é¢ãä½ã£ã¦ããã©ããã£ã¡ã¯ãã¹ãããã¾ãæ¸ãã¦ãªããããã¯åããªããªã£ã¦ãä¸è¬ã¦ã¼ã¶ã¼ã«ã¯å½±é¿ãç¡ãã®ã§ãåããªããªã£ãã®ãæ°ã¥ãã¦ããç´ãã°ããããªã¼ã¨ããæãã
ãã¹ãã®å®è¡
Guardã¨Sporkãçµã¿åããã¦ä½¿ããçµæãGrowlã§åºåãã¦ã
guard/guard · GitHub
guard/guard-spork · GitHub
Guardã¯ãã¡ã¤ã«ã«å¤æ´ããã£ãããªã«ããã¦ããããã®ã
Sporkã¯äºåã«Railsã®ã³ã¼ããäºåã«èªã¿è¾¼ãã§ããã¦rspecã®èµ·åæéãç縮ãã¦ãããã
Growlã¯Macã ã£ããã¿ããªä½¿ã£ã¦ãã¢ã¬ã§ãããæè¿ææã«ãªãã¾ããããä¼ç¤¾ã« #éãã ã£ã¦è¨ã£ããè²·ã£ã¦ããã¾ããã
Guardã«é¢ãã¦ç´¹ä»ãã¦ãããã°ã¨ãèªãã¨ãguardãèµ·åæã«å
¨ä½ã®ãã¹ããæµããã¢ãã«ãªã©ã®ãã¹ããéã£ããã¾ãå
¨ä½ã®ãã¹ããæµãããã«è¨å®ãã¦ãããã©ãå
¨ä½ãã¹ããæµããã¨æéããããã®ã§è¨å®ãç¡å¹åãã¦ã
Guardfileã以ä¸ã®ããã«æ¸ãã°ããã
guard 'rspec', :version => 2, :cli => "--drb", :all_after_pass => false, :all_on_start => false do
å ¨ä½ãã¹ããå®è¡ããããªã£ãããguardãåãã¦ãæã§Enterãæ¼ãã°åãã
fixture_replacement
factory_girlã§ç¹ã«å°ã£ã¦ããªãã®ã§ç¸å¤ãããfactory_girlã使ã£ã¦ãã
thoughtbot/factory_girl · GitHub
modelãä½æããã¨ãã«factory_girlã®ãã¡ã¤ã«ãçæããããã«config/application.rbã«ä»¥ä¸ã®ããã«æ¸ãã¦ã
config.generators do |g| g.test_framework :rspec, :fixture => true, :fixture_replacement => :factory_girl g.fixture_replacement :factory_girl, :dir => 'spec/factories' end
ãã¨Sporkãå®è¡ãã¦ãã¨ãfactory_girlã®ãã¡ã¤ã«ã«å¤æ´ããã£ã¦ãæ´æ°ãã¦ãããªãã®ã§ãspec_helper.rbã«ä»¥ä¸ã®ããã«æ¸ãã¦ãã
Spork.each_run do FactoryGirl.reload Deadend::Application.reload_routes! end
ã«ãã¬ãã¸
åå¹´ãããåã¯cover_meã使ã£ã¦ããã©ãæè¿ã¯simple-covã使ã£ã¦ãã
colszowka/simplecov · GitHub
åºåãããã«ãã¬ãã¸çµæã®HTMLã綺éºãªã®ã¨ãrcovå½¢å¼ã§åºåã§ãã¦Jenkinsã§ã使ããã®ãè¯ãã
Sporkã§å®è¡ãããå ´åã¯ä½ãå¤ã«ãªãã®ã§ãSporkã使ã£ã¦ãæã¯å®è¡ããªãããã«ãã¦ãã
ãã¨ãã¼ã«ã«ã§rake specããã¨ãã¯ããã©ã«ãã®åºåããCIã§å®è¡ããå ´åã«ã¯rcovå½¢å¼ã§åºåã§ããããã«spec_helper.rbã«ä»¥ä¸ã®ããã«æ¸ãã¦ãã
unless Spork.using_spork? require 'simplecov' if ENV["JENKINS"] == 'on' require 'simplecov-rcov' SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter end SimpleCov.start 'rails' do add_filter "/spec/" end end
Redisã®ãã¹ã
resqueã使ã£ã¦ãã¨ããã®ããããããã¸ã§ã¯ãã§Redisã使ã£ã¦ããã®ã§ãã®ãã¹ããæ¸ãããã
RSpec and Resque · defunkt/resque Wiki · GitHub
resqueã®Wikiãåèã«ããã¹ãå®è¡æã«redisã®confãã¡ã¤ã«ä½ã£ã¦redisãèµ·åãããã¹ããå®äºå¾ã«ããã»ã¹ãè½ã¨ãã¦ãã³ããã¡ã¤ã«ãæ¶ãã¦ãã
Jenkinsã§åããå ´åã«ãã¾ãåããªãã£ãã®ã§ãã®é¨åã ãTempFileã使ãããã«ãã¦ãã
REDIS_PID = "#{Rails.root}/tmp/pids/redis-test.pid" REDIS_CACHE_PATH = "#{Rails.root}/tmp/cache/" config.before(:suite) do redis_options = { "daemonize" => 'yes', "pidfile" => REDIS_PID, "port" => 9736, "timeout" => 300, "save 900" => 1, "save 300" => 1, "save 60" => 10000, "dbfilename" => "dump.rdb", "dir" => REDIS_CACHE_PATH, "loglevel" => "debug", "logfile" => "stdout", "databases" => 16 }.map { |k, v| "#{k} #{v}" } if ENV["JENKINS"] == 'on' require 'tempfile' temp = Tempfile::new("redis_temp.conf", REDIS_CACHE_PATH) redis_options.each do |value| temp.puts(value) end temp.close Subexec.run("redis-server #{temp.path}") else redis_options = redis_options.join("\n") `echo '#{redis_options}' | redis-server -` end end config.after(:suite) do %x{ cat #{REDIS_PID} | xargs kill -QUIT rm -f #{REDIS_CACHE_PATH}dump.rdb } end
WebAPIã®ãã¹ã
ããã§è¨ãWebAPIã®ãã¹ãã¨ã¯ãå¤é¨ã®WebAPI(twitterã¨ã)ã使ãå ´åã®ãã¹ãã®ãã¨ã
ããã¯webmockã¨ããgemã使ãã°è¯ãã
bblimke/webmock · GitHub
ãã ãwebmockã使ã£ã¦ãã¾ãã¨Capybaraãlocalhostã«ã¢ã¯ã»ã¹ããã¨ãã«ããã¹ã¦mockãè¿ã£ã¦ãã¦ãã¾ãã®ã§ãlocalhostãé¤å¤ããããã«ãã
spec_helper.rbã«ä»¥ä¸ã®ããã«æ¸ã
WebMock.disable_net_connect!(:allow_localhost => true)
Javascriptã®ãã¹ã
Capybara-Webkitã使ã£ã¦ãã
thoughtbot/capybara-webkit · GitHub
ä»ã®ã¨ãããããªç¹æ®ãªJavascriptãæ¸ãã¦ãããã§ã¯ãªããã»ã¨ãã©jQueryã«é ¼ã£ããã®ãªã®ã§ããã§ååéã«åã£ã¦ãã
ãã ãé£ã®äººããJSã®ã«ãã¬ãã¸ãè¦ããã¨ããè¦æãåºã¦ãã®ã§ãpoltergeistã使ã£ãã»ããè¯ãã®ãããããªãã
jonleighton/poltergeist · GitHub
ãã¨Capybara-Webkitã¯rspecã¨ã¯å¥ã®ã¹ã¬ããã§åãããããfactory_girlã§ä½ã£ããã¼ã¿ãCapybaraå´ã§èªããªãã
Capybaraã®githubã§ActiveRecordã®shared_connectionãå¤ããæ¹æ³ãç´¹ä»ããã¦ããã©ããªãããã¾ãè¡ããªãã£ãã®ã§DatabaseCleanerã使ãæ¹æ³ãã¨ã£ã¦ãã
JSã®ãã¹ã以å¤ã¯å¾æ¥ã®transactionã使ã£ã¦ãã¼ã¿ãæ¶ããJSã®æã¯truncateãå
¨ãã¼ãã«ã«ããæ¹æ³ã«ãã¦ãã
Capybara.javascript_driver = :webkit config.before :each do if Capybara.current_driver == :rack_test DatabaseCleaner.strategy = :transaction DatabaseCleaner.start else DatabaseCleaner.strategy = :truncation end end config.after :each do DatabaseCleaner.clean end
ç»åã®ãã¹ã
ç»åé¢é£ã¯CarrierWaveã使ã£ã¦ããã ãã©ãfactory_girlã§ä½ããã¦ãã¾ãã®ã§ãã¹ããçµãã£ãå¾ã«æ¶ãã¦ãããã¨ãã¹ãã®å ´åã¯é常ã¨ã¯éããã£ã¬ã¯ããªã«æ¸ãåºãã¦ãã
ç¶ç¶çã¤ã³ãã°ã¬ã¼ã·ã§ã³
Jenkinsã使ã£ã¦gitã«pushãããããã¹ããå®è¡ãã¦ããããã¨ã¯å¥ã«æ8æããã«ãæµãã¦ãã
simplecov-rcovã¨ci_reporterã使ã£ã¦ãã«ãã¬ãã¸ã¨ãã¹ãæ°ã®æ¨ç§»ãã°ã©ãã§åºãã¦ãã
ã¾ããã¹ãã«éã£ãããèªåçã«ç¤¾å
ã®æ¤è¨¼ç°å¢ã«ãããã¤ãããããã«ããã«ããã¤ãã©ã¤ã³ã®è¨å®ããã¦ãã
Abilieã«é¢ãã¦ã¯ã¾ã ãªãªã¼ã¹ããã¦ãªãã®ã§ãJenkinsã試é¨çã«ç¤¾å
ã®ãµã¼ãã«å
¥ãã¦ãã ãã§ãæ¬çªã¸ã®ãããã¤ã¨ãã¯ãããã©ããããããªãã
ã¾ã Jenkinsã¯ä½¿ãå§ããã°ããã§ãã¾ãããã£ã¦ãªããã©ãrails_best_practiceã¨ããçµã¿è¾¼ããã¨ããããªã¨æã£ãããã¦ãã
ãããã«
å
¥ç¤¾ããç´å¾ã«å¼ãç¶ãã ããã¸ã§ã¯ãã¯ãã¹ããç¡ãããã¼ã ã«ãã¹ããæ¸ãæåããªããæ¥åã§ã¡ããã¨ãã¹ããæ¸ãããã¨ããªãã£ãã¼ãã§ãããå
¥ç¤¾åå¹´å¾ããããããã¹ããæ¸ãå§ããå°ããã¤ãã¹ããæ¸ãæåãã§ãã¦ãã¦ããã£ãããªã¨ã
ã¨ã¯è¨ã£ã¦ãåã®æ
å½ãã¦ãããã¸ã§ã¯ã以å¤ã¯ç¸å¤ããããã¹ããæ¸ããã¦ãªããã®ãå¤ãã®ã§ããã®ããããä»å¹´ã®èª²é¡ãªæ°ã¯ãã¦ãã
*1:詳ããã¯http://d.hatena.ne.jp/tohae/20111222/1324533072