読者です 読者をやめる 読者になる 読者になる

light log

学んだこととか

RSpecを導入しようとしたらSpringとか調べてた

ただの作業ログ的な日記的な文章。

環境

$ ruby -v
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-darwin14]
$ rails -v
Rails 4.2.1

背景

Rails Tutorialを終えたので、学んだことを活かして、以前勉強用に作ったRailsアプリにRSpecのテストを書いてみようと思った。

作業ログ

Rails Tutorialを参考にGemfileを修正

テスト関連のgemの記載を追加するんだけど、それぞれが何をしているのかわからずに追加するのも気持ち悪いので、簡単に調べた。

ブラウザのエミュレータ

Selenium WebDriver

  • Capybara

ユーザのブラウザ上での振る舞い(クリックとか)をシミュレートするソフトウェア

Capybara

BDDテスティングフレームワーク

RSpec: Behaviour Driven Development for Ruby

…という大雑把な理解。

RSpec/Capybaraの入門記事を読むと、Selenium WebDriverを使っていないものもあったので、とりあえず入れないことにした。必要だったらどうせすぐにエラーなりが発生して気付くだろう。逆に最初に全部入れた場合、もし実際には必要なくて使われていなかったとしても、なかなか気付けなさそうなので。

ということでrspec-railsとcapybaraを追加する。

group :development, :test do
  ...
  gem 'rspec-rails'
  ...
end

group :test do
  # gem 'selenium-webdriver'
  gem 'capybara'
end

rspec-railsをdevelopment,testのグループに入れているのはRails Tutorialの名残り。他の入門記事にはtestのグループに入れてるやつもあるけど、それぞれどうしてなのか理解しないまま、ここではRails Tutorialのやり方をそのまま踏襲している。行動が一貫していない。。

最初、Rails Tutorialのままrspec-railsのバージョンを2.13.1と指定していて、bundle installしてrails g rspec:installした。

その後で2.13.1ってだいぶ古そうだと気付いて、バージョン指定を外してbundle updateしたら3.2.1に上がった。

メジャーバージョンが上がってるから、Rails Tutorialで学んだ知識と変わってる部分が結構あるかもしれないと思いながらbundle exec rspecしてみたら、以下の警告が出た。

Deprecation Warnings:

Requiring `rspec/autorun` when running RSpec via the `rspec` command is deprecated.

そこで、spec_helper.rbを再生成しようと思って、specディレクトリごと削除して、再度rails g rspec:installしたら今度はrails gが動かなくなっていた。

$ rails g -h
There is a version mismatch between the spring client and the server.
You should restart the server and make sure to use the same version.

CLIENT: 1.3.5, SERVER: 1.3.4

クライアントとサーバでバージョンがミスマッチしている。多分bundle updateのときにバージョンが上がったんだろうけど、そもそも何らかのサーバを起動している自覚がない。指摘されてるspringってなんだろうと思って調べた。

Spring

Spring is a Rails application preloader. It speeds up development by keeping your application running in the background so you don't need to boot it every time you run a test, rake task or migration.

rails/spring - GitHub

SpringはRailsアプリのプリローダで、バックグラウンドでアプリを起動した状態にしておいてくれることで色々なコマンドの実行が速くなる、というやつらしい。

これが勝手に動いてるんだな。確かにGemfileに

gem 'spring'

と書いてある。

以下で停止できた。

$ spring stop
Spring stopped.
$ spring status
Spring is not running.

その後これで再起動できた。

$ spring rails

ここにきて、「バックグラウンドでアプリを起動した状態にしておいてくれることで色々なコマンドの実行が速くなる」というのが気になった。SpringがやってることってSporkと同じ?

調べたら、やはり基本的には同じ目的のツールのようだ。

SporkからSpringに乗り換えた結果wwwwwwwwwwww - リア充爆発日記

Springのページには

in Rails 4.1 and up Spring is included by default

と書いてある。Rails 4.1以上にはデフォルトで含まれる。

Rails TutorialではRailsのバージョンは4.0.5だからSporkを使っていたのかもしれない。Rails Tutorialの前に読んだ入門書(Ruby on Rails 4 アプリケーションプログラミング)もRails 4.0.2をターゲットとしているので、Springに関する記述はなかったと思う。でも4.1以上を使うならデフォルトで入ってるSpringを使った方がいい気がする。

ということで、最初は、RSpecのテストを書き始められたら、Guard/Sporkを導入しようと思っていたけど、SporkじゃなくてSpringにする。

binstub

Springについて調べていたら、以下の記事が見つかった。

Rails 4.1以降のコンソールコマンドは必ず bin/ を付けなきゃいけないの? - Qiita

rails/rake/rspecなどのコマンドは、そのコマンドのラッパーとなる実行ファイルがプロジェクトの/binディレクトリに置かれていて、このラッパーをbinstubと呼ぶ。ここでのbinstubは、該当するコマンドを実行する前にSpringの起動をしていて、そのために二回目以降のコマンド実行が速くなる仕掛けになっている。

だから、これがデフォルトで有効になっているRails 4.1以降では、必ず/binの下の実行ファイルを明示的に指定しなければならないのか?という記事。

記事の結論は、railsコマンドだけは基本的にbin/を付けなくてもbin/railsが実行されるのでspringが動くが、bin/を付けることによる害はないので全部に付けておけば問題ない、という感じ。

bin/を付けるのも面倒という人向けに、自動的にカレントディレクトリのbin/にパスを通してくれるdirenvというソフトウェアも紹介されている。とりあえず自分は今はこれは入れなくていいやと思った(すでに大幅に脱線しているので)

binstubについては以下も参考にした。

binstub について翻訳してみた - Qiita

rspec with spring

springは、

$ spring binstub --all

とすると、コマンドのbinstubを/bin以下に生成してくれる。ただデフォルトだとrspecコマンドについては知らないようなので、spring-commands-rspecを入れる必要がある。

gem 'spring-commands-rspec'

これで、rspecのbinstubも生成できる。以下で生成とSpringの再起動。

$ bin/spring binstub rspec
* bin/rspec: generated with spring
$ bin/spring stop
Spring stopped.
$ bin/rspec 

まとめ

これから用事があるから今日はここまで。テスト書き始めるまでたどり着かなかったorz

でもとりあえずSpringについて調べられたし、明日はテスト書けそう。書けるといいな。あとRDocも書いてみたい。