Rubyでテストコードの作成
はじめに
Rubyでテストコードのお試しをしました。
Rubyでのテスティングフレームワークは何種類かあります。
以下あたりが人気っぽいです。
- RSpec
- Minitest
今回はRSpecを選びました。
選ぶ基準はここを参考にさせていただきました。(情報量の多さとか使われている多さ等々)
今読んでいるパーフェクトRubyではRubyに同梱されているtest-unitの説明のみだったため、
RSpecで書いてみた内容をメモして置きます。
RSpec導入
Rubyでの導入は簡単です。
というか前回のCLIアプリケーションにも導入しています。
前回の記事の通り以下の初期実行にてテスティングフレームをRSpecを選択していれば -t オプションをつけたときに勝手に入ります。
bundle gem sample -b -t
もしここでRSpecを選んでなかったよって人は以下で導入できます。
bundle gem sample -b -t rspec
このコマンド後RSpecの設定ファイル(.rspecとspec/spec_helper.rb)も作成されてます。
途中からって人は多分.gemspecに書くとかすればいける気しますが、試してません。
またテストコードも一部自動で作成済みです。
spec/sample_spec.rbはlib/sample.rbに対するテストコードで、バージョンがnilでないこととfalseがtrueであることを確認しています。
RSpec.describe Sample do it "has a version number" do expect(Sample::VERSION).not_to be nil end it "does something useful" do expect(false).to eq(true) end end
テストコードの実行
試しにこの状態ままで実行してみます。
実行のコマンドと実行結果は以下です。
$ bundle exec rspec Sample has a version number does something useful (FAILED - 1) Failures: 1) Sample does something useful Failure/Error: expect(false).to eq(true) expected: true got: false (compared using ==) # ./spec/sample_spec.rb:7:in `block (2 levels) in <top (required)>' Finished in 0.04696 seconds (files took 0.40854 seconds to load) 2 examples, 1 failure Failed examples: rspec ./spec/sample_spec.rb:6 # Sample does something useful
もちろん後者は失敗しました。
テストの作成
続いてはテストを自分で作成してみます。
前回CLIアプリケーションのお試しで作ったSampleプロジェクトを使います。
Thor部分はテストし辛いので少しソースをいじります。
lib/sample/cli.rbを以下のように修正します。
require "sample" require "thor" +require "sample/greeting" module Sample class Cli < Thor desc "hello {name}", "Hello {name}!" def hello(name) - puts "Hello #{name}!" + puts_str = Sample::Greeting.hello_create(name) + puts puts_str end end end
lib/sample/greeting.rbを作成します。
require "sample" module Sample class Greeting def self.hello_create(name) "Hello #{name}!" end end end
見てわかるとおり挙動は変えてません。
テストするためだけにGreetingクラスを作成しました。
このGreetingクラスに対するテストコードを書きます。
rspec/sample/greeting_spec.rbを作成します。
このコードはhello_createメソッドの挙動を確認しています。最後だけわざと失敗するように作成しました。
require "sample/greeting" RSpec.describe Sample::Greeting do it "return Hello Tanaka!" do expect(Sample::Greeting.hello_create("Tanaka")).to eq("Hello Tanaka!") end it "return Hello 田中!" do expect(Sample::Greeting.hello_create("田中")).to eq("Hello 田中!") end it "test failed" do expect(Sample::Greeting.hello_create("山田")).to eq("Hello 田中!") end end
テストを実行してみます。
新たに作成したテストが追加で実行できていることが確認できると思います。
$ bundle exec rspec Sample::Greeting return Hello Tanaka! return Hello 田中! test failed (FAILED - 1) Sample has a version number does something useful (FAILED - 2) Failures: 1) Sample::Greeting test failed Failure/Error: expect(Sample::Greeting.hello_create("山田")).to eq("Hello 田中!") expected: "Hello 田中!" got: "Hello 山田!" (compared using ==) # ./spec/sample/greeting_spec.rb:12:in `block (2 levels) in <top (required)>' 2) Sample does something useful Failure/Error: expect(false).to eq(true) expected: true got: false (compared using ==) # ./spec/sample_spec.rb:7:in `block (2 levels) in <top (required)>' Finished in 0.05989 seconds (files took 0.43274 seconds to load) 5 examples, 2 failures Failed examples: rspec ./spec/sample/greeting_spec.rb:11 # Sample::Greeting test failed rspec ./spec/sample_spec.rb:6 # Sample does something useful
今回のテストコードはものすごい基本的な文字列確認ですが、RSpecで提供されているメソッドをいろいろ使えば柔軟にテストを書くことができると思います。