Ruby勉強会を開催しました(2016#02)
今年も2回目の勉強会を開催しました。
今回の参加者は11名!
徐々に社内のRuby人口が増えつつあります。mrubyの勉強を中心にしてもらえるメンバも加わりました。
流行?のIoTの分野でもRubyは浸透していくと思いますので、mrubyについても積極的に取り組んでいきたいですね。
一方グループウェアの方は、Capybara, RSpec, DatabaseCleaner, FactoryGirl を使って遅ればせながらテストコードの実装を始めました。
リファクタリングでコードを見直すときも都度テストを実行することで、修正ミスをすぐに見つけることができので、思い切った変更も行ったりしています。
現在テスト周りで設定している内容を少しご紹介させていただきますが、これがベストではないと思いますのでご了承ください。
対象のテストはmodelの単体チックなテストと、UIを操作して行うテストfeatureの2種類です。
controllerのテストも実装していたのですが、ActiveRecordによるデータ取得(検索)の結果を一部正しく検証することができませんでした。
そんなこともあり、controllerのテストは早々にあきらめてしましました。基本UIのテストが通ればOKと判断できるようにしたいと思います。
まず、事前にデータベースに初期のデータを流し込みますが、これはseedで行っています。
将来的には手段を変更する必要性が出てくるかもしれませんが・・・
以下のようなコードをspec_helperに追加しています。
beforeの引数に :suite を指定していますので、すべてのテストがロードされた後、テスト(example)実行前にseedが実行されます。
改めてRSpecのドキュメントを見てみると、:each, :all がそれぞれ :example, :contextに変わっているようですね。
:each, :allはスコープのエイリアスとなっており、使うことは問題ないようです。
RSpec Core 3.4のドキュメントから引用すると、hookの順序は次のようになるようです。
続いて DatabaseCleaner ですが次のように設定してみました。
RSpecのgemのバージョンは3.0.4だったのですが、:exampleという指定も可能でした。というかむしろこちらが標準になっているようでした・・・。
あまり必要性を感じていない部分もあるのですが、FactoryGirlも使っています。
ここで困った問題が発生しました。各テスト(feature)の実行時に、background(:each)の中で、FactoryGirlを利用してデータベースに登録したはずの
データがテスト(example)の中で取得できなかったのです。
結局、feature毎に実行されるbackgroundとscenario毎に実行されるbackgroundとを分けて記述し、feature毎に実行するbackgroundのブロックのなかでFactoryGirlを
利用することで問題を回避することにしました。
実際には次のようなコードになります。
background(:each)のなかで、createを実行してもexample実行時に登録されていない状態でしたが、background(:all)の中で
実行したcreateではexampleの実行時ではデータが登録されており、期待通りのテストを実行することができました。
この理由をもう少し調べたいところですが今はテストの実装を優先している状況です。この辺のベストプラクティスがわかりましたらご紹介したいと思います。
注意点としては、example毎にデータが新たに登録されません(feature毎に登録される)ので、他のexampleに影響がないようにする点でしょうか。