Anonymous Function

tmaesaka の lifelog | カルチャー、ときどきテクノロジー

minitest で RSpec っぽくテストを書く方法

このエントリは刻々と変化する RSpec の作法や暗黙のルールに疲れた人むけです。

spec

テストフレームワークとして人気のある RSpec ですが、しばらく使っていると非本質的な話に振り舞わされて疲れることがあります。インターネット上の情報も早いペースで古くなりがちです。こういった事情により RSpec から標準のテストフレームワークに出戻る、あるいは移行するデベロッパが世界中で増えていると聞きます。

移行するといっても、いざコードを書きはじめてから minitest のシンプルすぎる構文に戸惑う人もいるでしょう。そういった人たちのために、なるべく慣れ親しんだテスト構成を標準ライブラリで組む方法を紹介します。

Example Group が恋しくなる

RSpec を使っていると example group を使ってテスト対象を細かく絞ったり、対象の状態に応じたテストを書くことがよくあります。そうすることによって、仕様書のように綺麗なテストが出来上がるからです。Model spec なんかは解りやすい例ですね。

describe SomeModel do
  describe '#func_foo' do
    context 'without xxx' do
      it 'fails to validate' do
        expect(...).to_not be_valid
      end
    end
  end
end

RSpec から離れたいけど、上記のようなテストを書き続けたいと考える人は少なくないと思います。実際にこういう声もあります。

MiniTest::Spec の出番

Ruby 1.9.2 から標準で搭載されている MiniTest::Spec を使うと RSpec 風にテストを書けるようになります。有効にするには test_helper.rb などで require 'minitest/spec' します。

describe SomeModel do
  it 'test case A' do
    assert true
  end

  describe 'nested group A' do
    it 'test case B' do
      assert true
    end
  end
end

有効にすると上記のように RSpec 風にテストを構成できるだけでなく、Assertion の代わりに Expectations を使うことも可能です。

context メソッド

残念ながら MiniTest::Speccontext メソッドを提供してくれません。どうしても欲しければ alias_method :context, :describe 的な monkey patch で無理やり対応できそうですが、おすすめはしません。

ここまで来ると RSpec で良いじゃんと突っ込まれそうですが、ころころ変わる作法にとらわれないための第 1 歩としてはアリじゃないでしょうか。

Increments の道玄坂オフィスに行ってきた話

友人の誘いで QiitaQiita:Team などを運営する Increments 社にお邪魔してきました。

increments

道玄坂に移転してから日も浅いということで、外部の人たちが参加する初の TGIF でした。まとめると、全文検索のチューニング、Markdown パーサ拡張、インフラストラクチャ移行、ServiceWorker、キーワード抽出など、濃厚な話をピザを食べながらしました。この充実した時間、さすがデベロッパーを支える Increments の空気です。

今回の集まりで Chrome 42 から対応される Push NotificationEpitome に実装するきっかけを得たので、近日中に最先端を走る利用者むけに実装します。うまくいったら、それを足がかりに ServiceWorker を使ったコンテンツの先読みに挑戦するかも。

Epitome (エピトミ) プロジェクトをリリースしました

Epitome は一言でいうと、英語などの言葉で書かれているウェブ上の文書のあらすじを読むことで、価値のある情報かどうかを事前に確認できるナレッジベースです。

launch

何のためのサービス?

特定の話題について調べたいけど、外国語の記事しか出てこない。記事のすべてを読むのは大変。記事を読む前に自分にとって価値のある情報かどうかを知りたい。そんな悩みの解決を試みるサービスだと思ってください。

一般的なエントリーには、原文への URL と、そのあらすじを説明する要約ポイントが表示されています。 気になった記事があれば、そのまま Google 翻訳で開けるようにボタンも設置しました。

運営が一方的にリンクや要約を提供するのではなく、利用者のみなさんに投稿していただくことで成り立つサービスです。

なぜ作ったのか

自分は友人との会話や仕事上のやりとりの際に、相手の参考になりそうな記事へのリンクを送ることが多いのですが、その記事が英語のものだと、相手にとって負担になるのではないかと思うことがあります。

英語の記事はがんばれば読める、という人は多いと思いますが、長文の場合だと気合と時間が必要になります。しかも、がんばって時間をかけて読んだのに大した情報じゃなかった、なんて不幸なこともあり得ます。そこで、貴重な時間を割いてまで読む価値のある記事かどうかを事前にさくっと母国語で知ることができたらすごく便利なんじゃないか、と思ったのが Epitome 立ち上げのきっかけです。

ロングターム

このサービスのポイントは「記事の要約」であり、「フル翻訳」ではありません。フル翻訳が集まるサイトが存在したところで、母国語に訳された記事ばかり読んでいる人の英語読解力は上がりません。Epitome の長期的なミッションは、海外の記事を原文で読む機会を増やし、日本人全体の英語読解力向上に貢献することです。

テクノロジー

Epitome を作るにあたって、自分が今まで使ったことのない技術を利用者に有益な形で活用することにしました。そのいくつかを紹介します。

フロントエンド

ソフトウェアの体感速度は速ければ速いほど良いと思っています。体感速度が速いほど、利用者は期待を満たさない結果に対して、回遊や再検索などのセカンドチャンスを与えてくれるからです。そこで、モバイルウェブ版に pjax を導入しました。データ通信量を削減するために rack-pjax と組み合わせています。

インフラストラクチャ

Google Cloud Platform を一部採用しました。具体的には Google Cloud DNSGoogle Cloud Storage です。Google Compute Engine も使いたいところですが、低予算でプロジェクトを回しているので、今回は見送りました。計算リソースの監視には、はてなの Mackerel を使っています。ついでに SPDY (h2-14) にも対応しました。

これから

直近は URL fetcher を賢くするなど、ソフトウェアの品質向上に取り組む予定です。機能は必要に応じて... と言いたいところですが、そのときの謎のテンションでいろいろ作ってしまうんでしょうね。