非同期処理/RSpecなど|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。非同期処理/RSpecなどhachi8833シェアツイートブックマークLINEこんにちは、hachi8833です。今回は棚卸しとして、弊社CTOのbabaさんによるRails勉強会スライドから引用して記事にします。3.x時代のものなので既出が多くなっていますが、棚卸しも兼ねて今のうちに記事にいたしました。言うまでもなく、リクエストからレスポンスまでの時間が長くなるほどユーザー・エクスペリエンスの質が低下します。これを改善するためにさまざまな工夫が必要になるわけですが、その中の一つとして、時間のかかる処理をバックグラウンドで実施しておくというのがあります。cron最も素朴な方法はやはりunix標準のcronを使って定時に出力データを準備することでしょう。この場合、起動用スクリプト(rakeなど)やジョブ管理は自分で作成する必要があります。Recordで管理できます。その便利さについては各方面で語られているので省略しますが、以下の点が少々残念であるという指摘があります。ジョブ完了時にキューから該当ジョブを単純に削除するため、完了したのか、Enqueueに失敗したのかわかりにくいデータをMarshallで渡すため、バージョンが変わったときにトラブルの元になることがあるRailsが動作していることが前提のため、その分重いresque3番手はresqueです。使用してジョブキューを管理します。Redisとresqueがインストールされていれば、Railsなしでも実行可能です(ActiveRecordがないと使いにくいとは思います)。resqueはJSONでデータを受け渡しするので互換性が高いのが特長です。※Redisには少々癖があり、旧バージョンでは書き込みIO負荷が高い・メモリ不足の時に落ちる・expireしても次回読み込みまで消えないなどの問題があったようです(2012年時点の情報なのでその後状況が変わっている可能性あり)。使い方は以下をどうぞ。(日本語)resqueはgemで拡張するのが習わしになっています。cronでキューに入れる。resqueをバックグラウンド実行中にロックをかける。今ひとつわからないresqueの注意点などresqueはマスタープロセスからforkさせてからキューを実行するので、デプロイ時にはマスタープロセスの再起動が必要。Workerクラスはモデルの内部クラスとして実装すると見通しがよくて便利です。resqueの監視にはmonitが無難でおすすめです(godよりは安定しているみたい)。awayエラーが発生する場合は、最初にActiveRecord::Base.verify_active_connections!を行ってみよう。database.ymlにreconnection:trueと書く手もあるようですが、長いトランザクションの途中でreconnectされると怖いかも。(一時はRails3の登場で絶滅が危惧されたそうです)。プロジェクトの規模に応じて、RailsとSinatraを使い分け、場合によってはRackを直接駆動するというのがよい感じです。ちなみに紹介記事を元に生Rackアプリを書いてみたら、えらく簡単でした。endendテスト駆動開発(TDD)についてTestFirstとTDDは同じものではありません。TestFirstは単にテストが先行しているだけの状態であり、TDDはテストが開発を牽引しているかどうかという点が違います。テストのカバレッジですが、一般的に言って100%にこぎつけるのはやはり難しいと言えます。カバレッジにはC0/C1/C2などの段階がありますが、たとえばbegin/rescueブロックをどうチェックするか、fork先のプロセスまでチェックするかなど、追い求めるときりがありません。Coverageは90%を目指すのが現実的だと思います。xUnit対RSpecという図式について、Railsでは当時からRSpecが支配的だったこともあり、弊社ではRSpecの使用が推奨されてきました。RSpecでのノウハウ以下パラパラとメモします。テスティングでよく使用されるのはAAAというパターンです。結果を検証itでのテスティングの説明は極力シンプルにしましょう。ほとんどの場合1行以内に収まるはずです。beforeをうまく使ってテスティングの下準備部分をまとめ、効率化するのがポイントです。:eachなのでその場合:eachは省略できます。itを生成するメタプログラミングもありですが、あまり複雑にするのはよくないようです。入力・出力のペアをまとめて検証するぐらいにしておきましょう。JavaScriptのテストは一律行うと遅いので、必要な部分のみを実施するようにしましょう。最初にJSをオフにして全テストを実行し、最後にJSが必要な部分だけを実行すると効率的です。具体的には、decribeブロックごとにRackとWebKitを切り替えます。必要な場合にのみWebKitを使用してJavaScriptをテストし、通常は極力Rackを使用します。RackはWebKitより10倍速いので。指定すると、失敗が1つ発生した時点でテストが終了するので、うまく使えば時間を節約できます。--fail-fastRSpecのマッチャーRSpecも少し前に3.0が登場しましたが、以前のノウハウもまだまだ健在です。RSpecのマッチャーで真っ先に覚えるべきはbe_hogehoge系のpredicate(述語)マッチャーでしょう。このマッチャーが機能するには、hogehoge?というメソッドが必要ですので、逆に言えばこのマッチャーが使えるようにコードを書くようにしましょう。ついでながら、このメソッド名もマッチャーがおかしくならないような名前にしておきたいものです。「is_flag?」みたいなメソッド名だとマッチャーが「be_is_flag?」みたいなみっともない名前になるので、そういう名前は使うものではないということがわかります。他にビルトインのsatisfyマッチャーはブロックを引数に取り、ブロックがtrueかどうかをチェックします。raise_errorマッチャーは例外が発生するかどうかを確認できるビルトインマッチャーです。例外のテストは意外と忘れがちです。それから、カスタムマッチャーは遠慮せずにどんどん作りましょう。複雑なオブジェクトをeqで比較できるようにするとか。UIテストについてTestFirstが常に善とは限りません。UIを試行錯誤しながら開発するときにはTestFirstはほとんど意味がないのでとっとと諦めましょう。UIにびっしりテストを書いたところで、仕様が変わったときのダメージが大きいので、必要な分だけにしておきましょう。UIのテストでは、むしろ「/usersだったらuserがたくさん表示されていることを確認する」など、瑣末でない本質的な部分を押さえるようにしてください。後、クライアントの指示で必ず含めなければならない定番の文言があるならそれをテストに含めるのも有効です。テスト内容がCSSセレクタでデザインに依存するのはよい傾向ではありません。テストデータ単体テストでは、テスト対象以外の関連オブジェクトのデータを作るかどうかが思案のしどころです。大きく分けて、モックでさくさく進めるか、ちゃんとオブジェクトを作成(Object#create)するかです。モックは動作も高速で比較的作りやすいのですが、関連オブジェクトの仕様が変わっても検出できないという問題があります。Object#createは面倒な代わりに、関連オブジェクトの仕様が変わった場合に検出することができます。どちらを選ぶにしても、テストをどのように分離し、網羅するかはしっかり考えておく必要があります。単体テストはその対象だけに集中すべきと考えるなら、結合テストで関連オブジェクトとの関係をカバーする必要がある、というふうに。CIを始め多くのサービスが出現していますので、積極的に使いましょう。出力ファイル名でRSpecのログを残せます。出力ファイル名とすればHTML形式で出力できます。自動生成ドキュメントは何かと使いづらいので、必要なドキュメントがあれば自分で書きましょう。decoratorヘルパーファイルの命名はビューに依存していて、数が増えてくるとapp/helperの下のどれに追加したらよいか迷ってしまいます。メソッドを追加したいのはモデルであることが多いのですが、モデルが肥大化するのは避けたいものです。decoratorやdraperなどのdecoratorパターンです。full_nameなどのメソッドを簡単に見通しよく追加できます。decoratorパターンについては『肥大化したActiveRecordモデルをリファクタリングする7つの方法』も参考にしてください。コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。enno.jpを運営。実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。