Hatena::Groupiphone-dev

laiso

 | 

2012-01-11

iOS アプリ開発向け受け入れテスト/結合テストフレームワークのまとめ

20:07 | はてなブックマーク -  iOS アプリ開発向け受け入れテスト/結合テストフレームワークのまとめ - laiso

はじめに

最近iOS アプリ開発向けの受け入れテストに興味があっていくつか使ってみたのでフレームワーク概要、比較などをした。


いきまりまとめ

iOS アプリ開発向け受け入れテストフレームワークはまだどれも成熟していなく、まだそのプロジェクトのコントリビューターになれる人ぐらいしかうまく使えないかもしれないが、受け入れテストの自動化は将来的にも有用であるので投資すべき。


iOS アプリ開発向け受け入れテストフレームワーク の定義

ここでいう「iOS アプリ開発向け受け入れテストフレームワーク」とは「iPhone/iPad アプリ開発において、開発者がユーザーの為にアプリケーションが仕様どうり動作する(振舞う)」ことをテストすることを目的としたもの。

なので「開発者が実装・設計・リファクタリングなどの為にコード/クラスの動作(振舞い)をテストする」という目的のTDDにおける単体テストと区別する為だけに使っている。

単体テストは実例をあげるとXcode 組込みのSenTestKit やGHUnit なんかで実行しているテストが該当する。ただこのあたりの境界はあいまいで人によって領域が違ったり呼び方も異ったり同じ用語の意味が別だったりする(iOSアプリ開発コミュニティだと"UI テスト" という用語を使う人もいる)、のであんまり気にしない。

たとえば"iOS開発ガイド"にもロジックテスト, アプリケーションテストという用語を使っているしGHUnit でもビューコントローラーのテストができる。違うのはユーザーはビューコントローラーのプロパティを読み込んで画面に文章が表示されているか確認できるわけでもないし、直接ボタンアクションの関数を呼びだすわけでもない—— といえばわかりやすいのか、単に内部からのテストか外部からのテストかと表現した方がいいのか。

ウェブアプリ開発の知識がある人向けだと、テストヘルパーなどでリクエストとレスポンスのオブジェクトからテストを実行しているのと、mechanizeSeleniumPhantomJS でHTTP クライアントでサーバプロセスにテストを実行しているような違い。かなあ。

iOS開発ガイド - アプリケーションの単体テスト

http://developer.apple.com/jp/devcenter/ios/library/documentation/Xcode/Conceptual/ios_development_workflow/index.html#135-Unit_Testing_Applications/unit_testing_applications.html#//apple_ref/doc/uid/TP40007959-CH20-SW3

受け入れテストはどちらかと言えば顧客のためのテスト。受け入れという名の通り、このテストがパスすればその機能は実装が完了したとわかり、顧客の立場からすると要件が正しく実装されていること、進捗が管理しやすいなどの利点がある。

(UKSTUDIO - BDDについて自分なりにまとめてみた)

ソフトウェアテスト - Wikipedia


比較表

名前テスト記述言語テスト実行操作からテスト生成実機動作依存CIサポートライセンス
KIFObjective-CXcodeNOYES-Apache v2
FrankGherkin(Cucumber), RubyCucumberNO- *1Cucumber, Ruby- *2
Sikuli IDESikuli Script(Jython)Sikuli *3YESNOSikuli ランタイムMIT
FoneMonkey for iOSObjective-C(SenTestKit)/Javascript(QUnit)Xcode(テストバンドル)YESYES-GPL v3
UIAutomation+tuneupJavaScriptXcodeYES *4YESInstrumentsLICENSE
NativeDriver for iOSJavaEclipse,コンソールNOYESJavaApache v2
補足

CI サポートと設けた項目は

◎: 公式ドキュメントに載ってる

○: 使える。使ってる人がいる

△: 不可能ではなさそうだが不明

×: 仕様的に不可能

という感じ。

そもそもCI サポートとは何かというのもあるけど、だいたいのところで「Jenkins からビルドやテストを実行できてテスト結果のレポートなどを読めるようになる」ぐらいの意味です。


KIF

square/KIF - GitHub

https://github.com/square/KIF

KIF は公式には"iOS integration test framework"と謳っているんだけど前述の用語の使い方の違い参照で同じようなものです。Twitter共同創設者のジャック・ドーシーが立ち上げた Square っていう会社が作成しているオープンソーソライセンスのライブラリ。

