やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

QtのiOSアプリ生成を試してみた

Qt 5.2から、iOS/Androidネイティブアプリの生成がサポートされました。とりあえずiOSアプリについて試してみたメモ。

開発環境のインストール

Xcode

Xcode 5.1.1および、Xcode Command Line Toolsのインストールが必要です。

アプリを実機にインストールする場合、またApp Storeにリリースするビルドを行なう場合は、Xcodeメニューの[Preferences...]->[Accounts]画面でiOS Developer Programに加入しているアカウントを追加し、証明書とプロビジョニングプロファイルをダウンロードしておく必要があります。

Qt

今回はQt 5.3.1で確認しました。Download Qtからオンラインインストーラでインストールできます。

インストールパスは

/Applications/Qt/

としました。 ビルドに使用するqmakeなどのコマンドが、Mac OS Xネイティブアプリ向けの

/Applications/Qt/5.3/clang_64/bin

のほか、

/Applications/Qt/5.3/android_armv7/bin
/Applications/Qt/5.3/ios/bin

にもインストールされます。

Qtプロジェクトの作成

QtのIDEであるQt Creator.appを起動して"新しいプロジェクト"をクリック、テンプレートを選択します。 このとき「サポートされるプラットフォーム」が表示されますが、今のところ全てのテンプレートでiOSもサポートされているようです。

f:id:nowsprinting:20140702060952p:plain

テンプレートを選択したら、プロジェクトの格納パスを決定します。

f:id:nowsprinting:20140702061036p:plain

続いてキットを選択します。ここでiphoneos(実機用)とiphonesimulator(シミュレータ用)を選択します。

f:id:nowsprinting:20140702061048p:plain

そのほか、テンプレートに応じた設定などを確認すると、Qtプロジェクトが作られます。

