RailsじゃないRspec3環境を構築する方法

[RSpecの入門とその一歩先へ ～RSpec 3バージョン～ - Qiita](http://qiita.com/jnchito/items/624f6d5023c279046a1c) の記事とかを見ていると、
Rspecの勉強をしようと意気込んで、試そうと思っても **Rails** じゃない **Rspec** の環境ってどうするんだっけ。。と環境構築の部分で第一の障壁が来ると思います。。。
Railsのエコシステムの中で普段開発している方などには結構、**あるある** な気がする。
毎回ググって複数のサイト見てやっていたことだったので自分のためにもまとめたいと思います。

### 前提

- Bundlerベースでrspecはインストールするので、`bundler` はが入っていることを前提とします。


### 1. 適当な作業用ディレクトリ(rspec_test)を作って移動します。

```
% mkdir rspec_test
% cd rspec_test
```


### 2. `bundler` を初期化してrspecをインストールします

```bash:initを実行して初期化
% bundle init
```

Gemfileが生成されるので以下のとおり修正します。

```diff:Gemfile
# A sample Gemfile
source "https://rubygems.org"

- #gem "rails"
+ gem "rspec", ">= 3.0.0"
```

```bash:bundleでrspec3をインストール
% bundle install
```

### 3. rspec自体を初期化

以下のコマンドを実行すると **.rspec** , **spec/spec_helper.rb** の２つのファイルが生成されます。

```bash:--initを実行して初期化する
% bundle exec rspec --init
```

**spec/spec_helper.rb** はほとんどがコメントアウトされているので、外して有効化する。
**`=begin` と `=end` の部分を削除してコメントを外す**
spec_helper内の各設定のオプションは解説しません。

```diff:spec/spec_helper.rb
…省略
RSpec.configure do |config|
# The settings below are suggested to provide a good initial experience
# with RSpec, but feel free to customize to your heart's content.
- =begin
  # These two settings work together to allow you to limit a spec run
  # to individual examples or groups you care about by tagging them with
  # `:focus` metadata. When nothing is tagged with `:focus`, all examples
  # get run.
  config.filter_run :focus
  config.run_all_when_everything_filtered = true
  
  ...省略

    # Prevents you from mocking or stubbing a method that does not exist on
    # a real object. This is generally recommended.
    mocks.verify_partial_doubles = true
  end
- =end  
end
```

これでほぼ初期化作業は終わりです。
あとはテストファイルと実行ファイルを用意して試してみます。


#### 4. テスト(Spec)コードとプロダクションコードを用意する

ここではプロダクションコードは ***`lib`*** ディレクトリ に置いて、テスト(SPec)コードを ***`spec`*** ディレクトリ に置くものとします。
その上で、 **lib/hello.rb** と **spec/hello_spec.rb** 作ってみます。

とりあえず、以下のような構成でファイルを作ります。

```
rspec_test
├── Gemfile
├── Gemfile.lock
├── lib
│   └── hello.rb
└── spec
    ├── hello_spec.rb
    └── spec_helper.rb
```

```rb:lib/hello.rb
class Hello
  def message
    "hello"
  end
end
```

```rb:spec/hello_spec.rb
require_relative '../lib/hello'

RSpec.describe Hello do
  it "message return hello" do
    expect(Hello.new.message).to eq "hello"
  end
end
```

**hello_spec.rb** の中で `require` している部分がRailsのSpecファイルとは異なる部分かと思います。(Railsはすべて自動でrequireされているので)
ここでは **`require_relative`** メソッドを使って ***相対パス*** で **hello.rb** をrequireするようにしています。

**`require_relative`** メソッドは **ruby1.9** 以降から使えるようになりましたが、`require_relative` を使わずやるなら以下のようになると思います。

```rb:requireのみで相対パスから読み込む場合
require File.expand_path('../lib/hello', File.dirname(__FILE__))`

RSpec.describe Hello do
  it "message return hello" do
    expect(Hello.new.message).to eq "hello"
  end
end
```

【参考】

- [るりま module function Kernel.#require_relative](http://docs.ruby-lang.org/ja/2.1.0/method/Kernel/m/require_relative.html)
- [Rubyで相対パスのファイルをreuqire -- ぺけみさお](http://www.xmisao.com/2013/11/21/ruby-require-relative.html)

***【追記】@jnchitoさんよりコメント頂きました！！ので追記します！！***
上記のように各specのファイルでrequireする方法もいいけど、**`require`** するのも、アプリケーションのコードなので、**spec_helper.rb** で一括指定したほうがいいですね♪
以下のように、spec_helper.rb に以下の設定を追記して、各テストファイルでは ***`require spec_helper`*** とします。

```spec/spec_helper.rb
#... 省略
Dir[File.join(File.dirname(__FILE__), "../lib/**/*.rb")].each { |f| require f }
```

```rb:spec/hello_spec.rb
require 'spec_helper'

RSpec.describe Hello do
  it "message return hello" do
    expect(Hello.new.message).to eq "hello"
  end
end
```

### 5. 実際に実行してみる

```bash:rspecコマンドで実行する
% bundle exec rspec
```

ちゃんとテストがグリーンになれば **OK** です！

### おまけ rakeコマンドでやってみる。

railsとかだと `rake spec` でrspecを実行する事ができると思います。
そんな感じでrakeタスクで実行させてみたいなーと思ったらありました。
[rake task - Command line - RSpec Core - RSpec - Relish](https://www.relishapp.com/rspec/rspec-core/docs/command-line/rake-task)


- Gemfileにrakeを追加する

```Gemfile
# A sample Gemfile
source "https://rubygems.org"

gem "rspec", ">= 3.0.0"
gem "rake"
```

- Rakefileを作成する


```Rakefile
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

task :default => :spec
```

- コマンドを実行

```bash:rakeでspecを実行
% bundle exec rake spec
```

以上でテストがグリーンになれば **OK** です！



### 最後に
最終的なファイル構成は以下となりました。

```
vendor_test
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── lib
│   └── hello.rb
└── spec
    ├── hello_spec.rb
    └── spec_helper.rb
```

以上です。