最近iOS アプリ開発向けの受け入れテストに興味があっていくつか使ってみたのでフレームワーク概要、比較などをした。
iOS アプリ開発向け受け入れテストフレームワークはまだどれも成熟していなく、まだそのプロジェクトのコントリビューターになれる人ぐらいしかうまく使えないかもしれないが、受け入れテストの自動化は将来的にも有用であるので投資すべき。
ここでいう「iOS アプリ開発向け受け入れテストフレームワーク」とは「iPhone/iPad アプリ開発において、開発者がユーザーの為にアプリケーションが仕様どうり動作する(振舞う)」ことをテストすることを目的としたもの。
なので「開発者が実装・設計・リファクタリングなどの為にコード/クラスの動作(振舞い)をテストする」という目的のTDDにおける単体テストと区別する為だけに使っている。
単体テストは実例をあげるとXcode 組込みのSenTestKit やGHUnit なんかで実行しているテストが該当する。ただこのあたりの境界はあいまいで人によって領域が違ったり呼び方も異ったり同じ用語の意味が別だったりする(iOSアプリ開発コミュニティだと"UI テスト" という用語を使う人もいる)、のであんまり気にしない。
たとえば"iOS開発ガイド"にもロジックテスト, アプリケーションテストという用語を使っているしGHUnit でもビューコントローラーのテストができる。違うのはユーザーはビューコントローラーのプロパティを読み込んで画面に文章が表示されているか確認できるわけでもないし、直接ボタンアクションの関数を呼びだすわけでもない—— といえばわかりやすいのか、単に内部からのテストか外部からのテストかと表現した方がいいのか。
ウェブアプリ開発の知識がある人向けだと、テストヘルパーなどでリクエストとレスポンスのオブジェクトからテストを実行しているのと、mechanize やSelenium やPhantomJS でHTTP クライアントでサーバプロセスにテストを実行しているような違い。かなあ。
iOS開発ガイド - アプリケーションの単体テスト
受け入れテストはどちらかと言えば顧客のためのテスト。受け入れという名の通り、このテストがパスすればその機能は実装が完了したとわかり、顧客の立場からすると要件が正しく実装されていること、進捗が管理しやすいなどの利点がある。
名前 | テスト記述言語 | テスト実行 | 操作からテスト生成 | 実機動作 | 依存 | CIサポート | ライセンス |
---|---|---|---|---|---|---|---|
KIF | Objective-C | Xcode | NO | YES | - | ◎ | Apache v2 |
Frank | Gherkin(Cucumber), Ruby | Cucumber | NO | - *1 | Cucumber, Ruby | ◎ | - *2 |
Sikuli IDE | Sikuli Script(Jython) | Sikuli *3 | YES | NO | Sikuli ランタイム | △ | MIT |
FoneMonkey for iOS | Objective-C(SenTestKit)/Javascript(QUnit) | Xcode(テストバンドル) | YES | YES | - | ◎ | GPL v3 |
UIAutomation+tuneup | JavaScript | Xcode | YES *4 | YES | Instruments | ○ | LICENSE |
NativeDriver for iOS | Java | Eclipse,コンソール | NO | YES | Java | △ | Apache v2 |
CI サポートと設けた項目は
◎: 公式ドキュメントに載ってる
○: 使える。使ってる人がいる
△: 不可能ではなさそうだが不明
×: 仕様的に不可能
という感じ。
そもそもCI サポートとは何かというのもあるけど、だいたいのところで「Jenkins からビルドやテストを実行できてテスト結果のレポートなどを読めるようになる」ぐらいの意味です。
square/KIF - GitHub
KIF は公式には"iOS integration test framework"と謳っているんだけど前述の用語の使い方の違い参照で同じようなものです。Twitter共同創設者のジャック・ドーシーが立ち上げた Square っていう会社が作成しているオープンソーソライセンスのライブラリ。
特徴はsenario, step, feature という語彙を使ってObjective-C でテストコードを書くこと。
自動テスティングフレームワーク "KIF" | Cocoaの日々情報局
http://cocoadays-info.blogspot.com/2012/01/kif.html
FoneMonkey - Functional testing tools for mobile apps | Gorilla Logic
http://www.gorillalogic.com/fonemonkey
FoneMonkey for iOS はiOS アプリ向けの機能テストを自動化する仕組み。エンタープライズRIAとか自動テスト方面で有名なGorilla Logic という会社が作っている。
特徴はiOS アプリに組込むSelenium IDE Plugin っぽい感じで。既存のアプリの上にコントロールパネルを表示して、そこから操作記録、再生、自動テストスクリプトの保存などが行なえる。自動テストスクリプトは最終的にはSenTestKit やQUnit のフォーマットになるみたい。ドキュメントが充実している。あとダウンロードにユーザー登録が必要。
以前から存在自体は知っていたんだけど、個人的なトラウマによりウェブサイトのゴリラの画像が怖過ぎてなかなか開けなかった。
Project of the Month: Automating iOS Application GUI Testing With FoneMonkey | Dr Dobb's
http://drdobbs.com/open-source/231901614
Automating iOS Application Testing: Under the Hood, Capturing and Recording Events | Dr Dobb's
http://drdobbs.com/open-source/231903414
Testing With Frank — Painless iOS Testing With Cucumber
http://www.testingwithfrank.com/
Frank はCucumber によるiOSアプリのテストを目的としたフレームワーク。マーティン・ファウラー でお馴染のThoughtWorks社に所属するPete Hodgson を中心に開発されている。
Frank の特徴はなんといってもCucumber のテスト環境をそのまま拡張して使っていることなんだけど。UISpec プロジェクトのUIScript というDSLをコンポーネントセレクタ(XPath, CSS セレクタのような)に利用していたり*5、ウェブブラウザ上で動作するインスペクタを使えるなど特殊なつくりになっている。
あと基本的にiOS シミュレータでの動作を想定しているみたい。
実際のテストは
のような流れ。
If all goes well, Frank has a lot of growing pains to look forward to!
http://moredip.github.com/frank_at_selenium_slides.html
Instrumentsユーザガイド
http://developer.apple.com/jp/devcenter/ios/library/documentation/InstrumentsUserGuide.pdf
alexvollmer/tuneup_js - GitHub
https://github.com/alexvollmer/tuneup_js
tuneup はUIAutomation のスクリプトに組込むアサーション用のライブラリ。UIAutomation は厳密にはInstruments(プロファイラ) の機能で、アプリの自動操作の記録、再生をしてくれるんだけど、これだけだと目視テストしかできない。しかしUIAutomation は外部ファイルをインクルードできるので検証用の関数などをまとめてあるのがtuneup。tuneup はUIAutomation 専用だけど、ここにJasmine とか組み込んでいる人もいた 。
Xcode/Instruments 4.2 からはXcode連携やコマンドライン実行などが強化されてなかなかよさげ。
Instruments新機能ユーザガイド
http://developer.apple.com/jp/devcenter/ios/library/documentation/WhatsNewInstruments.pdf
nativedriver - Native application GUI automation with extended WebDriver API - Google Project Hosting
http://code.google.com/p/nativedriver/
NativeDriver for iOS はGoogle が提供するテストフレームワーク。Google 東京オフィスで開発しているらしい 。Selenium にWebDriver というものがあり、それのネイティブ版という位置付けみたい。NativeDriver for Android もある。
NativeDriver の特徴はクロスプラットフォームを指標しているのでAndorid 用の受け入れテストとある程度の互換性があること。アーキテクチャ的にはFrank と同じくアプリにHTTPサーバを埋め込んでHTTPベースで操作するみたい。あとテスト時にはXoce とEclipse を併用する。
おまけ。
Sikuli はスクリプトにスクリーンショットの画像を組込んで自動テストする変ったプログラミング環境(確かOpenCV を使っている)。Sikuli プロジェクトにより開発されている。iOS アプリ開発向けではないがiOS シミュレータはMac アプリなのでiOS シミュレータに対してテストを実行できる。
MITの研究者が画面ショットを用いるスクリプト言語を開発|IT業界動向|トピックス|Computerworld
導入の手軽さ、設計のシンプルさからKIF 一択かなと思っていたんだけど
アップルのチートパワー*6によりUIAutomation の株も上ってきた
Frank は導入がムズ過ぎてまだ完全に動作テストできていない。Cucumber の知識を既にもっている玄人向けという感じがする
FoneMonkey はドキュメントもあってインストールも手軽でバランスが良さそう(突出して薦めたい箇所もないけど)。操作記録パネルなどはSelenium-IDE に使いごこちが近い。あと、ゴリラが怖い。
NativeDriver for iOS は信頼のGoogle かつ、日本人開発者なのも魅力。
こういう人にはこれがおおすめ、みたいなの。
受け入れテストはじめて : UIAutomation, KIF, FoneMonkey
Cucumber 使い: Frank
Selenium 使い: NativeDriver for iOS, FoneMonkey
Android アプリ開発者: NativeDriver for iOS, FoneMonkey,
紹介した各フレームワークは内部にUIAccessibility の技術を使っているようです。
受け入れテストしやすいアプリ=アクセシブルなアプリという効果もありますね。
iOSアクセシビリティプログラミングガイド
http://developer.apple.com/jp/devcenter/ios/library/documentation/iPhoneAccessibility.pdf
iphone - iOS Tests/Specs TDD/BDD and Integration & Acceptance Testing - Stack Overflow
References on Unit Testing & UI Automation for iOS Applications | Jojit Soriano's Blog
*1:実験的な機能
*2:ちゃんと決ってない http://goo.gl/7NpnB
*3:事前のビルドとインストールが必要
*4:UI Automation のみ
*5:が現在UISpec が独自実装に移行しようとしている所。Moving on from UISpec
*6:Xcode やInstruments の内部はサードデベロッパーには いじれない
なにを指しているのか文面から読みとれませんでした。
僕の解釈では「ユニットテスト」はテストレベルと呼ばれるものの分類の一部であり、
「機能テスト」はテストタイプと呼ばれるのの分類の一部です。
テストレベルは「動かす対象物の範囲」で区切ることがおおく、テストタイプは「テストの目的」から派生することが多いです。
なので、「機能テスト」という「テストタイプ」は「ユニットテスト」という「テストレベル」にも表われることが出来ます。(他のテストレベルだと「結合テスト」などがよくつかわれる単語だと思います。
なので、基本的には「ユニットテスト」と「機能テスト」は比較する性質が異なります。
ここの文面では「比較をしている」のか、直交するテストレベルとテストタイプをそれぞれ「列挙した」のか気になりました。
ユニットテストをテストタイプとして捉えているのかな。。。とも思ったのですが、まだそこの想像がついていません。
自分の知識の範囲内から解説としてこの文章は書いたんですが、テストレベル・テストタイプという考え方自体がなかったです。なので「ユニットテストをテストタイプとして捉えている」という解釈であっています。
表現したかったのは、「単体テストツールと呼ばれるものが既にあり、それとは別の目的に使用するテストツールがまた別にあり、それらの紹介」ぐらいのことです。
受け入れテスト、統合テスト、結合テストなどの一種の提唱者による用法の違いのひとつとして「機能テスト」という言葉も使っていたんですが、これらの用語と「機能テスト」は区別して使われていたんですね。