モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)
目次目次を開く/閉じる

rspecの基本的な使い方 (ruby/sinatraを含む)

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

公開日公開日
2014/10/05
最終更新最終更新
2017/02/10
記事区分記事区分
一般公開

目次

    アカウント プロフィール画像 (サイドバー)

    量子コンピューティングの可能性を探る研究者もどき

    0
    ステッカーを贈るとは?

    他の言語と同様にrubyにも様々なテストツールがありますが、その中でも特にrspecというテストツールについて使用方法を記載します。rspecのバージョンは3.1を想定しています。本ページの内容を越えるものは、以下の公式ページをご参照ください。

    インストール

    $ gem install rspec -v 3.1
    $ gem list | grep rspec
    rspec (3.1.0)
    rspec-core (3.1.5)
    rspec-expectations (3.1.2)
    rspec-mocks (3.1.2)
    rspec-support (3.1.1)
    

    初期設定

    GEMパッケージをインストールするとrspecコマンドが使用できるようになります。rspecコマンドを使用して、設定ファイルなどを自動生成しましょう。

    $ rspec --init
      create   .rspec
      create   spec/spec_helper.rb
    

    .rspec

    rspecコマンドを実行する際に自動で付与される引数を記述できるファイルです。

    --color
    --format documentation
    --require spec_helper
    

    などとしておくとよいです。それぞれの意味については

    $ rspec --help
    

    を参照してください。

    spec/spec_helper.rb

    テスト時に自動で読み込まれるファイルです。各テストにおいて共通の処理があればこのファイルに記述します。

    テストコードの例

    sample.rb

    class MyStack
      def initialize
        @arr = []
      end
    
      def push(val)
        raise if val.nil?
        @arr.push(val)
        return val
      end
    
      def pop
        @arr.pop
      end
    
      def size
        @arr.size
      end
    end
    

    spec/sample_spec.rb

    require './sample'
    
    RSpec.describe MyStack do
    
      subject { @stack }  # ← subject (和訳:テストされる者)
      before(:example) do   # ← それぞれの 'example' (itブロック) の前で実行される
        @stack = MyStack.new  # (「before(:each) do」としても同じ意味。エイリアス)
      end
    
      describe "#push" do
        context "in 正常系" do
          it { expect(subject.push(123)).to eq 123 }
          it { expect(subject.push('value1')).to eq 'value1' }
          it { expect(subject.push(false)).to eq false }
          it { expect(subject.push([])).to eq [] }
          it { expect(subject.push([])).to be_empty } # としても同じ
        end
        context "in 異常系" do
          it { expect { subject.push(nil) }.to raise_error }
        end
      end
    
      describe "#pop" do
        context "in 正常系" do
          context "スタックが空の場合" do
            it { expect(subject.pop).to be_nil }
          end
          context "スタックに値がある場合" do
            before do
              subject.push 'value1'
              subject.push 'value2'
            end
            it { expect(subject.pop).to eq 'value2' }
            it {
              subject.pop
              expect(subject.pop).to eq('value1')
            }
          end
        end
        context "in 異常系" do
          it { expect { subject.pop('arg') }.to raise_error ArgumentError }
        end
      end
    
      describe "#size" do
        context "in 正常系" do
          it { expect(subject.size).to eq 0 }
          it {
            subject.push('value')
            expect(subject.size).to eq(1)
          }
        end
        context "in 異常系" do
          it { expect { subject.size('arg') }.to raise_error ArgumentError }
        end
      end
    end
    

    実行方法

    $ rspec   ← spec/* のすべてのテストを実行
    (or $ rspec spec/sample_spec.rb)   ← 特定のspecファイルのみを実行
    

    実行結果例

    MyStack
      #push
        in 正常系
          should eq 123
          should eq "value1"
          should eq false
          should eq []
          should be empty
        in 異常系
          should raise Exception
      #pop
        in 正常系
          スタックが空の場合
            should be nil
          スタックに値がある場合
            should eq "value2"
            should eq "value1"
        in 異常系
          should raise ArgumentError
      #size
        in 正常系
          should eq 0
          should eq 1
        in 異常系
          should raise ArgumentError
    
    Finished in 0.006 seconds (files took 0.24701 seconds to load)
    13 examples, 0 failures
    

    Mockとは何か

    "Mock" という英単語には "物まね" や "偽物の" といった意味があります。rspecにおけるMockという仕組みを使用すると、あたかもあるクラスのオブジェクトであるかのような「もの」を用意できます。その「もの」に未実装のクラスの物まねを覚えさせることによって、未実装のクラスの存在を前提としたテストコードが記述できます。これによって、ある未実装のクラスに依存した実装済みのクラスのテストを、未実装のクラスの実装を待たずに行うといったことが可能になります。ここで記載する内容を越えるものは公式ページをご参照ください。

    用語

    rspecのMockという仕組みの中では以下のような用語が登場します。

    • double : この英単語には実は「代役、影武者」といった意味があります。物まねを覚える「もの」です。何らかのクラスの代役を務めます
    • stub : 仕様書に記載された名前と型を持つ。実際には何もしない関数など。rspec v3.1 においては以前ほど明示的には登場せず、ここに記載のあるように Old syntax 扱いのものが存在します

    テストコードの例

    全くの未実装の場合

    mymock1_spec.rb

    RSpec.describe "Unimplemented Class" do
    
      subject { @unimplemented }
      before(:example) do
        @unimplemented = double("unimplemented")
      end
    
      describe "#unimplemented_method" do
        it {
          allow(subject).to receive(:unimplemented_method).and_return('value')
          expect(subject.unimplemented_method).to eq('value')
        }
      end
    end
    

    実行例

    $ rspec spec/mymock1_spec.rb
    
    Unimplemented Class
      #unimplemented_method
        should eq "value"
    
    Finished in 0.012 seconds (files took 0.24701 seconds to load)
    1 example, 0 failures
    

    一部実装済みの場合

    mymock2_spec.rb

    class User
      def initialize(name)
        @name = name
      end
      attr_accessor :name
    end
    
    RSpec.describe User do
      subject { @user }
      before(:example) do
        @user = User.new('sample name')
      end
    
      describe "#unimplemented_method" do
        it {
          allow(subject).to receive(:unimplemented_method).and_return('value')
          expect(subject.unimplemented_method).to eq('value')
        }
      end
    end
    

    実行例

    $ rspec spec/mymock2_spec.rb
    
    User
      #unimplemented_method
        should eq "value"
    
    Finished in 0.012 seconds (files took 0.23501 seconds to load)
    1 example, 0 failures
    

    (参考) Sinatraでrspecを使用する場合

    rubyの軽量WebフレームワークであるSinatraにおいて、その本体アプリケーションファイルをrspecでテストする場合に必要となる事項について記載します。

    初期設定

    Sinatraのための初期設定として "Rack::Test::Methods" のincludeが追加で必要になります。この処理は複数のテストで必要になることが多いため、共通の処理として "spec/spec_helper.rb" に記述しておきましょう。

    spec/spec_helper.rb

    RSpec.configure do |config|
      config.include Rack::Test::Methods
    end
    

    テストコード

    「Hello World」と表示するだけのsinatraの本体アプリケーション "helloworld.rb" があるとします。これをテストするためには、ファイル "spec/helloworld_spec.rb" を作成し内容を以下のようにします。

    spec/helloworld_spec.rb

    ENV['RACK_ENV'] = 'production'
    
    # Sinatra本体アプリケーションを読み込む
    require './helloworld'
    
    describe 'HelloWorld Application' do
    
      # Rack::Testのために必要な設定
      def app
        Sinatra::Application
      end
    
      it "トップページにアクセスすると 'Hello World' と表示される" do
        get '/'
        expect(last_response).to be_ok
        expect(last_response.body).to eq('Hello World')
      end
    end
    

    HTTPメソッド

    get, post, put, delete, head が使用できます。各メソッドには引数が指定できます。例えばgetの場合は以下のようになります。

    $ get '/path', params={}, rack_env={}
    
    • /path : リクエストパスです。いわゆるクエリストリングでパラメータを指定することもできます
    • params={} : postやgetで指定するパラメータをハッシュ形式またはクエリストリング形式で記述できます
    • rack_env={} : rackの環境変数をハッシュ形式で指定できます。指定できる項目はこちらです。「rack.session」などが指定できます

    レスポンス

    HTTPメソッドを実行したあとは

    • last_request : 実際に実行されたHTTPリクエスト
    • last_response : HTTPレスポンス

    が使用できます。例えば

    • last_response.headers['Content-Length']
    • last_response.body

    といった値をテストで利用できるようになります。

    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    量子コンピューティングの可能性を探る研究者もどき

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      関連記事

      • レイアウトおよび部分テンプレートに関するまとめ (Rails4)
        レイアウトおよび部分テンプレートはどちらもテンプレート (*.html.erb) に共通の要素をまとめておき、任意のテンプレートから利用できるようにしておくための仕組みです。フッターやヘッダーといった大枠はレイアウト、小さなパーツは部分テンプレートというイメージで使い分けましょう。 レイアウトの使用方法 クラス毎に指定する方法と、アクション毎に指定する方法があります。 app/views/layo...
        taro三世taro三世10/21/2016に更新
        いいねアイコン画像0
      • Ruby コードスニペット (正規表現)
        sample.rb str = "001: This is a string." var1,var2 = 2,3 # 'EOS'とすると#{}による変数展開がなされない (%03dは展開される) doc = (<<"EOS" % var1) # 括弧は省略可。要は<<"EOS"の次の行からEOSまで。(参: <<-"EOS"とすると前に空白...
        だいふくうさぎだいふくうさぎ5/13/2018に更新
        いいねアイコン画像0
      • OAuthを用いずにTwitterに自動投稿する (回数制限あり, Selenium with Ruby)
        Seleniumを用いて、OAuthを用いずにTwitterに自動投稿するRubyスクリプトを記述してみます。連続で複数回実行すると、ボット判定としてキャプチャ認証が発生します。その認証までは通過できませんので悪しからず。また、Twitterの仕様変更次第ではDOMの構造が変化するため、下記サンプルは機能しなくなる恐れが有ります。 twitter_post.rb #!/usr/bin/ruby r...
      • Ruby における日本語のエンコーディング
        日本語を含めて多言語対応する際には、Asciiコード以外の文字コードセットが必要になります。日本語が主となる場合、よく使われる文字セットにはUnicode, Shift_JIS, EUC-JPがあります。このうち Unicode だけは特殊であり、世界中のあらゆる文字を収録しようとしていることから 1 文字を表現するために必要なバイト数が大きくなってしまっています。そのため Unicode のうち...
        だいふくうさぎだいふくうさぎ4/21/2017に更新
        いいねアイコン画像0
      • Rails3ビューテンプレートの基本的な使用方法 (Ruby)
        Railsでは、ERB (eRuby (テキストファイルにRubyスクリプトを埋込む書式の仕様) をRubyで実装したもの) を用いてHTML内にRubyスクリプトを埋込むことができます。 <% %> で囲むと出力されません (if-elseなど制御構文を記述します) <%= %> で囲むとエスケープ出力されます <%== %> で囲むとエスケープされずに...
        ほんわかパンダほんわかパンダ10/21/2016に更新
        いいねアイコン画像0