朝早く起きてしまったのでiOSのユニットテストについてまとめる その2


予定がないのでiOSにおけるユニットテストについてまとめる その1
という記事を昨日書いたんですが、なんとなく早起きしてしまい寝るのも癪なのでユニットテストの記事の続きを書きます。

↑の記事ではiOSでのユニットテストの方法や、必要性などについてまとめました。
調べているうちに継続こそテストなりという一つの心理が見えてきた気がするので、今回はそんな継続を実現する方法や、プロジェクト管理などの視点も含めて書いてみようかと思います。

継続的にテストをしよう

「継続こそテストなり」とはいうが、具体的になにをしたらええんや!というのはよく思うこと。
個人でアプリを開発していてもテストを書かないままローンチなんてよくあるし、なくてもそこまで困ったことはない。
でもなんで世の中テストテストと言うのか。

継続的インテグレーション

continuous integration = CI とよばれるやつです。
いろいろな会社がいろいろなやり方で実現しています。

継続的にテストやビルドを実行して、いつでもリリースできるよね?って状態を維持する取り組みみたいな認識でいるが、ここらへんは狭義・広義の意味があったり文献によって違う意味を持つことが多い。
その目的はいずれも回りに回って、継続的なリリースを維持しつつエンジニアの安眠を作るために仕組みやツールの実現。

*参考
nanapiのCI
cookpadのCI
yahooのCI

webにおけるCI

エンジニアのコミット

Githubでマージリクエスト

mergeされるとビルド・テストが走る

結果を通知

成功すればDeploy

基本的なフェーズは上記のようなもの。
その角フェーズで使うツールや、通知の仕組み、ルール作りをいろいろな会社がその会社ごとの文化(エンジニアだけでなく、それをとりまく企画やデザイナー、その他稀にいる面倒な人々)を内包して醸造している。

webでは当たり前の仕組みだ。歴史もあり、ツールも多い。
しかしiOSにおいてはあまり馴染んでないようにも思える。

iOSにおけるCI

ではなぜiOS業界においてCIってやつが一般的にならないのか。
それがCIの仕組みが結構複雑で、導入もjenkinsいじったりrubyを書いたりiOS以外の知識も多く必要になる。でも一番はiOS開発はリリースまでに人の手が入らなければいけない作業がめちゃくちゃあるからだと思う。

作業リスト

  • 振る舞いテスト
  • 統合テスト
  • Xcodeからの申請
  • ビルドが上がったらitunesConnectの準備完了のステータス変更を待ち
  • リリースノートを決め、申請ボタンを押す
  • etc...

iOSにおける振る舞いテスト

これにはいろいろな取り組みがされては消えてきた・・・
だが次のXcodeでとうとう公式にUI Testingという仕組みが入り、Seleniumのように動作を記録してテストケースを作ることができる。
ただただ最高である。まだあまり触ってないのでメリデメを把握していないが、絶対便利だ(信者感)
なのでここは便利になりそう◎

(後日)Recordingでちゃんとテストコードが吐かれるけど、実行できないことが多い・・・

iOSの自動デプロイ(申請)の取り組み

こいつだ。こいつなんだよ。
webでいうデプロイってやつはiOSはAppleに申請することを言うと思うんだが、こいつは全然スマートじゃないんだよ。
毎回毎回一応providioningを確認して、schemeのビルドをチェックして、Archieveしてsubmit storeボタンを押して。。。なんだかんだで30分とか平気でもってかれる。バイナリがでかい場合、iTunesConnectも処理に時間かかってバイナリあげてからも15分くらい待つ必要もある。
しかも失敗することもあるし、やっているあいだXcodeいじれないからなんもできない。
ほんとiOS開発における作業のボトルネックだよ!といつも思いながらも、「今回も申請通ってくれ!」ってサンフランシスコに祈りながら申請作業をしている。

Xcode6.3.X前はビルドコマンドを駆使したりして前はできたらしい。

今でもitunesConnectをハックしてクローリングするみたいに自動化する手段は作れる
AppStore申請を一式まるっと自動化する

他にもiTunesConnectの非公開APIを使ってみたり、やり方はいろいろあるが安定してないし、正規の仕組みじゃないからどこでほころびが出て失敗するかわかったもんじゃない!

ここを自動化できたとしても、申請してから数日は待たなければいけないし、なにかバグがあってもロールバックなんてできない。
これが本当に怖い。強制アップデートの仕組みを実装することはできるけど、ユーザーさんってだいたいアップデートするより消す方が簡単だから使えなかったら消しちゃう。

iOSにおけるCIで意識するべきwebと違う部分

まとめてみると上記のようなものがあると思う。

  • デプロイの自動化の難しさ
  • ロールバック不可能
  • 申請は手作業でやらなければいけない(ことが多い)

自動化できない⇨仕組み化できない⇨属人化という悲しき流れを生みがちだ。
これがあるからまだiOSエンジニアは世界で足りない足りない言われているんじゃないかと思うこともある。

iOSの継続的なユニットテスト

なんのツールで実現するか?

bot

iOSアプリで継続的インテグレーションする”Bot”の導入手順と注意点
iOSでのCIツールには公式のもので上記のようなbotと呼ばれるツールもある。
以下の実行を自動でやってくれるので、すべてのCIのプロセスを担保することは難しいかもしれないが、
大体はやってくれる認識である。

  • 自動ビルド
  • インテグレーション詳細情報の表示
  • BigScreenによるコクピット画面の表示
  • Analyze(静的解析)の実施
  • UnitTestの実行
  • ipaファイルの作成と配布
  • ビルド後のメール送信

*参考
Xcodeでbotを設定する

fastlane

開発者がイケメンで有名な最近出てきたiOSのCIツールだ。
fastlane

fastlaneは,iOSアプリをApp Storeに新規に提出する,あるいはアップデートする場合に通常必要なタスクの大部分をカバーする,rubyスクリプトのコレクションである。

どうやら今まで不可侵の領域だった申請の部分を網羅してくれるそうだ。
ビルドツールを独自に作っているか、itunesConnectのプライベートAPIを使っているか中身は定かではないが、先日来日していたり今後注目のツールになること信じている。

思想

ユニットテスト改善ガイドを読んだらいろいろと解決した。
概ね読んでおけば、「継続してテストを書き続けるために意識すること」を知れる気がする。と思った・

まとめ

結局のところiOSにおいてユニットテストは書いたほうがいいのか?っていう疑問に対して自分としての答えは、
「すぐ書かなくてもいいけど、いつでも書ける状態にしておこう。余裕のあるときにutilクラスかModelあたりから書いていこう」
というものになった。

ユニットテストなんてかければそりゃあいいものだ。でも時間はない、常にデザイナーが画面仕様書お送ってくるし、企画はリリース日を迫ってくるし、ユーザーさんは不満を言ってくる。
それでも毎日安心して寝るための仕組みづくり、それをいつでも導入できるようなコードや設計にしておかないと、技術的負債ってやつは溜まりに溜まってしまうだろう。
サービスがスケールするといつか絶対テストを書く。いつでも書けるようにしておこう。