特徴はsenario, step, feature という語彙を使ってObjective-C でテストコードを書くこと。

自動テスティングフレームワーク "KIF" | Cocoaの日々情報局

http://cocoadays-info.blogspot.com/2012/01/kif.html


FoneMonkey for iOS

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 のフォーマットになるみたい。ドキュメントが充実している。あとダウンロードにユーザー登録が必要。

以前から存在自体は知っていたんだけど、個人的なトラウマによりウェブサイトのゴリラの画像が怖過ぎてなかなか開けなかった。

FoneMonkey for iOS のアーキテクチャ解説

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


Frank

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 シミュレータでの動作を想定しているみたい。

実際のテストは

  1. アプリをビルドして起動
  2. アプリに埋め込まれたHTTPサーバ(CocoaHTTPServer)がlisten
  3. サーバに対してHTTP ベースでテストを実行。サーバはリクエスを解釈してネイティブAPI を呼び出す。

のような流れ。


Frank アーキテクチャ解説

If all goes well, Frank has a lot of growing pains to look forward to!

http://moredip.github.com/frank_at_selenium_slides.html


UIAutomation + tuneup

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 for iOS

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 IDE

おまけ。

Sikuli はスクリプトにスクリーンショットの画像を組込んで自動テストする変ったプログラミング環境(確かOpenCV を使っている)。Sikuli プロジェクトにより開発されている。iOS アプリ開発向けではないがiOS シミュレータはMac アプリなのでiOS シミュレータに対してテストを実行できる。

MITの研究者が画面ショットを用いるスクリプト言語を開発|IT業界動向|トピックス|Computerworld

http://bit.ly/xlSgoK


個人的な総評

導入の手軽さ、設計のシンプルさから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

http://stackoverflow.com/questions/4114083/ios-tests-specs-tdd-bdd-and-integration-acceptance-testing

References on Unit Testing & UI Automation for iOS Applications | Jojit Soriano's Blog

http://jojitsoriano.wordpress.com/2011/06/03/references-on-unit-testing-ui-automation-for-ios-applications/

*1:実験的な機能

*2:ちゃんと決ってない http://goo.gl/7NpnB

*3:事前のビルドとインストールが必要

*4:UI Automation のみ

*5:が現在UISpec が独自実装に移行しようとしている所。Moving on from UISpec

*6:Xcode やInstruments の内部はサードデベロッパーには いじれない

kyon_mmkyon_mm2012/04/10 15:27ここで語られている「ユニットテスト」と「機能テスト」の定義を教えてください。
なにを指しているのか文面から読みとれませんでした。

僕の解釈では「ユニットテスト」はテストレベルと呼ばれるものの分類の一部であり、
「機能テスト」はテストタイプと呼ばれるのの分類の一部です。
テストレベルは「動かす対象物の範囲」で区切ることがおおく、テストタイプは「テストの目的」から派生することが多いです。

なので、「機能テスト」という「テストタイプ」は「ユニットテスト」という「テストレベル」にも表われることが出来ます。(他のテストレベルだと「結合テスト」などがよくつかわれる単語だと思います。
なので、基本的には「ユニットテスト」と「機能テスト」は比較する性質が異なります。


ここの文面では「比較をしている」のか、直交するテストレベルとテストタイプをそれぞれ「列挙した」のか気になりました。
ユニットテストをテストタイプとして捉えているのかな。。。とも思ったのですが、まだそこの想像がついていません。

laisolaiso2012/04/10 16:18「iOS アプリ開発向け受け入れテスト/機能テストフレームワーク の定義」あたりの文章ですね? 確かに読み返しして見て違和感を感じそうなポイントはわかりました。
自分の知識の範囲内から解説としてこの文章は書いたんですが、テストレベル・テストタイプという考え方自体がなかったです。なので「ユニットテストをテストタイプとして捉えている」という解釈であっています。
表現したかったのは、「単体テストツールと呼ばれるものが既にあり、それとは別の目的に使用するテストツールがまた別にあり、それらの紹介」ぐらいのことです。
受け入れテスト、統合テスト、結合テストなどの一種の提唱者による用法の違いのひとつとして「機能テスト」という言葉も使っていたんですが、これらの用語と「機能テスト」は区別して使われていたんですね。

 |