テストがないコードはクソとか、このテストツールこそ至高みたいな話が世に溢れているわけですが、 そういう状況になってくると、どうやって始めたらいいのかわからなかったりすると思います。 そういう人のために、何を読んで勉強し、何を使って何を書くと始めやすいかという抽象的な解説をしようと思います。

テストフレームワークの選択

テスト初心者の最初の壁はフレームワークの選択です。 iOSのテストについて調べると、SenTestingKitはクソとかGHUnit最高とかKiwiこそ至高とか言っている人がいると思います。 ですが、入門に最も適しているのはSenTestingKitです。 セットアップが他と比べて簡単だということと、機能が十分に小さくて機能に溺れることがないということが理由です。

SenTestingKitの使い方を学ぶ

いきなり突き放すようなんですが、Appleの公式のドキュメントを読むのがいいと思います。 プロジェクトのセットアップ方法が詳細に説明されているので、途方に暮れることもないと思います。 おそらく、初めて読んだ時点ではロジックテストとアプリケーションテストの違いがよくわからないと思いますが、 ひとまずアプリに対するテストはアプリケーションテストとしてセットアップするのが良いと思います。 理由はUIApplicationやNSBundleの扱い方がプロダクトコードと揃うからです。

Xcode ユニットテスト ガイド (公式ドキュメント)

テストの対象を決める

iOSアプリのテストは書きづらいと言われることがありますが、ほとんどのコードに対するテストを書くことは可能です。 ですが、テストを書くコストに見合った分だけの利益がないと、テストを書き続けるモチベーションは下がると思いますので、 初めは恩恵を受けやすいモデルのテストのみを書くことを勧めます。 UIViewControllerのテストを書くことも出来ますが、 初めは完璧を目指すよりも無理のない範囲で安定した粒度のテストを書くことの方が大切です。

サンプルコードを動かす

続いてすべきことは、Appleが提供しているサンプルコードを動かすことだと思います。 このサンプルコードから学ぶべきことは、モデルに対するテストケースの書き方です。 CalculatorLogicTests.mを読むとモデルに対してどのようにテストを書けばいいか分かるはずです。 (iOS_CalcTests.mにはUIViewControllerに対するテストが書かれているのですが、前節でやらないことにしたので省きます。)

Unit Testing Apps and Frameworks (サンプルコード)

実行するにはXcodeのスキームを以下のようにして、command+Uを押します。

ここまで実行すれば、テストをセットアップして、テストコードを書き、テストを実行する方法がわかると思います。 あとは自分のプロジェクトでこれらの手順を実行すれば、iOSテストに入門できたといえると思います。

他のテストツールについて

ひと通り実行してみると、SenTestingKitについて以下の点に気がつくと思います。

  • 非同期の処理が完了する前にテストケースが終わってしまう
  • このメソッドを呼んだらこのメソッドが呼ばれるというテストができない
  • テストしたい条件を作ることが難しい

1番目の非同期の問題はNSRunLoopを回して待つことで解決可能ですが、 Kiwiなどのフレームワークレベルで解決しているものを利用するという手もあります。 そもそもモデルの層で非同期の処理が入っているコードはテストしづらいコードだという説もあります。

2,3番目の問題はモック/スタブを提供するライブラリを導入することで解決できます。 OCMockなどのモック/スタブ単品のライブラリもあれば、Kiwiのようにフレームワークの一部として提供しているものもあります。

必要に応じてこういった外部のライブラリを導入するとテストが楽になるので、 なんかテストが書きづらいなあと思ったときは、それを上手く解決しているライブラリを探すといいと思います。

SenTestingKitに対するよくある誤解

SenTestingKitは誤解されやすいので、SenTestingKitに対するよくある誤解を並べておきます。

  • 非同期処理を含むテストを実行できない -> NSRunLoopを回して完了を待つことはできる
  • 実機上でテストを実行できない -> アプリケーションテストは実機でも実行できる
  • ターミナルからテストを実行できない -> xcodebuildコマンドで実行可能