はじめに
テストフレームワークの組み合わせとか
今現在iOS 向け開発でモックやマッチャーも含めて、ユニットテストを行なおうとするならだいたい使うのはこんなパターン
- SenTestingKit(SDK標準)
- OCHamcreast, Expecta
- OCMock, OCMockito, LRMocky
- GHUnit
- OCHamcreast, Expecta
- OCMock, OCMockito, LRMocky
- Cedar
- OCHamcreast(内包してる)
- OCMock(内包してる)
- Kiwi
- KWMatchers(自前)
- KWMock(自前)
- Specta
- Expecta(内包してる), OCHamcrest
- OCMock(内包してる)
GHUnit 以外はOCUnitサポートが入っていて、内部的にSenTestingKitのテストケースを実行しているのでXcode上からCommand-U で実行できる。CI 用のコマンドラインからの実行や、JUnit 互換のレポート出力などには今回は触れない。
寸評
SenTestingKit 直使い
- Xcode4 からセットアップ、初期設定してくれるので用意するまでが楽
- 使っている人が多いのでわからない時に質問や検索して教えてもらえる
- アップルが公式にサポートしているのでSDK アップデートしても基本的に使い続けられる
- 特定のテストだけを実行する/しない場合、プロジェクトのSchemeで設定する
- ソースは公開されてない。昔のソースは公開されてたんだけど公式の取り込まれた時点でしなくなったのかな。
なので保守的に安定して使えるフレームワークであると言える。以下にアップルの公式ドキュメント翻訳がある
ちなみにiTunes App Store に申請したバイナリにSenTestingKit.framework をリンクしてしまうとリジェクトされる。
個人的に過去に経験を何回かしており憎しみを抱いている。
GHUnit
- アプリケーションの中にテストアプリケーションを埋め込むという柔軟な発想のフレームワーク
- 動的に特定のテストメソッドだけを実行、ということができるので大規模コードベースでも安心
- Macアプリ版もあり
- 非同期処理のテスト仕組みがデフォルトで用意されている
- View をキャプチャして画像同士で検証といったクールな方法も用意している
- Katsumi Kishikawa さんもオススメ
- OCUnit 形式の実行をサポートしていないので開発中にCommand-U でガシガシテスト実行できない
- OCUnit 形式の外にあるのは実機テスト実行のしやすさなどでメリットだったりもする
Cedar
- Pivotal Tracker でお馴染の Pivotal Labs のイケてるエンジニアたちによって開発されている
- アンチ車輪の再発明的というか既にある外部モジュールなどをうまく組合せて構成されている
- 企業で作っている & 内包・依存しているプロジェクトが多いので頭数的に、それだけ開発速度も早い。が調整もたいへんだろうと予想される
- マクロとかObjective-C++ でのメタプログラミング(?)ばなどが混在しており黒魔術的で、うまくいかなかった時に内部構造を追うのがたいへん
- 非同期処理を含むコードのテストをどうやるのかがわからない……
Kiwi
- iOS 向け。Mac OS X 向けの開発はサポートしていない
- 非同期処理のサポート
- モックオブジェクト用のクラスも内蔵している
- カスタムのマッチャーを作成するのも簡単
Specta
- 01/2012 に公開されたばかりのプロジェクト
- mainループ→UIApplicationDelegate で実行するわけではなさそうなのでUIKit 系のテストはできない?
タイプ別診断
使ってる開発者の数(シェア)だと
SenTestingKit > GHUnit > Cedar = Kiwi > Specta
ぐらいだけど、成熟したWeb開発に比べてそもそもTDD/BDD自体がそんなにやっている人がいない……
それを踏まえて「こういう人にはこれがおすすめ」というのを記します。
"A -> B -> C "というのは試してみる順番です。
- ユニットテスト自体をよくわからず、やったことがない
- SenTestingKit -> GHUnit -> Kiwi
- OS X 向けのアプリケーションも開発している
- SenTestingKit -> GHUnit -> Cedar
- 開発中にCommand-U でガシガシテストしたい
- SenTestingKit -> Kiwi -> Cedar
- 巨大なコードや非同期呼び出し満載の複雑なライブラリをメンテしている
- GHUnit -> もしくはテストターゲットを分割するのがいいかもしれない
まとめ
Cedar, Kiwi, Specta のBDDスタイルあたりだとシェアはしばらくCedar とKiwi が横並び状態ではあったんだけど、開発の勢い(あいまいだ)では個人的には最近——といっても1ヶ月ぐらいはKiwi がちょっと抜けてきた印象。
Kiwi を取り扱った電子書籍も出てる(US向けiBooksストア)
ただ自分が使ってるうちではなんかの拍子で突然テストランナーぶっ壊れたり(テスト成功するけど、テストコード走ってないとか)してターゲット再作成したり。非同期処理でうまくいかなかったりもした。
他にGoogle のCocoa 向け開発チームが提供しているGTMUnitTest とかもあったんだけ、これはSenTestingKit がまだiOS向けでに標準サポートされていない時に使いやすくする目的でものなので、最近はチェックしていないし。新たに使い出す人もあんまりいなそう。
あと初期iPhone3G時代に速攻でリリースされたことが印象に残っている内国産のiUnitTest も開発が続いている。
BDDスタイルのものは、ここで3つあげたけど。ただ、RSpec の恍惚が忘れられないRuby プログラマ兼iOSアプリ開発者たちによって日々新たなツールが生産し続けられているので将来的にはどれが流行っているかは正直わからない。