4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ruby on RailsAdvent Calendar 2017

Day 22

RSpecを実際に書いて体験してみる

Last updated at Posted at 2017-12-21

この記事の目的

RSpecの取っ掛かりとして、簡単なRSpecを書いて実際に実行してみます。流れの中で説明も多少入っていますが、事細かく何を意味しているかなどの説明はあまりしません。あくまでまずRSpecを実行してみる、体験してみるところに重点をおきます。

##今回使用するメソッドの説明

文字列数字を足し算するメソッドを作ってみましょう。メソッドはint Add(string numbers)。

  • メソッドは文字列の数字を引数(例:"1")に取る、カンマ区切りで複数の文字列の数字が取れる(例:"1,2,3")。
  • 空の場合は0を返す

##RSpecを準備する
Gemfileにrspecを追加。bundle installを実行。

Gemfile
source "https://rubygems.org"
...
...
gem "rspec"

そして、specディレクトリ(なければmkdir specで作成)の直下にstring_calculator_spec.rbを作成します。これが今回使用するRSpecのファイルです。

spec/string_calculator_spec.rb
describe StringCalculator do
end

RSpecでは、describeでclass、module、メソッドを記述します。describeブロックはrspecの処理の流れを記述するため、必ず最初に書かれます。

bundle exec rspecでrspecを実行してみます。すると下記のようなエラーが出てくるはずです。

実行結果
スクリーンショット 2017-12-17 3.57.20.png

これはまだStringCalculatorというクラスを作成していないからです。では、StringCalculatorクラスをlibの配下に作成します。

lib/string_calculator.rb
class StringCalculator
end

ここで、rspecのファイルにrequireを追加します。

spec/string_calculator_spec.rb
require "string_calculator"

describe StringCalculator do
end

bundle exec rspecを実行します。

実行結果
スクリーンショット 2017-12-17 4.11.09.png

先ほどのエラーがなくなりました。これでコードを書く準備ができました。

##実際にRSpecを書いてみる

StringCalculatorのaddメソッドは空(empty)を受け入れてます。空を受け取ったら0を返す仕様です。まずはdescribeにaddを追加してみましょう。

spec/string_calculator_spec.rb
require "string_calculator"

describe StringCalculator do

  describe ".add" do
    context "given an empty string" do
      it "returns zero" do
        expect(StringCalculator.add("")).to eql(0)
      end
    end
  end

end
  • クラスメソッドのaddを記述するために、また別のdescribeを使います。そして慣例で、クラスメソッドはドット(.)のprefixを付けて(".add")、インスタンスメソッドにはdash(#)を付けます("#add")。

  • コンテキストブロックではaddメソッドが空だったら0を返すことを記述しています。contextはdescribeと意味的には同じなのですが、コードの可読性を向上させるために使われたりします。

  • itブロックはテストケースを記述するために使います。上記は、addメソッドに空を与えると0を返しますよという例です。

  • 「expect(...).to」や「expect(...).not_to」は期待する(しない)結果を定義します。eqlはイコールの意味です(matcherと呼ぶらしい)。matcherはいろいろな書き方があるようです。参考:https://relishapp.com/rspec/rspec-expectations/v/3-1/docs/built-in-matchers

RSpecを書き終わったら、クラスにaddメソッドを追記しましょう。

lib/string_calculator.rb
class StringCalculator

  def self.add(input)
    0
  end

end

追記後bundle exec rspecを実行します。

実行結果
スクリーンショット 2017-12-17 5.01.03.png

RSpecが通りました。

##1つの数字でaddメソッドをRSpecに通してみる
string_calculator_spec.rbを下記のように書き換えてみましょう。

spec/string_calculator_spec.rb

require "string_calculator"

describe StringCalculator do

  describe ".add" do
    context "given '4'" do
      it "returns 4" do
        expect(StringCalculator.add("4")).to eql(4)
      end
    end

    context "given '10'" do
      it "returns 10" do
        expect(StringCalculator.add("10")).to eql(10)
      end
    end
  end

end

実行してみましょう。

実行結果
スクリーンショット 2017-12-17 12.55.23.png

1つ目のRSpecで期待する値(expected)は4に対して、受け取った結果の値(got)は0だよ、2つ目のRSpecでは期待する値(expected)は10に対して、受け取った結果の値(got)は0だよって書かれています。ゴールはRSpecを通すことなので、RSpecの対象となっているクラス(ここではStringCalculatorクラス)を修正します。

lib/string_calculator.rb

class StringCalculator

  def self.add(input)
    if input.empty?
      0
    else
      input.to_i
    end
  end

end

RSpecを実行してみてください。下記のようになると無事RSpecが通りました。
スクリーンショット 2017-12-17 13.00.59.png

複数の数字でメソッドを試してみる

最後に複数の文字列数字をカンマ区切りで渡した場合(本来のメソッド処理)のケースを試します。

spec/string_calculator_spec.rb

require "string_calculator"

describe StringCalculator do 

  describe ".add" do
    context "two numbers" do
      context "given '3,5'" do
        it "returns 8" do
          expect(StringCalculator.add("3,5")).to eql(8)
        end
      end

      context "given '1000,200'" do
        it "returns 1200" do
          expect(StringCalculator.add("1000,200")).to eql(1200)
        end
      end
    end
  end

end

RSpecを実行しましょう。失敗するはずです。
スクリーンショット 2017-12-17 17.57.41.png

ここで再度StringCalculatorをクラスを修正します。

lib/string_calculator.rb

class StringCalculator

  def self.add(input)
    if input.empty?
      0
    else
      numbers = input.split(",").map { |num| num.to_i }
      numbers.inject(0) { |sum, number| sum + number }
    end
  end

end

RSpecを実行します。

実行結果
スクリーンショット 2017-12-17 18.00.29.png

##おまけ
RSpecはアウトプットの表示方法がいくつかあって、そのうちのひとつにdocumentationフォーマットがあります。やり方は簡単で、

bundle exec rspec --format documentation

とするだけです。

実行結果
スクリーンショット 2017-12-17 18.50.12.png

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?