search
LoginSignup
115
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Organization

【動画付き】「プロを目指す人のためのRuby入門」のテストコードをRSpecに書き換える・その1

はじめに

僕が執筆したRubyの入門書「プロを目指す人のためのRuby入門」では、Minitestを使って例題の実行結果をテストしています。
ですが、実際の現場ではMinitestではなく、RSpecを使っている場合も多いと思います。

そこで、この記事では「プロを目指す人のためのRuby入門」のテストコードを、筆者自らRSpecに書き換えてみます。

rubybook-mini.jpg

RSpecをまったく知らない方へ

RSpecの基本は詳しく説明しません。RSpecをまったく知らない、という方は、先に以下の記事を読んでからこの記事に戻ってきてください。

使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 - Qiita
※ただし、「RSpecの高度な機能」の項で説明している知識は今回使いません。

本記事は3部構成になっています

ボリュームが大きいので、本記事は3部構成になっています。
この記事では第3章から第6章までのテストコードをRSpecに書き換えます。

動画とソースコード

この記事の内容は動画(スクリーンキャスト)形式で解説しています。
細かい説明は口頭で話しているので、ぜひ動画もチェックしてください。
(録音状況が悪いため、ときどき大きなノイズが入ります。ごめんなさい🙏)

「プロを目指す人のためのRuby入門」のテストコードをRSpecに書き換える・その1Screen Shot 2018-03-19 at 5.19.53.png

また、ソースコードはこちらにアップしています。

対象バージョン

この記事は以下の環境で動作確認しています。

  • Ruby 2.4.1
  • RSpec 3.7.0

それでは以下が本編です。

セットアップ

gemコマンドを使ってRSpecをインストールします。

$ gem install rspec

テストコードを書きたいプロジェクトのルートディレクトリに移動し、rspec --initコマンドを実行すると、RSpecの実行に必要なファイルやディレクトリが作成されます。

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

.rspecspec_helper.rbはRSpecを実行するための設定ファイルですが、今回はデフォルトのまま使うので説明は割愛します。

コンソールからrspecコマンドを実行し、以下のような結果になればセットアップ完了です。

$ rspec
No examples found.


Finished in 0.00038 seconds (files took 0.67611 seconds to load)
0 examples, 0 failures

セットアップ直後にはテストがありませんが、specディレクトリにテストコードがあれば、テストが実行されます。

第3章 FizzBuzzプログラム

Minitest版

test/fizz_buzz_test.rb
require 'minitest/autorun'
require './lib/fizz_buzz'

class FizzBuzzTest < Minitest::Test
  def test_fizz_buzz
    assert_equal '1', fizz_buzz(1)
    assert_equal '2', fizz_buzz(2)
    assert_equal 'Fizz', fizz_buzz(3)
    assert_equal '4', fizz_buzz(4)
    assert_equal 'Buzz', fizz_buzz(5)
    assert_equal 'Fizz', fizz_buzz(6)
    assert_equal 'Fizz Buzz', fizz_buzz(15)
  end
end

RSpec版

spec/fizz_buzz_spec.rb
require './spec/spec_helper'
require './lib/fizz_buzz'

RSpec.describe 'Fizz Buzz' do
  it 'returns valid string' do
    expect(fizz_buzz(1)).to eq '1'
    expect(fizz_buzz(2)).to eq '2'
    expect(fizz_buzz(3)).to eq 'Fizz'
    expect(fizz_buzz(4)).to eq '4'
    expect(fizz_buzz(5)).to eq 'Buzz'
    expect(fizz_buzz(6)).to eq 'Fizz'
    expect(fizz_buzz(15)).to eq 'Fizz Buzz'
  end
end

ポイント

  • 4行目のRSpec.describeでは、テスト対象のプログラムやクラスを記述します。
  • it 'returns valid string' doの部分では、プログラムの期待する振る舞いを記述しています。この場合は「(テスト対象のメソッドが)正しい文字列を返すこと」という内容になっています。
  • 英語が苦手な人はitに渡す文字列を日本語で書いても構いません(例:it '正しい文字列を返すこと' do)。
  • RSpecのexpect(A).to eq Bは、Minitestのassert_equal B, Aに対応します。

第4章 RGB変換プログラム

Minitest版

test/rgb_test.rb
require 'minitest/autorun'
require './lib/rgb'

class RgbTest < Minitest::Test
  def test_to_hex
    assert_equal '#000000', to_hex(0, 0, 0)
    assert_equal '#ffffff', to_hex(255, 255, 255)
    assert_equal '#043c78', to_hex(4, 60, 120)
  end

  def test_to_ints
    assert_equal [0, 0, 0], to_ints('#000000')
    assert_equal [255, 255, 255], to_ints('#ffffff')
    assert_equal [4, 60, 120], to_ints('#043c78')
  end
