Ruby Tests

Page content

Ruby テスト

シンプルに ruby プログラムのテスト, APIのテスト, html のテスト, sinatra 固有, rack アプリ固有, rails 固有のテスト, javascript も動作させる? web ブラウザでのテスト? 色々有りますよね。

Ruby 標準ライブラリのテスティングフレームワーク: Minitest or Test::Unit

この記事 が Minitest と Test::Unit について説明してくれています。 Ruby のバージョンによって片方のあるバージョンが標準バンドルされているんだけど、何度か行ったり来たりしているみたい。 ruby2.1.0 のころは Test::Unit だったようだけど、 2.5.0 あたりだと両方あるっぽい?

RSpec

多分、最もポピュラーなテスティングフレームワーク。 こういうところ で勉強してから使う。

  • spec ファイルの例: map-e_spec.rb
    require 'spec_helper'
    require 'rspec/its'
    require 'map-e'
    
    describe MapE do  # class名
      let(:provider_params) do
        {
          net6: '2001:db8::/30',
          net4: '198.32.0.0/12',
          rsv_port: 1024,
          user_pref6_len: 56,
          is_rfc: false
        }
      end
      let(:map) { MapE.new(provider_params) }
    
      describe 'checking sanity of provider-level map info' do
        it 'should provide appropriate EA bit length' do
          expect(map.ea_bit_len).to eq 26
        end
        it 'should provide appropriate ports from PSID' do
          expect(map.psid_to_ports(0).size).to eq map.ports_per_user
        end
      end
      describe 'checking mapping of IPv4+Port <-> IPv6' do
        it 'should provide mapping: IPv4+Port --> IPv6' do
          expect(map.pref4_to_pref6(pref4: '198.47.255.255', port: 2032)).to eq '2001:dbb:ffff:ff00:c6:2fff:ff07:f000'
        end
        it 'should provide mapping: IPv6 --> IPv4+Port' do
          expect(map.pref6_to_pref4('2001:dbb:ffff:ff00:c6:2fff:ff07:f000')).to eq(pref4: '198.47.255.255', port: 2032)
        end
      end
    end
    
  • テストの実行例:
    $ bundle exec rspec spec/lib/map-e_spec.rb
    .....
    
    Finished in 0.01201 seconds (files took 0.23161 seconds to load)
    5 examples, 0 failures
    

Rack::Test で Sinatra アプリの web API をテスト

Capybara

ユーザのブラウジング動作をテストする ライブラリ. E2E テストが主なターゲットかな. 詳細は Capybara の README.mdその日本語版 を見よう.

使えそうなシーン:

  • ページに期待するコンテンツが表示されること
  • フォームを埋めてボタンを押して、遷移後のページのコンテンツをテストする
  • Ajax や Javascript 対応は色々追加が必要そうでちょっと重た目なので、一旦放置
  • API のテストには使うなとのこと. 例えばここ とか ここ で言われています

勉強仕方:

Guard でテストの自動化

Guard はファイルの変更を検知し、任意のタスクを自動実行する。 guard-rspec で rspec のテストをファイル変更に応じて実行する。

  1. Gemfile に以下を追加
group :development, :test do
 gem 'guard'
 gem 'guard-rspec'
end
  1. guard, guard-rspec をインストール
bundle install --path=.bundle
bundle exec guard init rspec
  1. Guardfile で変更を watch したいファイルを指定する。例えば以下のようにする。
guard :rspec do
  watch(%r{^spec/.+_spec\.rb$})
  watch(%r{^lib/(.+)\.rb$})     { |m| "spec/lib/#{m[1]}_spec.rb" }
  watch('spec/spec_helper.rb')  { "spec" }
end
  1. guard を起動するには以下
bundle exec guard start
  1. watch しているファイルが保存されるたびにそのファイルを対象とした rspec が実行されます。 Enter を押せば全 rspec を実行してくれます

SimpleCov でテスト網羅性の可視化

テストのカバレッジが分かるよ!

  1. Gemfile に以下を追加
group :development, :test do
 gem 'simplecov'
end
  1. インストール
bundle install --path=.bundle
  1. spec/spec_helper.rb の先頭に追記。 add_filter で除外したいディレクトリなど指定可能。
require 'simplecov'
SimpleCov.start do
  add_filter '/.bundle/'
end
  1. テストを実行する。するとプロジェクトディレクトリ直下に coverage というディレクトリが出来る。
  2. 配下の index.html を開けば、各ファイルごとのカバレッジがパーセンテージ表示されるのと、各ファイルを開けばテストされた・されなかった場所が一目瞭然!