Hamamatsu.rb#64 のrspecに関する補足事項
Hamamatsu.rb(浜松Ruby) #64 に参加しました
今回は RSpec
の回だったのですが
RSpecの環境構築をしている際に、
と口に挟んでしまい混乱させてしまいました
こちらのコマンドで RSpec の 環境構築をすることについて補足しておきたいと思います
環境等
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
$ bundle -v
Bundler version 1.12.3
$ cat ~/.bundle/config
---
BUNDLE_GEM__COC: false
BUNDLE_GEM__MIT: false
BUNDLE_GEM__TEST: rspec
bundle gem
コマンドとは?
RubyGems
を作るためのコマンドです
Ruby のライブラリの配布形式です
説明は省略しますが、作ったライブラリは bin/rake release
コマンドで RubyGemsサーバーに登録することができます
bundle gem を利用したRSpec環境の構築
以下のコマンドで rspec_example
という gem
を作成します
$ bundle gem rspec_example
以下のようなディレクトリ構造になります
rspec_example
├── Gemfile
├── README.md
├── Rakefile
├── bin
│ ├── console
│ └── setup
├── lib
│ ├── rspec_example
│ │ └── version.rb
│ └── rspec_example.rb
├── rspec_example.gemspec
└── spec
├── rspec_example_spec.rb
└── spec_helper.rb
rspec_example.gemspec の編集
bundle gem
で作成した場合 (オプションを指定しない場合) デフォルトで rspec
がインストールされるように設定されています
通常ですと bundle install
コマンドでそれらのライブラリをインストールできます
しかし、bundle gem
コマンド実行直後に bundle install
コマンドを実行すると以下のようになります
$ bundle install --binstubs
You have one or more invalid gemspecs that need to be fixed.
The gemspec at /Users/kengos/workspace/sandbox/rspec_example/rspec_example.gemspec is not valid.
Please fix this gemspec.
The validation error was '"FIXME" or "TODO" is not a description'
TODO や FIXME が含まれているとエラーがでてしまうようです
rspec_example.gemspec
というファイル を開き以下のように変更します
- spec.summary = %q{TODO: Write a short summary, because Rubygems requires one.}
+ spec.summary = %q{Write a short summary, because Rubygems requires one.}
- spec.description = %q{TODO: Write a longer description or delete this line.}
+ spec.description = %q{Write a longer description or delete this line.}
- spec.homepage = "TODO: Put your gem's website or public repo URL here."
+ spec.homepage = ""
再度 bundle install
を実行すると今度は実行できるはずです
$ bundle install --binstubs
Fetching gem metadata from https://rubygems.org/
Fetching version metadata from https://rubygems.org/
Resolving dependencies...
Using rake 10.5.0
Using bundler 1.12.3
Using diff-lcs 1.2.5
Using rspec-support 3.4.1
Using rspec_example 0.1.0 from source at `.`
Using rspec-core 3.4.4
Using rspec-expectations 3.4.0
Using rspec-mocks 3.4.1
Using rspec 3.4.0
Bundle complete! 4 Gemfile dependencies, 9 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
※実際に 公開用のRubyGemを作成する場合は きちんと TODO
の箇所を設定する必要があります
RSpecの実行
上記では bundle install --binstubs
コマンドでインストールをしました
このコマンドでインストールすると bin
以下に様々なファイルが作成されます
rspec_example/bin
├── bundler
├── console
├── htmldiff
├── ldiff
├── rake
├── rspec
└── setup
bin/rspec
が含まれていますので、実行してみます
$ bin/rspec
RspecExample
has a version number
does something useful (FAILED - 1)
Failures:
1) RspecExample does something useful
Failure/Error: expect(false).to eq(true)
expected: true
got: false
(compared using ==)
# ./spec/rspec_example_spec.rb:9:in `block (2 levels) in top <(required)>'
Finished in 0.01884 seconds (files took 0.12111 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/rspec_example_spec.rb:8 # RspecExample does something useful
上記のようになれば RSpec
の実行環境が整ったことになります
specファイルの修正
インストール直後にサンプルの specファイルが含まれています
このspecは落ちるように記述されています
spec/rspec_example_spec.rb
このファイルを修正します
require 'spec_helper'
describe RspecExample do
it 'has a version number' do
expect(RspecExample::VERSION).not_to be nil
end
it 'does something useful' do
- expect(false).to eq(true)
+ expect(false).to eq(false)
end
end
再度 bin/rspec
を実行します
$ bin/rspec
RspecExample
has a version number
does something useful
Finished in 0.00144 seconds (files took 0.08446 seconds to load)
2 examples, 0 failures
今度は spec が failure にならずに 正しく pass しています
簡単な機能を持ったクラスを作ってみる
テスト対象となる簡単なクラスファイルの作成
lib/rspec_example
以下に my_class.rb
というファイルを作成します
module RspecExample
class MyClass
def sum(*args)
0
end
end
end
こちらのファイルがロードされるように
lib/rspec_example.rb
から require
するようにします
require "rspec_example/version"
+ require "rspec_example/my_class"
module RspecExample
# Your code goes here...
end
specファイルの作成
specファイルには命名規則があり テスト対象の ファイル名 + _spec.rb
とします
この場合 テスト対象が my_class.rb
というファイルですので
spec
以下に my_class_spec.rb
というファイルを作成します
require 'spec_helper'
RSpec.describe RspecExample::MyClass do
describe '#sum' do
subject { described_class.new.sum(1, 2, 3, 4, 5) }
it { is_expected.to eq 15 }
end
end
※ described_class.new
は RspecExample::MyClass.new
を意味します
spec の実行
以下のような実行結果になれば問題ありません
MyClass#sum
のメソッドは 合計を返すように実装されておらず
常に 0
を返すようになっているため、このspecは落ちます
今回は 独自のクラスファイルの追加方法を示したかったので、 このspecがきちんとpassするような実装については省略します
MyClass#sum
をきちんと実装して この spec が落ちないように修正してみてください
$ bin/rspec
RspecExample::MyClass
#sum
should eq 15 (FAILED - 1)
RspecExample
has a version number
does something useful
Failures:
1) RspecExample::MyClass#sum should eq 15
Failure/Error: it { is_expected.to eq 15 }
expected: 15
got: 0
(compared using ==)
# ./spec/my_class_spec.rb:6:in `block (3 levels) in <top (required)>'
Finished in 0.02232 seconds (files took 0.1487 seconds to load)
3 examples, 1 failure
Failed examples:
rspec ./spec/my_class_spec.rb:6 # RspecExample::MyClass#sum should eq 15