end

RSpec版

spec/rgb_spec.rb
require './spec/spec_helper'
require './lib/rgb'

RSpec.describe 'RGB' do
  describe '#to_hex' do
    it 'returns valid string' do
      expect(to_hex(0, 0, 0)).to eq '#000000'
      expect(to_hex(255, 255, 255)).to eq '#ffffff'
      expect(to_hex(4, 60, 120)).to eq '#043c78'
    end
  end

  describe '#to_ints' do
    it 'returns valid array' do
      expect(to_ints('#000000')).to eq [0, 0, 0]
      expect(to_ints('#ffffff')).to eq [255, 255, 255]
      expect(to_ints('#043c78')).to eq [4, 60, 120]
    end
  end
end

ポイント

  • describe '#to_hex' dodescribe '#to_ints' doは、それぞれテストのグループ化をしています。前者は「to_hexメソッドをテストするグループ」で、後者は「to_intsメソッドをテストするグループ」です。

第5章 長さの単位変換プログラム

Minitest版

test/convert_length_test.rb
require 'minitest/autorun'
require './lib/convert_length'

class ConvertLengthTest < Minitest::Test
  def test_convert_length
    assert_equal 39.37, convert_length(1, from: :m, to: :in)
    assert_equal 0.38, convert_length(15, from: :in, to: :m)
    assert_equal 10670.73, convert_length(35000, from: :ft, to: :m)
  end
end

RSpec版

spec/convert_length_spec.rb
require './spec/spec_helper'
require './lib/convert_length'

RSpec.describe 'Convert length' do
  it 'returns valid value' do
    expect(convert_length(1, from: :m, to: :in)).to eq 39.37
    expect(convert_length(15, from: :in, to: :m)).to eq 0.38
    expect(convert_length(35000, from: :ft, to: :m)).to eq 10670.73
  end
end

ポイント

(ここでは特に新しいトピックはありません。)

第6章 ハッシュ記法変換プログラム

Minitest版

test/convert_hash_syntax_test.rb
require 'minitest/autorun'
require './lib/convert_hash_syntax'

class ConvertHashSyntaxTest < Minitest::Test
  def test_convert_hash_syntax
    old_syntax = <<~TEXT
      {
        :name => 'Alice',
        :age=>20,
        :gender  =>  :female
      }
    TEXT
    expected = <<~TEXT
      {
        name: 'Alice',
        age: 20,
        gender: :female
      }
    TEXT
    assert_equal expected, convert_hash_syntax(old_syntax)
  end
end

RSpec版(letを使わない場合)

spec/convert_hash_syntax_spec.rb
require './spec/spec_helper'
require './lib/convert_hash_syntax'

RSpec.describe 'Convert hash syntax' do
  it 'converts old syntax to new syntax' do
    old_syntax = <<~TEXT
      {
        :name => 'Alice',
        :age=>20,
        :gender  =>  :female
      }
    TEXT
    expected = <<~TEXT
      {
        name: 'Alice',
        age: 20,
        gender: :female
      }
    TEXT
    expect(convert_hash_syntax(old_syntax)).to eq expected
  end
end

RSpec版(letを使う場合)

spec/convert_hash_syntax_spec.rb
require './spec/spec_helper'
require './lib/convert_hash_syntax'

RSpec.describe 'Convert hash syntax' do
  let(:old_syntax) do
    <<~TEXT
      {
        :name => 'Alice',
        :age=>20,
        :gender  =>  :female
      }
    TEXT
  end
  let(:expected) do
    <<~TEXT
      {
        name: 'Alice',
        age: 20,
        gender: :female
      }
    TEXT
  end
  it 'converts old syntax to new syntax' do
    expect(convert_hash_syntax(old_syntax)).to eq expected
  end
end

ポイント

  • RSpecではテストコード内に登場するローカル変数やインスタンス変数を、letと呼ばれるコードブロックに移動させることができます。
  • ここではit 'xxx' do ... endの中身をスッキリさせるために、letを使いました。
  • letについては前述の「使えるRSpec入門・その1」でも説明しているので、そちらの説明も参考にしてください。

まとめ

この記事では「プロを目指す人のためのRuby入門」の第2章から第6章までのテストコードをRSpecに書き換えました。
第7章以降のテストコードは第2回、および第3回の記事で書き換えていきます。

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
What you can do with signing up
115
Help us understand the problem. What are the problem?