Qtプロジェクトのビルド(IDE

そのままQt Creatorでアプリのビルドを実行してみます。 まず、メニューの[ビルド]->[ビルド/実行キットセレクタを開く…]を選択して下記ウィンドウを出し、キット=iphonesimulator、ビルド=デバッグを選択します。

f:id:nowsprinting:20140702063409p:plain

続いてメニューの[ビルド]->[実行]でビルド、iOSシミュレータへのデプロイ、アプリ起動まで実行されます(iOSシミュレータのバージョン、解像度は指定できないようです)。

また同様に、実行キットセレクタでキット=iphoneosを選択すると、USB接続している実機でアプリ起動まで実行されます。

Qtプロジェクトのビルド(コマンドライン

IDEでなく、コマンドラインでのビルド方法です。 まずqmakeコマンドで、QtからiOSプロジェクトの出力を行ないます。

$ /Applications/Qt/5.3/ios/bin/qmake -r

これでiOS向けプロジェクト(Xcodeプロジェクト)と、上記構成のプロジェクトであれば下記4種類のMakefileが生成されます。

続いてビルドターゲットに応じたMakefileを指定してmakeを実行します。

$ make -f Makefile.ReleaseDevice

ReleaseDeviceの場合、ビルドはRelease-iphoneos/HelloWorld.app/に出力されます。

ipaファイルの生成

.appからipaファイルの生成は、xcrunコマンドを使用します。生成されたipaファイルはそのままXcodeのオーガナイザやiTunesで端末にインストールしたり、TestFlightにアップロードすることが可能です。

$ xcrun -sdk iphoneos PackageApplication Release-iphoneos/HelloWorld.app -o $(PWD)/HelloWorld.ipa

iostoolコマンドでのインストール

Qt Creatorのiostoolによるインストール方法について、@IoriAYANEさんに頼まれた内容の確認を行ないましたが現在まだ成功していません。

端末UDIDの取得

端末をUSB接続した状態で下記コマンドを実行すると、端末のUDIDが取得できるようです。

$ /Applications/Qt/Qt\ Creator.app/Contents/Resources/ios/iostool -device-info

実行結果は以下の通りです。

<?xml version="1.0" encoding="UTF-8"?>
<query_result>
    <device_id>8af2b012d6ab166f897b91d8919c8812401c1fda</device_id>
    <device_info>
        <item>
            <key>developerStatus</key>
            <value>Development</value>
        </item>
        <item>
            <key>deviceConnected</key>
            <value>YES</value>
        </item>
        <item>
            <key>deviceName</key>
            <value>Koji Hasegawa の iPhone 5s</value>
        </item>
        <item>
            <key>osVersion</key>
            <value>7.1.2 (11D257)</value>
        </item>
    </device_info>
    <exit code="0"/>
</query_result>

なお、UDID自体はiTunesでも確認できますし、ビルドする前にプロビジョニングプロファイルに紐付ける必要もあるので、このタイミングで取得することは稀だとおもいます。

端末へのインストール

下記コマンドでインストールできそうなのですが、うまく行っていません。

$ /Applications/Qt/Qt\ Creator.app/Contents/Resources/ios/iostool -device-id 8af2b012d6ab166f897b91d8919c8812401c1fda -bundle Release-iphoneos/HelloWorld.app -timeout 10000 -run

実行結果(エラー)は以下の通りです。

<?xml version="1.0" encoding="UTF-8"?>
<query_resultCommandSession ERROR:  "failed to get app Path on device for bundle Release-iphoneos/HelloWorld.app with appId: com.nowsprinting.iostestautomationbook.HelloWorld">
    <msg>TransferAppSession(8af2b012d6ab166f897b91d8919c8812401c1fda, Release-iphoneos/HelloWorld.app)failed to get app Path on device for bundle Release-iphoneos/HelloWorld.app with appId: com.nowsprinting.iostestautomationbook.HelloWorld
</msg>CommandSession ERROR:  "Unexpected reply: ENo such file or directory () (454e6f20737563682066696c65206f72206469726563746f7279202829) vs OK (4f4b)"
    <msg>TransferAppSession(8af2b012d6ab166f897b91d8919c8812401c1fda, Release-iphoneos/HelloWorld.app)Unexpected reply: ENo such file or directory () (454e6f20737563682066696c65206f72206469726563746f7279202829) vs OK (4f4b)
</msg>
    <app_started status="FAILURE"/>
    <exit code="0"/>
</query_result>

-bundleに指定しているパス(.app)は存在し、メッセージ中のappIdはその.app下から読んでいるはずなので間違いないはず。

また、.appでなく上記xcrunコマンドで生成した.ipaファイルを指定しても同様のエラーかつappIdが表示されません。

独自のInfo.plistを使用する

iOSアプリのメタ情報を管理するInfo.plistファイルは、qmakeコマンドで生成されます。この中のCFBundleIdentifierなどを書き換えたい場合、以下の手順で行ないます。

1.あらかじめ専用のInfo.plistファイルを別名で作成する(ここではHelloWorld-Info.plist)

2.HelloWorld*1.proファイルに以下を追記する

QMAKE_INFO_PLIST = HelloWorld-Info.plist

これで、qmakeでデフォルトのInfo.plistは生成されず、続くビルドでHelloWorld-Info.plistが使われます。

*1:プロジェクト名

Travis CI Night に行ってきました #eytokyo

Engine Yard 東京オフィスで開催された Travis CI Night に行ってきました。

f:id:nowsprinting:20140327064058p:plain

iOSオープンソースライブラリにおけるCI環境の定番となっている Travis CI に関する国内初イベントとのことで、行ってきました。RubyPHPなどで利用されている方々のお話も聞けて、横のつながり的な良い感じのイベントでした。

会場は業務レベルのPaaSを提供する Engine Yard の東京オフィスさん。

Travis CIについて

以下、メモ書きから。メモしきれなかったので、安藤さんのスライドが公開されたらそちらを参照してください。

  • ベルリンの会社。今回主催の安藤さん@Engine Yardはベルリン好き(偶然の一致)
  • ベルリンといえば熊
  • サービス開始は2011年2月?(ドメイン取得がこのタイミング)
  • 特徴は、オープン、分散、即時。GitHubのパブリックリポジトリであれば無償利用可能
  • .travis.ymlに、最低限language:だけ指定すれば、デフォルトでよきに計らってくれる
  • language: objective-cで、Mac OS Xでビルド可能。他にも類似サービスはあるがMac OS X利用可能なサービスは少ない
  • Seleniumの利用が可能。WorkerにはFirefoxが入っている
  • .travis.ymlに直接書いて晒したくない情報は、travis encriptコマンドであらかじめ暗号化してsecret:記述することが可能
  • ビルド、テスト、Engine Yard などのPaaSへのデプロイ
  • FacebookTravis CI 日本語コミュニティ があり、Travis社の日本人エンジニアAsariさんもいるので、ジョインして盛り上げて欲しい

【3.27追記】安藤さんおよびLTのスライド、動画が公開されています。

iOSアプリ開発でもTravis CI

ついでに書籍の宣伝LTもしてきました。

スライドで触れていますが、本書の7.3でTravis CI、また8.1でCoverallsによるコードカバレッジ表示について書いています。

iOSアプリ テスト自動化入門

iOSアプリ テスト自動化入門

iOSアプリ テスト自動化入門 のサポート

【3/21】タイトルを変えました

拙著『iOSアプリ テスト自動化入門』が発売されました。このエントリで内容のフォローをしていきます*1ので、誤字・脱字、説明の足りないところ等ありましたら、コメントなどでご指摘ください。

iOSアプリ テスト自動化入門

iOSアプリ テスト自動化入門

Amazonさんでは在庫切れのようですが、お近くの書店等でぜひお手に取ってご覧ください。

サンプルコードはGitHubで公開しています。

本書の内容、想定読者、目次などについては、先のエントリを参照してください。

誤字・脱字・補足説明など

1.1.1 テスト自動化の必要性

3.2 GHUnit

  • Podfileに記述する識別子が、'GHUnitIOS'から'GHUnit'に変更になりました(ただしiOS 6以上)

3.3 Kiwi

  • Podfileに記述する識別子が、'Kiwi/XCTest'から'Kiwi'に変更になりました
  • サンプルコードで使用していた[KiwiStubAdditions stubAndReturn:]は非推奨になりました。[KiwiStubAdditions stub: andReturn:]に変更しています

5.3 Frank

5.4 MonkeyTalk

5.5.1 KIF(Keep It Functional)

  • XCTestに対応したKIF 3.0がリリースされています。Xcode 5.1ではKIF 3.0以降でないとビルドに失敗するようです

6.2.4 ビルドの配布方法

7.3.2 .travis.yml

8.1 コードカバレッジ

  • Xcode 5.1より、カバレッジ取得のための__gcov_flush()による回避策は不要となりました。サンプルコードでは以下を変更しています。
    • GenerateTestCoverageFor_iOS7を使用しない
    • Makefilecoverageルールを廃止し、testルールに統合

執筆に関して

企画自体は昨年前半に決まっていたのですが、仕事のスケジュール、Xcode 5・iOS 7リリースによる様々な影響もあって、ほぼ昨年一杯かかってしまいました。

企画当初からChapter 2にある「ユニットテストの書きかた、テスタブルなプロダクトコード」が中心でした。その軸は変わらなかったのですが、想定よりもChatper 7(CI)、Chapter 8(メトリック)にページを割くことになりました。
そもそも普段は一人で開発しているもので、余りこのあたりの恩恵を受けていませんでした。しかし書き進めるうち、またテスト自動化研究会などで話をするうち、現状ユニットテストすら無いプロダクトにおいて「CIや静的解析から入る」アプローチも有効だと感じ、それがページ数に反映された形です*2

また、勉強会などで質問を受けるたび、テスト自動化、それ以前にテストに関しての前提がまちまちであると感じており*3、この本がテストおよびテスト自動化へのスタートラインになるよう気を配ったつもりです。

今回、執筆はMarkdown、査読はGitHub上に上げた原稿をもとにIssueを上げていただく形で進めました。自動化の本を書いていながら、スクリーンショットを撮影したり捏造したり、校正以降はpdfを目diffするなど、昔懐かしい感じ(戻りたくはない)の手作業に追われて考えさせられたりもしましたが、なんとか形にすることができました。

*1:ブクマしてね!

*2:特にChapter 8は、当初Appendixだったものが昇格しました

*3:ほぼ、質問者の現状へのヒアリングから始まります

iOSアプリのテスト自動化本を執筆しました

まだ校正中なのですが、iOSアプリのテスト自動化入門(仮)的な*1タイトルの本を執筆しました。秀和システムさんから3月中旬ごろ発売予定です。

iOSアプリ テスト自動化入門

iOSアプリ テスト自動化入門

【3/7追記】Amazonさんで予約はじまりましたのでリンク追加しました

昨年Androidテスト部で書いた『Androidアプリテスト技法』は、テスト技法とテスト自動化が半々という構成でしたが、本書はほぼテスト自動化について特化した一冊です。

内容、想定読者

Xcode 5・iOS 7環境*2における、ユニットテストの書きかた、システムテスト〜受け入れテスト向けのツールフレームワークのほか、ビルドやAdHoc配布の自動化、CI、メトリック(メトリクス)採取など、アプリ開発にまつわる「自動化」できるものは盛り込みました。

また、自動化の手法・手段だけでなく、テストケースの洗い出し方、テストしやすいプロダクトコードを書くためのヒントなども、テスト用語の解説とともに書いてあります。

テストに関する用語は開発現場ごとにまちまちだと思いますが、開発者間でデザインパターンによる意思疎通ができるように、テスト用語にも拠り所があれば色々捗ると思っています。なので極力、ISTQBのソフトウェアテスト標準用語集に準拠し、引用も交えて紹介するようにしています。

「アプリ開発はできているが、テストは書いていない」という開発者をメインターゲットとしたテストの入門書として、過不足ない内容になっているはずです。

目次

全8章で、ページ数はChapter 2と3が多め、1と8は少なめ、他はほぼバランスしています。詰め混み具合は推して知るべし。

Chapter 1 テスト自動化への取り組み

  • 1.1 テスト自動化とは
    • 1.1.1 テスト自動化の必要性
    • 1.1.2 自動テストと手動テスト
    • 1.1.3 テスト自動化のROI
  • 1.2 テストの種類と自動化のスコープ
    • 1.2.1 テストレベル
    • 1.2.2 テストタイプ

Chapter 2 テストコードの書きかた

  • 2.1 モデルのユニットテストを書く
    • 2.1.1 XCTestの導入
    • 2.1.2 テストクラスの新規作成
    • 2.1.3 テストメソッドの作成
    • 2.1.4 テストの実行
    • 2.1.5 テストメソッドアサーションの関係
    • 2.1.6 テスタビリティの高い設計
  • 2.2 既存のアプリにテストを追加する
    • 2.2.1 不具合修正の前にテストを書く
    • 2.2.2 タイミング依存の問題に対してテストを書く
    • 2.2.3 テストを書くことが困難な場合
  • 2.3 ユニットテストのテクニック
  • 2.4 iOSアプリのテストTips
    • 2.4.1 テストフィクスチャをファイルでバンドルする
    • 2.4.2 NSUserDefaultsをクリアする
    • 2.4.3 アプリケーションデータを再現してテスト実行する
    • 2.4.4 Core Dataを使用しているアプリのテスト
    • 2.4.5 Core Dataをインメモリストアで使用する
    • 2.4.6 非公開メソッドをテストする
    • 2.4.7 例外発生をテストする
    • 2.4.8 性能テスト(処理時間の測定)

Chapter 3 ユニットテストフレームワーク

  • 3.1 XCTest
    • 3.1.1 既存プロジェクトにXCTestを導入する
    • 3.1.2 テストターゲットの依存関係
    • 3.1.3 XCTestのアサーション
    • 3.1.4 コマンドラインからXCTestを実行する
    • 3.1.5 OCUnitからXCTestへのコンバート
  • 3.2 GHUnit
    • 3.2.1 GHUnitをプロジェクトに導入する
    • 3.2.2 GHUnitのテスト実行
    • 3.2.3 GHUnitのアサーション
    • 3.2.4 非同期処理のテスト
    • 3.2.5 UIViewの表示テスト
    • 3.2.6 コマンドラインからGHUnitを実行する
  • 3.3 Kiwi
    • 3.3.1 Kiwiをプロジェクトに導入する
    • 3.3.2 Spec(仕様)の記述方法
    • 3.3.3 Expectations(期待値の評価)
    • 3.3.4 テストスタブによる間接入力の操作
    • 3.3.5 モックオブジェクトによる間接出力の検証
    • 3.3.6 プロトコルのモックオブジェクト
    • 3.3.7 非同期処理のテスト

Chapter 4 ユニットテストの補助ツール

  • 4.1 OCHamcrest
    • 4.1.1 OCHamcrestをプロジェクトに導入する
    • 4.1.2 OCHamcrestの使いかた
  • 4.2 OCMock
    • 4.2.1 OCMockをプロジェクトに導入する
    • 4.2.2 テストスタブによる間接入力の操作
    • 4.2.3 特殊な間接入力の操作
    • 4.2.4 モックオブジェクトによる間接出力の検証
    • 4.2.5 プロトコルのモックオブジェクト
    • 4.2.6 クラスメソッドの置き換え
    • 4.2.7 Nice Mock, Partial Mock
  • 4.3 OCMockito
    • 4.3.1 OCMockitoをプロジェクトに導入する
    • 4.3.2 テストスタブによる間接入力の操作
    • 4.3.3 モックオブジェクトによる間接出力の検証
    • 4.3.4 プロトコルのモックオブジェクト
    • 4.3.5 OCMockitoでは実現できないこと
  • 4.4 NLTHTTPStubServer
    • 4.4.1 NLTHTTPStubServerをプロジェクトに導入する
    • 4.4.2 NLTHTTPStubServerの使いかた
    • 4.4.3 レスポンス操作のバリエーション

Chapter 5 システムテストの自動化

  • 5.1 システムテスト自動化の予備知識
    • 5.1.1 システムテストの位置付け
    • 5.1.2 Drive, Judge, Report
    • 5.1.3 システムレベルの機能テスト自動化のROI
  • 5.2 UI Automation
  • 5.3 Frank
    • 5.3.1 Frankをプロジェクトに導入する
    • 5.3.2 cucumberコマンドオプション
    • 5.3.3 フィーチャとステップの記述
    • 5.3.4 Symbioteインスペクトツールの利用
  • 5.4 MonkeyTalk
    • 5.4.1 MonkeyTalkのセットアップ
    • 5.4.2 テスト対象アプリとの接続、キャプチャ&リプレイ
    • 5.4.3 MonkeyTalkのComponentとAction
    • 5.4.4 MonkeyTalkエージェントのアプリへの組み込み
  • 5.5 その他のテスティングフレームワーク
    • 5.5.1 KIF(Keep It Functional)
    • 5.5.2 Appium
    • 5.5.3 Calabash
    • 5.5.4 Zucchini

Chapter 6 ビルドと配布の自動化

  • 6.1 テスト用のビルドを作る
    • 6.1.1 Target, Configuration, Scheme
    • 6.1.2 xcconfigファイルの利用
  • 6.2 ビルドとテスト実行の自動化
    • 6.2.1 xcodebuild
    • 6.2.2 xctool
    • 6.2.3 バージョン番号、Copyrightの更新を自動化する
    • 6.2.4 ビルドの配布方法
  • 6.3 TestFlightによるビルドの配布
    • 6.3.1 TestFlightの利用登録
    • 6.3.2 Upload API
    • 6.3.3 テスターの登録

Chapter 7 CI(継続的インテグレーション

  • 7.1 OS X Server/Bots
    • 7.1.1 OS X Serverのインストールと設定
    • 7.1.2 Botsによるビルド実行設定
    • 7.1.3 ビルド結果の確認
  • 7.2 Jenkins
    • 7.2.1 Jenkinsのインストールと設定
    • 7.2.2 ジョブの設定
    • 7.2.3 ビルド結果の確認
    • 7.2.4 xctoolによるテスト実行とレポート
  • 7.3 Travis CI
    • 7.3.1 Travis CIの利用登録
    • 7.3.2 .travis.yml
    • 7.3.3 ビルド結果の確認

Chapter 8 メトリック

  • 8.1 コードカバレッジ
  • 8.2 静的解析
    • 8.2.1 Analyzeビルドアクション
    • 8.2.2 OCLintによる解析
    • 8.2.3 OCLintをJenkinsで実行する

Appendix

サンプルコードについて

サンプルコードは発売に合わせてGitHubで公開予定ですしました。

nowsprinting/iosAppsTestAutomationSamples · GitHub

ひとつのシンプルなアプリに対し、本書で紹介しているテスティングフレームワークを使ってゴテゴテとテストを書いています。それぞれのフレームワークによるテスト記述を比較できるはずです。

発売および予約開始はまだ先ですが、興味を持たれた方はお楽しみにお待ちください。

サポート

本書発売後のサポート、Xcodeバージョンアップへの対応などは、下記エントリを参照してください。

*1:あの日書いた本の名前を僕達はまだ知らない

*2:あんな変更やこんな変更がなければ、もっと早く出せていたはず…

GREE Tech Talk #04 スマートフォン時代のソフトウェアテスト に行ってきた #greetech04

最近テストづいている?勢いで、GREE Tech Talk #04 : スマートフォン時代のソフトウェアテストに行ってきたのでメモ。

WAPとかCiRCUSとかHT03AとかIS01とか懐かしいキーワードが出てきたりUnityの話が聞けたりと、幅広く、そしてスマートフォンの闇の深さを再認識できた良いイベントでした。

モバイルテスティング・クロニクル

まず松木さんの講演。モバイルおよびそのテストの歴史、現在(スマートフォン時代)に求められる品質モデルの話など。

  • アプリの品質要素、iOS/Androidともセキュリティ&プライバシーのプライオリティがダントツに高い
  • プライバシー保護については、セキュリティが確保されているのが前提

ちっともスマートじゃないスマートフォンアプリのテスト事情

GREEでTest Engineering Teamを立ちあげた山本さんの講演。

  • Androidは機種が多く、ユーザから不具合報告がある端末は高い確率で社内にない
  • 同じモデルでもキャリアや国によって違う。Galaxy S4だけで12種類のバリエーション
  • IS01みたいな変態端末
  • チップセットなどの要素をもとにペアワイズ法でテスト対象機種を絞り込む
  • アプリがテストチームに渡ってから2日でリリースされるので、できるテストが限られる
  • 先月からTest Engineering Teamを立ちあげ、
    • まずドリランドでリグレッションの自動化を進めている。新規機能は手動で行なう。テスト実行環境はエミュレータ
    • 課金機能について、Calabashで実機検証環境を整えようとしている

シェアカバー率について書き損じたので引用

Test Engineering Teamについてはこちらの書籍を参照

テストから見えてくる グーグルのソフトウェア開発

テストから見えてくる グーグルのソフトウェア開発

UnityによるGameObjectとコルーチンを利用したTestingフレームワーク

GREEの奥村さんの講演。

C#ユニットテストフレームワークとしてSharpUnitがあるが、以下の制約がある

  • 1フレームで完結するものしか書けない
  • テストのツリーをコードベースで編集
  • 失敗がログでしかわからない、どのテストが落ちたのかわからない

Unityにはそれぞれ補完できそうな機能が備わっているので、これらを改善できるフレームワークUniUnitTestを作った。これは近日オープンソース化されるとのこと。

Unityで作られたアプリがiOS/Androidで動くとは言っても、環境固有の問題は発生し得る。例としてアセットをアプリにバンドルしたとき、Androidではfile:///スキームでアクセスする必要があるなど*1

Jenkinsによるテスト自動化の会社への導入

太田さん@SHIFT、岡崎さん@GREE、粉川さん@SEGAによるパネルディスカッション。皆さんドンキで買ったJenkinsさんコスプレで登壇。

  • 内部品質はアプリの売上と必ずしも比例しない
  • ソシャゲのイベント投入などで上がる売上と、その修正にかかるコストの問題。コストが見合わないなら撤退
  • テスト自動化しやすいコードは既によくできている
  • 既存のテストの無いプロダクト、テスト自動化しにくい場合は「あきらめる」も選択肢
  • できるところからはじめる
    • ステートレスなユーティリティクラスはテスト書きやすい
    • 静的検証ツールを使う。その指摘を通じて保守性の高い設計と実装をチームに学習させることでテスタブルなコードに変わっていく。これはQAからの指摘ではなく、開発チームのアーキテクト主導で実施してもらった
  • ビルドやデプロイの自動化だけでも効果はある
  • テストコードのカバー率、数などにゲーミフィケーションを導入して改善していく。1000本目のテストコードを書いた人、など

静的検証ツールのところ、詳細を質問しておきながら自分でメモ取れてなかったので引用

最後にまとめとして一言づつ。

岡崎さん「"イノベーション"と大きく構えるのではなく、"工夫"で良い。たまに大発見もあるし、日々の工夫を積み重ねれば大きな改善になる」

太田さん「欲張らない」

感想

スマートフォンのテストに関して、その最前線にいるソシャゲ業界の実情や取り組みを聞ける大変貴重なイベントでした。

特にパネルディスカッションでは、チーム・組織にどのように自動化の文化を浸透させていくか、その手段としてのJenkinsや静的解析についての話が聞けて、大変参考になりました。*2

主催のGREEさん、登壇者の皆さん、ありがとうございました。

*1:Unityわからないので間違ってるかも

*2:ぼっち開発者なのですぐに役に立つわけではないですが、逆にとても気になっている分野なのです

システムテスト自動化カンファレンス2013で「スマートフォンアプリのテスト自動化をはじめよう」をお話してきました #stac2013

テスト自動化研究会主催のシステムテスト自動化カンファレンス2013にスタッフとして参加&モバイル枠をいただいてお話してきました。

システムテスト自動化カンファレンス2013ツイートまとめ - Togetterまとめ

毒食わば皿まで

古来より「毒食わば皿まで」という言葉がありまして、これはつまり「スライドを使いまわした*1ならブログエントリも使い回せばいいじゃない」という意味なのですが、さすがに心苦しいので以下オリジナルの補足をします。

尚、スライド自体もiOSに関する記述を追記したり*2、構成を見なおしたりしています。

テストレベルについての補足

途中で言った「『ユニットテストの話はするな』という圧力」はもちろん冗談なのですが、テストレベルに関して説明不足を感じたので補足します。

スライドでは「ユニットテスト」で済ませている部分、デブサミ2012でのAndroidテスト部講演や、書籍Androidアプリ テスト技法では「モデル*3ユニットテスト」を適切に切り出してテストすべきで、テスト困難なViewとControllerはシステムテストなど上位で実施すればいい*4のではないか、という方針でした。

それに対し、現時点では「モデルだけでなく、ビューのユニットテスト」まで行なった上で、Controllerはシステムテストで担保できれば良いのではないか、と考えています。

スライドにも「(システムテストでは)日時、天気、株価、為替、乱数などに起因するJudge*5を無理にはしない」と書いていますが、表示内容や最小桁/最大桁での見栄えはユニットテストで実施可能です。

もちろんUIの変更が発生するとテストのメンテナンスも必要になってしまうのですが、システムテストレベルで(スタブサーバを用意するなどして*6)実施するテストよりも楽に対応できるはずです。

尚、Viewのユニットテストを行なう前提は以下の二点です。

  • GHUnitなどイメージ比較をサポートしているテストフレームワークを使う
  • Viewに表示内容を渡す部分が切りだされている(MVVMにおけるViewModel的なもの。ControllerにsetText()等が書かれていないこと)

まずユニットテストからはじめなければ!という方は、テスト技法からユニットテストの基礎、Mockito、Robotiumなども載っているこちらの書籍をぜひお読みください(宣伝)

Androidアプリ テスト技法

Androidアプリ テスト技法

質疑応答(12/6追記)

これからモバイルのテストをやろうとする人へのオススメは?

まず、ちゃんとユニットテストを書きましょう。 開発者テストから入れない事情があるのであれば、Monkey Talkなどでハッピーパスから入ることをおすすめします。

モバイル向けWebアプリとネオティブアプリとの違いは?

システムテストなど上層のテストでは観点や手段などはほとんど変わらないと思います。ユニットテストなど開発者テストでは差があるはず。 WebViewのテストはMonkey Talkでもサポートされています。

システムテストではスクリプトを書くスキルは必要なのか?

自分は(開発者なので)ツールでキャプチャしたものより、スクリプトを書いています。 ひとつのアプリを複数の環境にカスタマイズしている場合など*7、キャプチャしたものをコピペしたものではメンテナンスが大変。

まとめ・感想

まずスタッフとして、手応えのある、とても良いイベントだったと思っています。講演すべて聞けたわけではないのですがどれもとても濃い内容でしたし*8、なにより会場の反応が良く、楽しんでいただけている雰囲気、一体感のようなものを感じられました。

テスト自動化研究会で初の主催イベント、しかもキャパ200人。研究会メンバーで運営にあたりましたが、事前準備、段取り、また会場をご提供いただいた日本オラクル様のサポート、また何より来場いただいた方々のご協力があって大きなトラブルもなく終えることができたと思っています。

自分の発表に関しては、Tizenとか自動化ハイ(©TABOK関西)とかがウケてよかったです。ハイと言えばDIO様のあれをネタ画像に使おうかとも思ったのですが自重したのが少し心残りです。

WebViewのテストについて

Seleniumハンズオン参加者の方から質問をいただいたそうなので(又聞き)ここで回答します。

アプリ内に組み込んだUIWebView/WebViewのテストは、少なくともMonkey Talkではサポートされています。

またSelenium自体にもAndroid Driverがバンドルされ、iOS向けにはios-driverというフレームワークも公開されているようなので、そちらも検討してみてはいかがでしょうか。WEB+DB PRESS Vol.77の特集1-3で紹介されていました。

WEB+DB PRESS Vol.77

WEB+DB PRESS Vol.77

  • 作者: 中川勝樹,山内沙瑛,舟崎健治,吉荒祐一,今井雄太,八木橋徹平,安川健太,近藤宇智朗,奥野幹也,天野祐介,賈成カイ,伊藤直也,住川裕岳,北川貴久,菅原一志,後藤秀宣,久森達郎,登尾徳誠,渡邊恵太,中島聡,A-Listers,小俣裕一,はまちや2,川添貴生,石本光司,舘野祐一,沖田邦夫,澤村正樹,卜部昌平,吉藤博記,片山暁雄,平山毅,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2013/10/24
  • メディア: 大型本
  • この商品を含むブログ (3件) を見る

12/3追記

@dageziさんより、RobotiumでもWebViewの中のエレメントにアクセスできるとの情報をいただきました。ありがとうございました!

*1:ひとつ前のエントリ参照。でも結構アドリブで違うこと喋ってるのです

*2:そもそもこちらがオリジナルで、Quesは後から決まった話なので削った、が正しい

*3:MVCのModel

*4:Controllerの責務にフォーカスするという意味ではなく、画面遷移やUIイベントを実行すれば確認できたと言えるので

*5:自動化の三要素(Drive, Judge, Report)からこう書いていますが、xUnitで言うAssertion

*6:そもそもスタブサーバを使うテストがシステムテストと言えるか、という話もあります

*7:これはちょっと例が悪かったのですが

*8:私のが一番内容薄くてごめんなさい感でいっぱいです

圧縮されたplistファイルをPythonで読む方法

事の発端は、iOSアプリのAdHocビルドをOTA配布するためのplistファイルを作って欲しいというリクエスト。

複数のビルドターゲットxコンフィギュレーションを使っているプロジェクトなのでbundle-identifierはbuildディレクトリ下のターゲット名.app/Info.plistから取得するしかなく、これが圧縮されていてplistLibで読めなかったのです*1

plutil を使う

OSXにはplutilというコマンドがあり、

$ plutil -convert xml1 -o xmlファイルパス 圧縮plistファイルパス

とすると、-oで指定したファイルにxml形式に展開されたplistファイルが出力されます。あとはこれをplistLibで読むだけ。

ビルドスクリプトへの反映

これを組み込んだビルドスクリプトはGitHubに晒してあります。くやしかったのでTestFlight Upload APIでアップロードするスクリプトも書きました。

nowsprinting/ios-build · GitHub

このスクリプトで扱っている複数のビルドターゲットxコンフィギュレーションの扱いについては、次の記事に書いてありますのでご参考になれば。

複数のTarget/Configurationを持つiOSプロジェクトの構成Tips - やらなイカ?

参考

圧縮されたまま読む方法をググっていたためplutilに辿りつけなかったのですが*2、GitHubのコード検索で見つけたこのプロジェクトのおかげで解決しました

jfoucry/xcodebuild-wrapper · GitHub

*1:plistLibのドキュメントに"sometimes compressed"って書いてあるのに、それをどう回避するかは書かれてなかったのです

*2:老害ですね!