ホーム DoRuby rspec で、referer や user_agent 関連の機能もテストしよう

rspec で、referer や user_agent 関連の機能もテストしよう

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

お恥ずかしながら、TDDを行わずにRailsで開発を行い続けてきたred です。最近、自分でも spec を書く用になりました。かなり捗ります。まだの方、お早めに。

自分にとって、spec を覚えるにあたっての最大の難関は、参考になる情報をなかなか見つけられなかった、ということでした。

結局、自分は、プロジェクトメンバの書いたものをコピペ改変することにより覚えました。

もし、独学の方、まわりにspec を書いている方のいない Rails/Ruby プログラマの方、まずはこのブログの記述もしくは下の私のコードを写経してみて、そこから、RSpec on Rails の使い方を調べるのが、導入によろしいかと思います。

=====

これ以下の内容は、下記環境にて動作確認をしています。

  • ruby 1.8.7
  • rails 2.1.0
  • rspec 1.3.0
  • rspec-rails 1.3.2

=====

直近のプロジェクトでは、ユーザエージェントやリファラを見て、それによって LPO を行うナビゲーションを実装していました。

つまりは、下記のような機能を実装しました。勿論、本物はもっと高機能です。

#{RAILS_ROOT}/app/controllers/test_controller.rb

class TestController < ApplicationController

  # リファラより、どの検索エンジンから流入したかを特定
  def referer
    referer = request.env['HTTP_REFERER']
    if referer.blank?
      @engine = "no referer"
    elsif referer.split("?")[0].include? "google"
      @engine = "google"
    elsif referer.split("?")[0].include? "yahoo"
      @engine = "yahoo"
    else
      @engine = "not determined"
    end
    render :text => @engine
  end
 

  # ユーザエージェントより、どのブラウザよりアクセスしているかを特定
  def ua
    ua = request.env['HTTP_USER_AGENT']
    if ua.include? "MSIE"
      @browser = "ie"
    elsif ua.include? "Firefox"
      @browser = "firefox"
    elsif ua.include? "Chrome"
      @browser = "chrome"
    elsif ua.include? "Opera"
      @browser = "opera"
    elsif ua.include? "safari"
      @browser = "safari"
    else
      @browser = "others"
    end
    render :text => @browser
  end

end

上記のようなアプリがうまく動いているか確認する際、通常のブラウザで見ることが不可能な場合は、Live HTTP Headers や User Agent Switcher のようなツールを使い、ユーザエージェントやリファラを詐称してチェックするのがセオリーかと思います。

spec で上記テストを自動化したい場合、下記のように記述すれば実行することができます。

#{RAILS_ROOT}/spec/controllers/test_controller_spec.rb

require 'spec_helper'

describe TestController do
  
  describe "referer" do
    it "google 検索からの流入かどうか判別するテスト" do
      request.env["HTTP_REFERER"] = "http://www.google.co.jp/search?q=test"
      get "referer"
      response.should be_success
      assigns[:engine].should == "google"
    end
    
    it "yahoo 検索からの流入かどうか判別するテスト" do
      request.env["HTTP_REFERER"] = "http://search.yahoo.co.jp/search?p=test"
      get "referer"
      response.should be_success
      assigns[:engine].should == "yahoo"
    end
  end
  
  describe "ua" do
    it "firefox を使っているかどうか判別するテスト" do
      request.env["HTTP_USER_AGENT"] = "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.0.17) Gecko/2009122116 Firefox/3.0.17 GTB6 (.NET CLR 3.5.30729)"
      get "ua"
      response.should be_success
      assigns[:browser].should == "firefox"
    end
    
    it "IE を使っているかどうか判別するテスト" do
      request.env["HTTP_USER_AGENT"] = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
      get "ua"
      response.should be_success
      assigns[:browser].should == "ie"
    end
  end
end

上記のように、get で controller/method にアクセスする前に、request.env の各項目の値を上書きすれば、該当のテストを作成することができます。

dev_machine:rails_root red$ spec spec/controllers/test_controller_spec.rb 
....

Finished in 0.065284 seconds

4 examples, 0 failures
dev_machine:rails_root red$ 

describe や it は配列の each の中での実行も出来るので、テストしたいユーザエージェントやリファラとその結果をDB化しておくことにより、いちいちツールを用いて切り替えることなく、一気にhttp_header 関連のテストが行えるようになりました。

参考:http://stackoverflow.com/questions/542856/how-do-i-set-http-referer-when-testing-in-rails

記事を共有

最近人気な記事