寄付窓口はこちら

クックパッドアプリのテストを味わう | try! Swift Tokyo 2017 #tryswiftconf Day1-8 聞き起こし

twitter.com

品質やテストの話は往々にして提供するサービスやアプリのコンテキストに依存します。クックパッドiOSアプリを題材にして、私たちが機能的な品質を保つためにどのようなテストを行ってきたかをお話します。特に、自動化されたテストに関してお話します。UIのリニューアルや様々な取り組みと変化だけではなく、Objective-CからSwiftへの書き換えなど、iOSを取り巻く環境は短い間に大きく変化しています。その中で、どのような取り組みにより最低限の不具合を防ぎ、iOSアプリをリリースし続けてきたのか。また、これにより得られた学びや、これからの取り組みに関してもお話しいたします。

クックパッドアプリのテストを味わう

f:id:niwatako:20170302150339j:plain

私はテストエンジニアなのでテストの話をします。

f:id:niwatako:20170302150409j:plain

テスト自動化やプロセス改善、組織改善に関わっています。

Swift, Ruby, Java, Elixerなどを使っています。

f:id:niwatako:20170302150452j:plain

テストと言ってもたくさんの意味やテーマが有ります。

f:id:niwatako:20170302150510j:plain

テストレベルとオートメーション、UIテスト、テストがどのように開発をサポートしているかをお話します。

f:id:niwatako:20170302150530j:plain

私たちのプロダクトでのケーススタディをお話します。

f:id:niwatako:20170302150549j:plain

テストの対象についてまず説明します

テスト対象の知識は、テスト戦略やケーススタディ理解を手助けしてくれます

f:id:niwatako:20170302150614j:plain

クックパッドはレシピ共有サイトです。

f:id:niwatako:20170302150625j:plain

f:id:niwatako:20170302150635j:plain

日本向けとそれ以外でアプリケーションが有ります。サービスレベルが違うので二つは統合されていません。

f:id:niwatako:20170302150700j:plain

日本向けのアプリの話をします。

f:id:niwatako:20170302150709j:plain

5年成長を続けています。

スクリーンショットで変化を示しています。UIは複数回大きく変え、実装も大きく変えています。

プロダクションコードは10万行ぐらい。

この間何度もリリースしています。最近のサイクルは1ヶ月ぐらいのサイクル。以前は2週間でした。ソースコードは5千から1万行に変わっています。

内部のロジックも書き換えたりしています。

f:id:niwatako:20170302150823j:plain

MustBeはクラッシュしないこと

f:id:niwatako:20170302150900j:plain

f:id:niwatako:20170302150927j:plain

どれぐらい長い間開発されてきたか、日本市場・モバイルでのクオリティについて話しました。

ではどのようにエンジニアリングしているか

f:id:niwatako:20170302150953j:plain

f:id:niwatako:20170302151009j:plain

継続的に開発してきてこれからも変化します。

モバイルアプリについてはリエンジニアリングをしました。

テストターゲットを変えて継続的開発を可能にし開発速度を維持師でグレードを起こさない。

ユニットテストリファクタリング前に書くことは不可能なこともある(??)

f:id:niwatako:20170302151045j:plain

機能はテストをせずにリファクタすると問題が起きる。

f:id:niwatako:20170302151122j:plain

リエンジニアリングのアプローチは2つ

内部と外部。

コードの話しとユーザーからみたのUI

f:id:niwatako:20170302151203j:plain

もしバグがあったらリリース前に修正をかけます

f:id:niwatako:20170302151219j:plain

f:id:niwatako:20170302151231j:plain

自動化テストだけでなく、UnitTestが完全に自動化されると言えば、殆どの開発者に合意してもらえると思うが、

f:id:niwatako:20170302151257j:plain

他のテスト、たとえば結合などであればこのレベルは下がります。

ただ最も自動化が必要なのはUIです。

多くの場合時間があまりにかかってしまいます。モバイルテスト自動化は難しいからです。

f:id:niwatako:20170302151338j:plain

これは理想のテストのピラミッドです。

UnitTestが一番多く、UIが一番少ない

f:id:niwatako:20170302151357j:plain

f:id:niwatako:20170302151403j:plain

モバイルは容易に逆になる

f:id:niwatako:20170302151417j:plain

これを逆にしたい

f:id:niwatako:20170302151438j:plain

人を介すること無くチェックできるように

Itunes Connectのクラッシュ件数

f:id:niwatako:20170302151503j:plain

どんどん下がっています。

2015年以前はもっと高い数値でした。

この間ずっとリリースをして活発化しています。 この結果を見ていただくとクラッシュレート減少を達成

f:id:niwatako:20170302151536j:plain

f:id:niwatako:20170302151550j:plain

今はスクリーンの遷移の8割を自動化されたUIテストしています。

これがアーキテクチャです。

f:id:niwatako:20170302151609j:plain

エンドユーザー間の独立性を担保

f:id:niwatako:20170302151639j:plain

シナリオは"ターニップ"で定義しています

f:id:niwatako:20170302151705j:plain

f:id:niwatako:20170302151717j:plain

味付けということで幾つかヒントを

f:id:niwatako:20170302151731j:plain

内部ロジックに依存せずにテストすること

f:id:niwatako:20170302151803j:plain

f:id:niwatako:20170302151812j:plain

f:id:niwatako:20170302151831j:plain

UIテスト拡張にさらに取り組み

内容のテストだけでなくレポートもする

f:id:niwatako:20170302151900j:plain

相違をデザイナが簡単に確認できる。

f:id:niwatako:20170302151929j:plain

ネットワークトラフィックもチェックしている

f:id:niwatako:20170302151943j:plain

なにか変更で壊れるとUIテストでエラーが発見される。

f:id:niwatako:20170302151959j:plain

数ヶ月前にSwiftを導入し3割近くがSwiftで書かれている。

UI、リクエストレベルで怖がること無くコードを書くことが出来る。

f:id:niwatako:20170302152038j:plain

f:id:niwatako:20170302152104j:plain

プロダクションコードと責任を分けて

f:id:niwatako:20170302152123j:plain

f:id:niwatako:20170302152124j:plain

開発者の空き時間で出来ることではありません。普段のコーディングとは異なったスキルが必要になります。

f:id:niwatako:20170302152139j:plain

Q&A

いぜんAppiumを使っていて、起動とテストに時間が掛かる。UITestingではなくAppiumを選択した理由は

シミュレーターの状態をクリーンにしてシステムアラートを出すことが出来る形になっているのでシナリオの再現性という点でAppiumを採用しました。

遅さはあるが、CI上でコミット毎にUIテストを回すことはしていない。どのタイミングでテストするかという戦略を考えなければいけない。

バンダリーをチェックすべきでないとおっしゃっていたが別のテストはどのようなものを導入しましたか?

20文字しか入力できないところを19文字入力したり21文字入力したり、と言ったバリデーションに関わるところは、UIでやってもいいが、バリデーションに合致するかどうかはUIで全てケースを揃えると底に至るまでのステップが重くなるので、なるべくUnitTestでやったほうが良いというのは、そうした文字入力の部分になります。