|http://d.hatena.ne.jp/laiso+iphone/もうすでに終戦しているのに俺がジャングルに潜伏しているような状態になってはや1,2年。それ自体は別にいいんだけどはてなグループダイアリーの機能がだんだん貧弱に思えてきたのではてなダイアリーの方にポートしました。URL以外は別に変わりません。|https://itunes.apple.com/jp/book/test-driving-ios-development/id502345143?mt=11これ。News)先日、日本のiBooksStoreからでも有料の電子書籍が買えるようになったみたいなので、著者の@dimsumthinkingに連絡して日本のストアでも買えるように設定してもらった(日本人には滅多に話しかけないんだけど外国人相手だと英会話の練習がてらに気軽に問い合せてる)。iterations:10000];こういうの。プロファイラやなんかでボトルネックを探してて、ああここが遅いなというところを発見して、じゃあこういう風に変えようという案があるんだけどその時点での計測がしたいという時にコードの中にしのびこませる使い方がしたい。みんなどうやっているのかよく知らないけど(計測用のスニペットとかあるのかな)、そういう場面が度々あったのでRuby標準ライブラリのBenchmarkモジュールみたいなものが欲しいと思ってつくった。俺のたいがい解説くんタイプなので開発最新情報とかには詳しいけど実装はアヤしいのでライブラリとして妥当な感じかどうかはわからないけど、レビューedがわりにもなるしいいだとうとそのまま開陳している次第です。|更新:久しぶりにドキュメント確認したら、なんかもっといいやり方ありそうなので再考します:https://github.com/CocoaPods/CocoaPods/wikiCocoapodsでインストールできるようにしたい、だが公式リポジトリに含めないという段階の時どういう手順を踏めばいいのかというのを他の人の参考になるよう書いてみます。add`というコマンドで非公式なリポジトリを登録しておくことでpodコマンド経由でセットアップできるようになります。PEARが一番イメージしやすいかも(非公式なリポジトリ使う場面が多いので)。ライブラリを書く通常のアプリを開発する時のような感覚でXcodeプロジェクトを作成します。ライブラリのビルド設定も要りません。ここがCocoapods環境のライフチェンジングなポイントだと思っているんですが、Cocoapodsでのインストールを前提にしていると開発者はめんどうなインストール用のスクリプトやファットバイナリやFramework形式を容易する必要がなくなり、ライブラリユーザーはハマりがちな依存ライブラリのセットアップやXcode設定を一切しなくてよくなります(Win-Win)。MyLibraryExampleというサンプルアプリプロジェクトを作成し、依存ライブラリはPodfileに記述してインストールし、MyLibraryというディレクトリを作成し、ライブラリに含めるソースコードは全部その中に置くという手順を踏むだけでもう公開する準備が整います。開発中はユーザー向けのソースコードをMyLibraryExampleに書き、開発者向けのソースコードをテストターゲットに追加して。MyLibraryExample.appで結合テスト+Xcodeでユニットテストを実行するというスタイルにするとテンポよく実装できます。GitHub")を採用しているようです。ライブラリ実装用の使いやすさもあるんでしょうが。以前以下に投稿した記事のような感じで。ローカルの作業スペースを掘ります。'v0.1.0'}のようにしてローカルにあるgitブランチを指定すればいいだけなので、ネットワークレスに作業できます。ライブラリを公開用Gitリポジトリに配備Githubでもどこでもチェックアウトできる場所につくるだけです。--tags`でリモートブランチにも反映されるようにしておきます。spec用のGitリポジトリを用意GithubじゃなくてもいいですがGithub前提で進めます。Githubを使うのは公式リポジトリがあってそれをフォークした方が、今後公式へpull-requestする際などに都合がいいからです。自分のアカウントでフォークしてください。specリポジトリのbeta配布用のブランチを作成このままでも使えはするんですが、公式のpodspec群がフルセットでコピーされてしまうので新たなブランチを作成して一旦真っ新な状態にします(masterは基本的にpull-request用のトピックブランチを作成する前に公式リポジトリの更新を取り込むだけ)。実際のライブラリユーザーは以下のようなコマンドを実行することになりますのでドキュメントなどに記述しましょう。iPhoneアプリ開発グループこの頃はあんまり良いライブラリが他になかったので自分で作ってたけど、今はいろいろ良いものが出てきているので実際の使い方などを紹介します。モックとスタブスタブという言葉が以降よく出てくるんですが、基本的には以下文章などを目を通した上で、「リクエストのモックオブジェクトがスタブの振舞いをして偽のレスポンスを返す」というような表現を使います。APIメンテ中デバッグできないなど)サンプルコードについてサンプルコードは以下。API呼び出しクラスのメソッドをテストする。FakeResponse/インストールできそうなものはcocoapodsで入れる。}];}非同期処理のテストについて、akisuteさんのSenAsyncTestCaseを使っている。NSURLProtocolに準拠したクラスを登録し、読み込んだURLに対するレスポンスを制御するCocoa/Foundation標準のURL読み込みシステムを使って、リクエスト・レスポンスの挙動をフックして処理する。柔軟になんでもできるので一応これが主流だと思う。冒頭のURLで提示した試作品と同じやり方。範囲がURL読み込みなんでもなのでUIWebViewとかにも適用される。Nocillahttps://github.com/luisobo/Nocilla/LSNocillaにstart/stopの命令を送ることでリクエストオブジェクトとそこから返ってくるレスポンスをスタブ化できる。するとテストメソッド実行ごとに真っ新にする。clear]っているメソッドもあるんだけどstop内から呼ばれている。公式ドキュメントだとBDDスタイル(Kiwi)のbeforeAll/afterAll/afterEachなんかを使ってテストケース全体でstart/stop、テストごとにclearと、効率よく書けるというのをすすめているみたい。リクエスト・レスポンスの返り値は以下のような内部DSLで定義する。\"ok\""}");andReturn以前がリクエストの定義で、以下がそれにマッチした際に返すレスポンスになってる。マッチするかというのはURL、HTTPメソッド以外にヘッダやBodyも見ててそれも一致しないと「スタブ化されたレスポンスがありません」的なエラーが出ると思う。waitForTimeout:3];}これだけでURL読み込み状態に依存しない、常に同じレスポンスが返ってくるテストへ分離できる。JSONテキストのレスポンスをベタに貼るとNSStringの都合上ダブルクォートをエスケープしなきゃいけないのと、ちょと弄った時にJSONスキーマエラーとか出てないかとデバッグするのに都合がいいので外部ファイルに書き出してfixturesにしておいた方がいい。curlコマンドとかブラウザで直接取得した実際のレスポンスをコピペしておく。waitForTimeout:3];}responseTimeでダウンロード速度も指定できる。スタブ化しないリクエストにはOHHTTPStubsResponseDontUseStubを返すようにすると実リクエストが発行される。NSURLConnectionやASIHttpRequestのメソッドを置き換えるタイプこれはNSURLProtocolのCocoaのhooksの仕組みを使うのではなく、Objective-Cランタイムに定義されているmethod_exchangeImplementationsで実オブジェクトの実装を置き換えてスタブ化する。Swizzlingでのレスポンス置き換えについては、以前からよくpracticeとしてブログで書いている人たちが居た。利用して対象のクラスメソッドの実装を入れ替える。置き換える先はクラスメソッドではないのがポイント。nil);}が、これだとloadItemsWithTag:completionHandler:内部で実装しているJSONのパースやエラー処理を全部すっとばして、望んだテスト用レスポンスを検証しているだけで、自作自演状態になっているのであんまり意味がない。今度はテスト対象のQiitaAPIクラスではなくて、メソッド内部で依存しているNSURLConnectionのsendAsynchronousRequest:queue:completionHandler:だけを置き換え必要最小限にする。nil);}FakeWebhttps://github.com/dealforest/iOS-FakeWeb同名のrubyコミュニティで有名なモジュールがあり、そのiOS版的な位置付け。waitForTimeout:3];}NSURLConnectionVCRhttps://bitbucket.org/martijnthe/nsurlconnectionvcrこれは正確にはレスポンスをスタブ化するモジュールではなくて、リクエストの記録、結果をキャッシュして繰り返しのテストに使って実行速度とネットワーク依存を改善するためのものらしい。Rails向けにVCRというモジュールがもともとあり、それに着想と得てCocoa向けに使えるようにしたものみたい。cloneできね〜」と思っていたらGitリポジトリだった。tearDown];}ドキュメントそのままだとパスに書き込み権限なくて動かないので注意。以下に保存できるように指定した。何が保存されるかというとバイナリPLIST形式でシリアライズしたものです。自身にHTTPサーバーを立て、リクエストURLに対してレスポンスを制御するこれはリクエストやレスポンスをスタブ化するのではなくて、リクエストする先のサーバーの方をスタブ化するようなイメージ。ウェブアプリ開発だと、本番サーバーからローカルの開発サーバとアクセス先を切り変えるけど、そのローカルサーバーがアプリ自身内に埋め込まれているという違いがある。リクエストやレスポンスオブジェクト自体には手を加えないので、黒魔術的な意図しない動作は起きにくいのが利点と言える。アクセス先ホストをテスト時に動的に変えてやる必要がある。NLTHTTPStubServerhttps://github.com/yaakaito/NLTHTTPStubServer日本人開発者のyaakaitoさんが作っているモジュール。セロリ食べたいなどを参照。}];}最終的にテストがこう書ける。Swizzlingより副作用もなくて、内蔵ウェブサーバーより手軽なので、まずこの2つから候補にして使ってみるといいでしょう。見ユーザー多そうなのはNocillaの方です。|iOS向けの受け入れテストフレームワークはたくさん出揃っているんだけどMacアプリ向けのは全然話聞かないなあ、と思っていたので試してみた。KIFとはKIFはiOSアプリ向けの受け入れテストツール。ユーザーから見たアプリの正しい振舞いを検証する。ユーザー操作をエミュレーションするAPIを備えたライブラリを使ってシナリオを記述し、アプリに含めてビルドして実行する。iPhoneアプリ開発グループMac版KIFとはMac版KIFはGithub上で@joshaberによってフォークされている。iOS版KIFをベースにいくつかのMac版のサポートコードが追加されている。GitHubはじめようまずXcodeからテスト対象となるCocoaアプリケーションを作成します。今回は"KIFMac01"という面白気のない名前で作成しました。仕様としてはウィンドウ中央にあるHelloボタンが押せるというだけのアプリケーションです。MainWondows.xibを開いてPushボタンのパーツを追加します。ダブルクリックしてタイトルをHelloにします。これでアプリケーションは完成です(!)。ビルド実行してアプリケーションがただしく使えるかを手動でテストしてみてください。したら次は自動テスト用のビルドの為に下準備をします。利用して取得したMac版KIFのソースをプロジェクトにインポートします。