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

スタートアップが HipChat から Slack に移行した話

10 人規模のスタートアップがオンライン・コミュニケーション手段を HipChat から Slack に変えた話です。移行を考えている人たちの参考になればと思います。

workstation

特に困っていなかった

まずは昔話から。3人で会社を創業したてのころは Google Hangouts でコミュニケーションを取っていました。強い理由はなく、なんとなくです。エンジニアが増えたことを機に HipChat を導入しました。GitHub の通知、デプロイメント、各種ツールからの通知を一元的に閲覧・共有するためです。そこから人も増え、会社のオペレーションやエンジニアリングは順調に回り続けました。製品アプリケーションの状態をスタッフにリアルタイムで知らせてくれる仕組みを作るなど、まさに「いい感じ」でした。

きっかけ

Slack 導入の話が浮上したのは、新しく入社してくれることになったエンジニアから Slack を使いたいという要望があった (らしい) からです。Slack 自体はしばらく個人的に使っていたので、導入自体は反対ではありませんでしたが、さすがに民族移動を行うには、それを正当化する理由を考える必要がありました。

悩む

なにもかも順調なら、なぜ移行するのか?黄金の質問ですね。Catch-22 です。

専属のマーケティング・マネージャーやダイレクト・セールスの仲間もいるので、理由もなく移行を押し付けれません。ただでさえ忙しいのに、一方的に環境をガラリと変えられるわけですから。

移行コストは人間的なものだけではなく、技術的にも生じます。各種ツールの再設定や、製品アプリケーションの通知コードに手をいれるといった手間です。これらのコストを伴ってまで移行する必要があるのか?と少し悩んでいました。

隣の芝生は本当に青いのか?

Slack を勧める人たちが口を揃えて言うのが、カスタム・インテグレーションの素晴らしさです。あらゆるサービスと簡単に連携できるんだよと。個人的にこの点には疑問を抱いています。いまどきのプロダクティビティツールだと当たり前の話ですし、なにより Slack も HipChat も立派な連携のラインアップを提供しています。

その他のメリットに関しても反論できるものばかりで、本当に困ったものです。

勢いのあるプロダクトに触れている重要性

流行っているから使いたい。もっとも説得力に欠ける論点ですね。それを言われた社内システムを保守する人間はこう考えるでしょう「勘弁してくれ、また何か流行ったら、すぐに乗り換えるのか」と。正論です。

同時に、勢いのあるプロダクトに日常的に触れることも重要です。人の心をつかむ色使い、レイアウト構成、文言スタイル、アニメーションの使い方、どんな技術を活用しているのか、運営サイドのコミュニケーションスタイルなど、吸収すべきものが山のようにあるからです。こういった話は言語化や定量化が難しく、プロダクト開発の現場にいない上司や部署には理解されづらい価値観です。非合理的ではありますが、自分はそういった価値観が好きなので、これで納得しました。

ちなみに、次に何か流行ったらまた乗り換えるのか?という疑問点ですが、ぶっちゃけ、当たり前だろw と個人的に思っています。知的好奇心には常に答えてあげないと。

実は大した話ではなかった

幸い、小さなスタートアップということもあり、誰も嫌がらずに乗り換えることが出来ました。勢い大事ですね。エンジニアリング面の移行コストも、いざ作業に入ってしまえば、大した話ではありませんでした。ワークフロー的にも、1 日で全員 Slack を使いこなしていたので、何ら問題はありませんでした。優秀なプロダクトの証拠ですね。

移行して良かったこと

実際に移行して良かったと思う点です。数は少ないです。

アイコンが可愛い: 無理やり感はありますが、普段つかっているツールに愛着を持つことは大事です。

Android アプリがよく出来ている: 自分も含めて、Android ユーザのスタッフはこれだけで喜んでいました。日本語がまともにレンダリングされる。

検索がよく出来ている: 日本語の検索クエリにも、それなりに満足な結果を返してくれます。これだけで移行の理由になるかもしれませんね。/s 検索クエリ のスラッシュコマンドも便利です。

相手の顔が見える: HipChat から Slack に移行して、プロフィール画像の重要性を改めて痛感しました。その昔、@os0x の書いた、ウェブ版の HipChat に無理やりプロフィール画像を差し込む Chrome Extension を重宝していたことを思い出しました。

運営のやる気を感じる: 正直なところ、HipChat は Atlassian に買収されてから動きが鈍くなったと感じています。対して Slack は、創業者が従来型よりもキツい Stock プランを模索しているほど、長い目で物事を見ているようです。これだけでも安心しますね。いきなりサービス終了や、中途半端に買収される心配もなさそうです。

結果的に、日常的に何か変わったわけではありませんが、エンジニアの頭の中から一つ雑念が減ることは良いことだと思います。知的労働者がよりハッピーになることで、ゾーンに入りやすくなるのであれば、とてもハイリターンな安い投資です。

引き続き、チームがよりハッピーになれる施策を実行していければと思います。