2017/02/03 JaSST’17 Tokyo
© 2017, Cygames, Inc., all rights reserved.© 2017, Cygames, Inc., all rights reserved.株式会社 Cygames折⽥田 武⼰己受け⼊入れテストの⾃自動化〜~ OpenCVの「眼」で捉え、Pythonの「脳」が思考し、Appiumの「指」で動かす
View Slide
© 2017, Cygames, Inc., all rights reserved.© 2017, Cygames, Inc., all rights reserved.株式会社CygamesCTO室 ソフトウェアエンジニア折⽥田 武⼰己ざまざまな基幹系システムの設計・開発を経て、2012年年より株式会社Cygamesに教育担当として参画。エンジニアを対象にした技術研修やインターンシップの企画・運営に従事。アルバイト学⽣生の技術指導を兼ねて、業務効率率率を改善するためのツールの設計・開発にも取り組んでいる。
© 2017, Cygames, Inc., all rights reserved.はじめに「受け⼊入れテスト」では、それを実施するのと同等か? あるいはそれ以上に、エビデンスを保全することが⼤大切切です。しかし、第三者にも検証可能な形でエビデンスを残すことは、想像以上にコストのかかる⼤大変な作業です。私の所属する部署では、アルバイト学⽣生の技術指導も兼ねて「受け⼊入れテスト」を⾃自動化するツールを開発しています。本セッションでは、その開発事例例について(構築のノウハウも交えながら)紹介します。
© 2017, Cygames, Inc., all rights reserved.⼈人間による動作検証そもそも、⼈人間はどのようにしてスマホアプリの動作検証を⾏行行っているのでしょう?おおまかに切切り分けると、下記のような役割分担になるのではないでしょうか?• スマホ画⾯面を眺める• 情報を読み取る眼• 読み取った情報を解析する• 次のアクションを決定する脳• スマホ画⾯面をタップする• 情報を⼊入⼒力力する指
© 2017, Cygames, Inc., all rights reserved.コンピュータによる動作検証コンピュータに同じことをさせる場合、どのように対応させれば良良いでしょう?私たちは、下記のようにマッピングすることで、問題を解決できると考えました。• OpenCV眼• Python脳• Appium指
© 2017, Cygames, Inc., all rights reserved.技術基盤技術基盤の各要素について、簡単に紹介します。v OpenCVv Pythonv Appium
© 2017, Cygames, Inc., all rights reserved.技術基盤【OpenCV】OpenCVは、オープンソースのコンピュータビジョン向けライブラリです。C/C++のほか、Java、Pythonを公式にサポートしています。• 画像処理理(変換、分割、検出)• 構造解析• モーション解析• パターン認識識• カメラキャリブレーション• 機械学習• ユーザーインターフェイス【URL】http://opencv.org
© 2017, Cygames, Inc., all rights reserved.技術基盤【Python】スクリプトの開発には、Pythonを利利⽤用しています。プログラミング⾔言語としてPythonを選んだ理理由は下記の通りです。• OpenCVとの親和性の⾼高さ• C/C++のモジュールが利利⽤用可能であること• Numpyをはじめとする優れたライブラリ群【URL】https://www.python.org
© 2017, Cygames, Inc., all rights reserved.技術基盤【Appium】Appiumは、スマホアプリを⾃自動操作するためのミドルウェアです。AndroidとiOSの両⽅方をサポートしており、下記のプログラミング⾔言語でスクリプトを記述することができます。• Java• JavaScript• Perl• PHP• Python• Ruby【URL】http://appium.io
© 2017, Cygames, Inc., all rights reserved.システム構成ターゲットとなるスマホOSの種類によって、システムの構成も変わります。Androidの場合、実機を使う以外に事実上の選択肢がありません。v Androidの抱える問題点v Androidの場合v iOSの場合本来の「受け⼊入れテスト」の⽬目的に照らし合わせれば、スマートフォンの実機を動作検証に使うのは好ましいことです。しかし、バッテリーの充電速度度より消費速度度の⽅方が早いため、⻑⾧長時間の連続稼働が難しいという⽋欠点があります。
© 2017, Cygames, Inc., all rights reserved.システム構成【Androidの抱える問題点】Androidを利利⽤用する上でのボトルネックは下記の通りです。1. Androidエミュレータが重たいx86互換のバイナリを⽣生成すれば、実⽤用的な速度度で動きます。しかし、すべてのソースコードにフルアクセスできる環境でないと、その恩恵を享受できません。2. スクリーンショットの取得が遅いAppium経由でフルサイズのスクリーンショットを取得する場合、(ADBコマンドの制約により)1〜~2秒くらいの時間を要します。【結論論】Androd実機を使う。【結論論】ビデオキャプチャデバイスを使う。
© 2017, Cygames, Inc., all rights reserved.システム構成【Androidの場合】Windows PCAndroid端末USBUSBMHL変換アダプタHDMIUSBWiFiHDMI分配器HDMIHDMIビデオキャプチャデバイスUSBHDMIWiFiOpenCVPythonAppium【Tips】画像取得の⾼高速化【Tips】WiFi経由で制御【Tips】DRMの解除【Tips】60 fpsに対応
© 2017, Cygames, Inc., all rights reserved.システム構成【iOSの場合】MacintoshiOSシミュレータOpenCVPythonAppiumiOSシミュレータは実機と遜⾊色のない速度度で動作するので、実機を使わずに済ませることも可能です。Lightning接続のAVアダプタを利利⽤用すれば、Androidの場合と同じように実機からHDMI信号を取り出せます。
© 2017, Cygames, Inc., all rights reserved.テンプレートマッチングOpenCVには様々な機能が⽤用意されています。なかでもテンプレートマッチングは「受け⼊入れテスト」の⾃自動化に必要不不可⽋欠です。v 概要v 特徴
© 2017, Cygames, Inc., all rights reserved.テンプレートマッチング【概要】テンプレートマッチングを使えば、「ターゲット画像」の中に、指定した「テンプレート画像」が含まれているか?調べることができます。ターゲット画像テンプレート画像【Tips】マッチした座標を返却
© 2017, Cygames, Inc., all rights reserved.テンプレートマッチング【特徴】テンプレートマッチングには、下記のような特徴があります。• ビットマップの完全⼀一致ではない• 多少のサイズ変動にも対応できる• 多少の傾きにも対応できる• マッチングの閾値を指定できるテンプレート画像を⾒見見つけた場合、ターゲット画像中の(複数個マッチした場合、そのすべての)座標を返却します。画⾯面遷移のトリガーを検出するのに最適です。
© 2017, Cygames, Inc., all rights reserved.基本パターン「受け⼊入れテスト」の⾃自動化は、下記の基本パターンを組み合わせることで実現可能です。v 状況分析v ⾏行行動決定v 画⾯面遷移v 時間調整v 情報取得
© 2017, Cygames, Inc., all rights reserved.基本パターン【状況分析】ターゲットとなるスマホアプリが現在どのような状態にあるのか?スクリーンショットを領領域分割し、個々の領領域を画像解析することで判断します。テンプレートマッチング画像の領領域分割スクリーンショットの取得
© 2017, Cygames, Inc., all rights reserved.基本パターン【⾏行行動決定】状況分析を⾏行行ったのち、どのようなアクションを取るべきなのか? 各種パラメータや内部状態を勘案しながら、スクリプトが決定します。各種パラメータ内部状態乱数変数リソース実⾏行行時引数環境変数
© 2017, Cygames, Inc., all rights reserved.基本パターン【画⾯面遷移】ボタンやリンクをタップすることによって画⾯面遷移を⾏行行います。ただし、メンテナンス性を考慮すると、それらのトリガーとなるオブジェクトの座標を決め打ちするのは、あまり好ましくありません。タップフリックスワイプピンチBACK
© 2017, Cygames, Inc., all rights reserved.基本パターン【時間調整】次にとるべきアクションが決定しても、それを即座に実⾏行行に移せない状況が発⽣生し得ます。1. データのアップデート中2. サーバーとの通信中3. お知らせ等のカットイン4. エラーの発⽣生5. その他(想定外)の事象上記「1」と「2」の場合、タイムアウトを考慮した上で⼀一定時間スリープします。
© 2017, Cygames, Inc., all rights reserved.基本パターン【情報取得】画⾯面に表⽰示された「画像」や「⽂文字」から情報を取得します。画⾯面に描画された「⽂文字」は、ビットマップ化された「画像」に過ぎないので、テキスト化のためのプロセスが別途必要となります。画⾯面の領領域分割画像のトリミングデータの符号化(OCR / CV)データの永続化
© 2017, Cygames, Inc., all rights reserved.ケーススタディShadowverseのカードパックの実装事例例から、技術的なポイントを解説します。v アプリ起動v タイトル画⾯面v ローディング画⾯面v ホーム画⾯面v ショップ画⾯面v カードパック購⼊入画⾯面v カード⼀一覧v カード詳細
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【アプリ起動】Appiumを使ってスマホアプリを起動します。その際に指定するのが、アプリを⼀一意に特定するための「パッケージ名」です。私たちのシステムでは、必要な情報をJSON形式の定義ファイルに記述します。Shadowverseの場合、下記のように指定します。 "appPackage": "jp.co.cygames.Shadowverse"
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【タイトル画⾯面】タイトル画⾯面が表⽰示されたら、画⾯面の任意の場所をタップしてホーム画⾯面に遷移します。【ASSERT】画⾯面中央のロゴ【TAP】画⾯面下部のプロンプト【ASSERT】画⾯面上部のボタン
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【アカウント連携設定】アカウント連携設定に関するダイアログが表⽰示されたら、画⾯面下部の「後で」ボタンをタップして設定を保留留します。【ASSERT】画⾯面上部の⽂文字列列【TAP】画⾯面下部のボタン
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【ローディング画⾯面】サーバーとの通信している最中は、ローディング画⾯面が表⽰示されます。タイムアウトを設定した上で、通信が完了了するまで待機します。【ASSERT】画⾯面右下のアイコン
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【お知らせダイアログ】お知らせダイアログが表⽰示された場合には、「閉じる」ボタンをタップします。【TAP】画⾯面下部のボタン【ASSERT】画⾯面上部の罫線
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【ホーム画⾯面】ホーム画⾯面が表⽰示されたら、画⾯面下部のボタンをタップして、ショップ画⾯面に遷移します。【ASSERT】画⾯面下部のボタン 【TAP】画⾯面下部のボタン
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【ショップ画⾯面】ショップ画⾯面が表⽰示されたら、カードパック購⼊入のアイコンをタップします。【ASSERT】画⾯面下部のボタン【TAP】画⾯面中央部の画像
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【カードパック購⼊入画⾯面】カードパック購⼊入画⾯面が表⽰示されたら、チケットでの「購⼊入する」ボタンをタップします。【ASSERT】画⾯面上部の⽂文字列列【TAP】画⾯面中央部のボタン【ASSERT】画⾯面中央部の⽂文字列列【ASSERT】画⾯面下部のボタン
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【数量量選択ダイアログ】数量量選択ダイアログが表⽰示されたら、画⾯面下部のボタンをタップします。【ASSERT】画⾯面上部の⽂文字列列【TAP】画⾯面下部のボタン
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【購⼊入確認ダイアログ】購⼊入確認ダイアログが表⽰示されたら、画⾯面下部の「購⼊入する」ボタンをタップします。【ASSERT】画⾯面上部の⽂文字列列【TAP】画⾯面下部のボタン
© 2017, Cygames, Inc., all rights reserved.カードパックのアニメーションが表⽰示されます。ケーススタディ【アニメーション】
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【カード⼀一覧】カード⼀一覧が表⽰示されたら、すべてのカードを順番にタップします。【ASSERT】画⾯面下部のボタン【TAP】画⾯面中央部の画像【ASSERT】画⾯面下部のテキスト
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【カード詳細:Aパターン】カード詳細が表⽰示されたら、エビデンスの永続化に必要な情報をテキストデータに変換します。【ASSERT】画⾯面上部の⽂文字列列【OCR】画⾯面右側の⽂文字列列【CV】画⾯面左側の画像
© 2017, Cygames, Inc., all rights reserved.ケーススタディ【カード詳細:Bパターン】カード詳細が表⽰示されたら、エビデンスの永続化に必要な情報をテキストデータに変換します。【ASSERT】画⾯面上部の⽂文字列列【OCR】画⾯面右側の⽂文字列列【CV】画⾯面左側の画像
© 2017, Cygames, Inc., all rights reserved.デモ動画(⾃自動テストツール)
© 2017, Cygames, Inc., all rights reserved.最適化テンプレートマッチングの最適化に関するポイントを整理理すると、次のようになります。v 探索索範囲の局所化v 画像サイズの調整v テンプレート画像の加⼯工v テンプレート画像の階層管理理
© 2017, Cygames, Inc., all rights reserved.最適化【探索索範囲の局所化】ターゲット画像の全域で照合作業を⾏行行うのは計算コストの無駄遣いです。画像をクリッピングすることによって、探索索範囲を絞り込みましょう。探索索範囲を局所化することにより、照合作業が⾼高速化する。探索索範囲を狭めすぎると、今度度はレイアウト変更更に柔軟に対応できなくなる。
© 2017, Cygames, Inc., all rights reserved.最適化【画像サイズの調整】ターゲット画像やテンプレート画像のサイズが⼩小さければ、その分だけ照合作業を⾼高速に終えることができます。画像サイズが1/2になれば、占有する⾯面積、つまりメモリ消費量量は1/4になる。その分だけ照合速度度が⾼高速化できる。テンプレートマッチングに利利⽤用する画像は、エビデンスとして保存する画像と同⼀一サイズである必要はない。
© 2017, Cygames, Inc., all rights reserved.最適化【テンプレート画像の加⼯工】テンプレートマッチングには「透明⾊色」という概念念はありません。テンプレート画像に背景が映り込んでいる場合、照合作業に影響のない範囲でトリミングしましょう。【NG】形状が複雑なため、テンプレート画像の中に背景が映り込んでいる。【NG】背景部分を除去しても、透明⾊色として扱われない。マスク処理理にも対応しない。【OK】背景に影響されないように、テンプレート画像をトリミングする。
© 2017, Cygames, Inc., all rights reserved.照合作業を最少のコストで済ませるためには、テンプレート画像を適切切な粒粒度度でグルーピングする必要があります。 ダイアログ 共通 ローディング アップデート ショップ 共通 カードパック 共通 チケット ルピ クリスタル サプライ クリスタル最適化【テンプレート画像の階層管理理】テンプレート画像をフォルダごとに分割する。フォルダ同⼠士や同⼀一フォルダ内のテンプレート画像については、出現頻度度の⾼高い順に照合作業を⾏行行う。
© 2017, Cygames, Inc., all rights reserved.サブシステム「受け⼊入れテスト」を⾃自動化するにあたり、下記のようなサブシステムを整備しました。v スクリーンキャプチャーv OCRサービスv ドライブレーダーv エビデンスビューワー
© 2017, Cygames, Inc., all rights reserved.サブシステム【スクリーンキャプチャー】ホストOS(Windows/Macintosh)に⽤用意されているAPIをC++のコードから呼び出すことにより、スクリーンショットを取得します。• ウィンドウハンドルの取得• ウィンドウの移動• ウィンドウのリサイズ• ビットマップ画像の転送Pythonからは、C/C++で書かれたライブラリをシームレスに呼び出すことができます。
© 2017, Cygames, Inc., all rights reserved.サブシステム【OCRサービス】市販の⽇日本語OCRライブラリを利利⽤用して、ビットマップ画像中に含まれるテキスト情報を抽出するため、下記のような(社内向け)Webサービスを⽴立立ち上げました。• WebSocketによるデータ通信• 任意の矩形でトリミング• 任意の矩形でテキスト化領領域を指定可能• 複数のテキスト化領領域を指定可能• 透過背景のノイズを⾃自動除去個々のPCにOCR機能を組み込む必要がなく、セットアップや運⽤用が容易易になります。
© 2017, Cygames, Inc., all rights reserved.サブシステム【ドライブレコーダー】下記の理理由により、スクリプトがタイムアウトもしくは異異常終了了した場合、直近のn秒間の様⼦子を動画ファイルとして⾃自動保存してくれます。• スクリプトの不不備• 実機のハードウェア障害• 実機のソフトウェア障害• その他(想定外)の事象スクリプト開発の初期段階では、実装要件の考慮漏漏れも多く、記録された動画ファイルがエラー原因の解析に役⽴立立ちます。
© 2017, Cygames, Inc., all rights reserved.サブシステム【エビデンスビューワー】スクリプトを実⾏行行すると、既定の場所に下記のようなエビデンスが⾃自動保存されます。• スクリーンショット• 実⾏行行結果のサマリー情報• 実⾏行行結果の詳細情報• ログファイル• 例例外発⽣生時のスタックトレース• 例例外発⽣生時の動画ファイルWebブラウザーを使って、社内のどこからでも⾃自動集計されたエビデンスにアクセスできます。また、スクリプトを実⾏行行することも可能です。
© 2017, Cygames, Inc., all rights reserved.デモ動画(エビデンスビューワー)エビデンスビューワーはWebアプリケーションですから、社内ネットワークのどこからでもアクセス可能です。また、JenkinsのようなCIツールと連携させることで、利利便便性はさらに向上します。
© 2017, Cygames, Inc., all rights reserved.前半のまとめコンピュータビジョンを応⽤用した「受け⼊入れテスト」の⾃自動化は、すでに実⽤用レベルの域に到達した “開発現場で使える” 技術です。細⼼心の注意を払ってスクリプトを実装すれば、熟練したスタッフと遜⾊色のない品質を担保できます。ただし、⼈人間ほどの柔軟性は備えていないので、想定外の事象にはとても弱いのです。すべての領領域を⼀一括移⾏行行するのは、コストやリスクの⾯面からみても現実的ではありません。反復復の頻度度の⾼高い処理理から順に置き換えるのが、もっとも有効なアプローチだと思います。
© 2017, Cygames, Inc., all rights reserved.⾃自動⽣生成ツール「受け⼊入れテスト」にも応⽤用可能な、UIテスト⽤用のスクリプトを⾃自動⽣生成するツールが存在します。様々な技術的制約があります。⼀一体どのようなものなのか?簡単に紹介します。v Selenium IDEv Appium Inspectorv ⾃自動⽣生成の問題点v ツール活⽤用の理理想形
© 2017, Cygames, Inc., all rights reserved.⾃自動⽣生成ツール【Selenium IDE】Webはすべてがオープンな世界です。HTTPプロトコル⾃自体がそうですし、コンテンツを⽣生成するためのフロントエンド技術についても同様です。もし、「受け⼊入れテスト」の対象がWebアプリケーションである場合、AppiumのベースとなったSeleniumが利利⽤用可能です。「Selenium IDE」は、利利⽤用者の操作内容を簡単に記録できます。またその場で、記録したスクリプトを再⽣生することも可能です。【画像の引⽤用元URL】http://www.seleniumhq.org/projects/ide/
© 2017, Cygames, Inc., all rights reserved.⾃自動⽣生成ツール【Appium Inspector】「Appium Inspector」を使えば、UIテスト⽤用のスクリプトを⾃自動⽣生成できます。ただし、「Appium Inspector」がターゲットを正しく検出できるのは、OSのネイティブなUIコンポーネントのみです。Unityをはじめ、マルチプラットホーム対応のツールキットの多くが、UIコンポーネントを⾃自前で描画するため正しく検出できません。【画像の引⽤用元URL】https://appium.io/slate/en/tutorial/ios.html?ruby#ending-the-session
© 2017, Cygames, Inc., all rights reserved.⾃自動⽣生成ツール【⾃自動⽣生成の問題点】ツールによって⽣生成されたコードには様々な問題点があります。• 分岐や繰り返しが苦⼿手• カスタマイズが難しい• 操作の重複が発⽣生する• サブルーチン化できない• 事前処理理、事後処理理が組み込めない• 意外性と網羅羅性に⽋欠ける※エンドユーザーが定型業務を再現するのには好都合ですが、「受け⼊入れテスト」に適⽤用するとなると、やはり⼒力力不不⾜足の感が否めません。
© 2017, Cygames, Inc., all rights reserved.⾃自動⽣生成ツール【ツール活⽤用の理理想形】⾃自動⽣生成ツールには、誰でも簡単にUIテストを記録&再⽣生できるという⼤大きなメリットがあります。そのままでは「受け⼊入れテスト」で利利⽤用することに躊躇しますが・・・ちょっとした⼯工夫をすることで、利利⽤用者の負担を軽減することは可能です。• テストシナリオ• オペレーション⾃自動⽣生成ツール• スクリプト• リソース• データトランスコンパイラ• インポート• 実⾏行行結果の照合• CIツール連携受け⼊入れテスト
© 2017, Cygames, Inc., all rights reserved.楽園の崩壊ある⽇日を境に、エンジニアがこつこつと築いてきた楽園が⾳音を⽴立立てて崩壊をはじめます。その理理由は様々ですが、対象メーリングリスト宛に送付されたJenkinsのアラートメールがトリガーになることが多いようです。v バグ修正v 仕様変更更v 機能拡張これまで良良かれと思って続けてきたこと・・・⾃自動テストのインフラを維持するためのコストが、プロジェクトの⼤大きな⾜足かせになってしまいます。
© 2017, Cygames, Inc., all rights reserved.楽園の崩壊【バグ修正】バグの原因を調査し、しかるべき対応を⾏行行う。報告された事象は解決したのに、今度度は違うところで副作⽤用が発⽣生してしまった。⾃自動テストの環境が整備されていたおかげで、副作⽤用を検出できたが・・・修正内容には直接関係しない箇所でもエラーが発⽣生している。そのテストケースの役割を理理解しないまま、安易易な解決⽅方法に頼る。結果的に、そこで担保していたものが⾻骨抜きにされてしまう。賽の河原で、崩れた⽯石をまた積み上げる・・・終わりの⾒見見えない作業、形骸化した開発プロセス。いつの間にか、その⽬目的さえ⾒見見失ってしまいます。
© 2017, Cygames, Inc., all rights reserved.楽園の崩壊【仕様変更更】当初の想定にない仕様変更更を求められた場合でも、⽴立立場的に拒否できないケースが少なくありません。仕様書は、すでに現状を正しく反映してはおらず、動いているコードがすべて・・・誰を責めるわけにも⾏行行かないし、⾃自分もそれに加担している。本来であれば、⾃自動テストについても抜本的な⾒見見直しを実施すべきですが・・・必要最低限の修正で妥協せざるを得ないのです。⾃自動テストのために整備された開発資産は、巨⼤大な⼤大海原のようであり、⾃自分に与えられた時間は⼩小⾈舟のように⼩小さい・・・無⼒力力感に襲われます。
© 2017, Cygames, Inc., all rights reserved.楽園の崩壊【機能拡張】仕様変更更が必要になった時点で、オリジナルの設計者たちは、すでに他のプロジェクトに移っていることも多いのです。新規開発の頃に⽐比べると、開発チームの⼈人員は⼤大幅に縮⼩小しています。これまでの開発の経緯を知るスタッフも数少ない状況で、どのようにシステムを正常進化させるべきか?現有戦⼒力力では勝⼿手が分からず、時間ばかりが過ぎてしまいます。⾒見見よう⾒見見まねで何とか体裁は保ったが、果たして適切切な処置だったのか?コピペした⾃自動テストの資産は・・・エラーを回避するだけで精⼀一杯だったりします。
© 2017, Cygames, Inc., all rights reserved.アンチエイジング⾃自動テストの開発資産は、それが完成した瞬間から、崩壊に向けたカウントダウンが始まります。1⽇日でも⻑⾧長く安定稼働を続けるには、アンチエイジングへの取り組みが必要不不可⽋欠です。v 増殖抑制v ⾼高集積化v 三位⼀一体
© 2017, Cygames, Inc., all rights reserved.アンチエイジング【増殖抑制】実際の開発プロジェクトでは、⾃自動テストのプロトタイプが出来上がると、それをお⼿手本に本格的な量量産体制に⼊入るのが⼀一般的です。その⼀一⽅方で無限増殖を抑制する動きも必要です。メンテナンスの対象が増えれば、それを維持するためのコストも指数関数的に増⼤大するからです。プロトタイプ利利⽤用者画⾯面Aパターン Bパターン管理理者画⾯面Aパターン Bパターン
© 2017, Cygames, Inc., all rights reserved.アンチエイジング【⾼高集積化】コンピューターのハードウェアは、「ムーアの法則」によって⽇日進⽉月歩の進化を遂げました。部品点数を減らし、個々のパーツを集積化することでシステム全体の信頼性を向上させたのです。⾃自動テストの開発資産についても、同様のアプローチで実装密度度を向上させるべきです。資産を増やすのではなく、むしろ減らすことの⽅方が、正しい進化の⽅方向なのです。圧縮集約結合
© 2017, Cygames, Inc., all rights reserved.アンチエイジング【三位⼀一体】⾃自動テストでは、開発資産を「スクリプト」「データ」「リソース」に三分割すべきです。それぞれに役割分担させることで、全体の⾒見見通しが良良くなり、影響範囲も局所化できます。※三位⼀一体の実装ポリシーについて、さらに具体的に解説しましょう。スクリプトデータリソース
© 2017, Cygames, Inc., all rights reserved.リソース異異なるメディアやデバイスをサポートする場合、安易易なコピー&ペーストを避け、メンテナンス対象ファイルの増殖を抑制することが⼤大切切です。また、マジックナンバー化しやすいリテラル部分を外部リソースとして分離離することで、スクリプトの可読性や保守性が⼤大幅に向上します。v ディレクトリ構成v フォーマットv ターゲット指定v メディアクエリー
© 2017, Cygames, Inc., all rights reserved.リソース管理理について、カードパック購⼊入画⾯面の事例例で説明します。 data resource bind image common buttonpurchase.png home json home shopcardpack.json soloplay ocr scriptリソース【ディレクトリ構成】すべてのリソースは、「resource」ディレクトリの配下に格納します。テンプレート画像は、各画⾯面ごと「image」ディレクトリの配下に格納します。画像ファイルは、JSONファイルから間接的に参照されます。リソース情報を定義したJSONファイルは、各画⾯面ごとに「json」ディレクトリの配下に格納します。データのバインド情報は、「bind」ディレクトリの配下に格納します。
© 2017, Cygames, Inc., all rights reserved.リソース【フォーマット】カードパックをチケットで購⼊入するには、下記のようなURLでリソース定義を参照します。【URL】/cardpack/standard/purchase/ticket/target/execute{"caption": "Card Pack","standard": {"purchase": {"ticket": {"boundary": [60, 35, 95, 50],"target": {"assets": "ocr://single/70/40/75/45","execute": "cv://image/common/button/purchase"}},"rupee": { /* 省省略略 */ },"crystal": { /* 省省略略 */ }}}}探索索領領域の左上座標、右下座標を画⾯面全体の割合でパーセント指定する。使⽤用するプロトコルとパスをURLで指定することで、操作対象を特定する。
© 2017, Cygames, Inc., all rights reserved.リソース【ターゲット指定】リソースをURL指定する場合、第1セグメントが同名のJSONファイルであると解釈されます。それに続く第2セグメント以降降は、JSONファイル内のデータ構造にマッピングされます。シンプルな⽅方式ですが・・・必然的にURIが⻑⾧長くなる傾向にあります。そこで、ワイルドカードに準拠した独⾃自の短縮表記をサポートしました。フルパス表記/cardpack/standard/purchase/ticket/target/execute短縮パス表記① /cardpack/standard/?/ticket/*/execute短縮パス表記② /cardpack/*/execute[1]
© 2017, Cygames, Inc., all rights reserved.リソース【メディアクエリー】異異なるデバイスをサポートする必要がある場合、テスト資産も個別に⽤用意する必要があります。UIが異異なるだけであれば、リソースの追加で対応できる可能があります。HTMLのメディアクエリーに相当するものを利利⽤用しましょう。リソース定義を⾏行行うJSONファイル内にメディアクエリーを指定し、実⾏行行時に対象を切切り替えます。デバイス種別 メディアクエリーパソコン @PCフィーチャーフォン @FPスマートフォン @SPタブレット @TAB
© 2017, Cygames, Inc., all rights reserved.スクリプトスクリプト開発の⽣生産性を向上させるためには、シンプルで理理解しやすいAPI設計が重要です。v 画像検索索①v 画像検索索②v タップv バリデーションv ⽂文字列列抽出v エビデンス保存v タイムアウトv 例例外処理理
© 2017, Cygames, Inc., all rights reserved.スクリプト【画像検索索①】OpenCVのテンプレートマッチングを利利⽤用して、画像の存在確認を⾏行行います。n APIn サンプルdef check_rarerity(self):if self.cvexists("/cardpack/cardinfo/rarerity/legend"):rarerity = Rarerity.Legendelif self.cvexists("/cardpack/cardinfo/rarerity/gold"):rarerity = Rarerity.Goldelif self.cvexists("/cardpack/cardinfo/rarerity/silver"):rarerity = Rarerity.Silverelif self.cvexists("/cardpack/cardinfo/rarerity/bronze"):rarerity = Rarerity.Bronzeelse:rarerity = Rarerity.Unknownreturn rareritycvexists(location, threshold=0.75)URL マッチングの閾値指定されたリソース定義の中で、メソッドの実⾏行行に必要なパラメータ情報を取得する。本来であれば、ifの制御構⽂文は出現頻度度の⾼高い順に並べるべき。
© 2017, Cygames, Inc., all rights reserved.スクリプト【画像検索索②】OpenCVのテンプレートマッチングを利利⽤用して、画像の検索索を⾏行行います。n APIn サンプルdef get_carddata(self):target, status = self.cvmatch("/cardpack/cardinfo/detail")if target is None:# 省省略略elif status:# 省省略略else:# 省省略略cvmatch(location, multiple=False, threshold=0.75)URL 複数検索索 マッチングの閾値照合結果とは別に、ステータス専⽤用の戻り値を返却する。ある画⾯面のリソース定義は、当然のことながら⼀一箇所に集約される。しかし、それを参照するスクリプトは、複数の箇所に分散することが多い。リソースをURLで参照するアプローチを採⽤用することで、画⾯面仕様が変更更になった際、修正するのはひとつのリソースファイルだけになる。
© 2017, Cygames, Inc., all rights reserved.スクリプト【タップ】指定された場所をタップします。対象が画像の場合、それが出現するまで⼀一定時間待機します。n APIn サンプルdef goto_cardpack(self):self.tap("/home/menubar/shop")self.validate("/shop/validation")self.tap("/shop/cardpack")self.validate("/cardpack/validation")self.uncheck("/cardpack/autoturn")tap(location, duration=100, wait=True, timeout=30)URL 押下時間(ミリ秒)リソースのURLがコメントの役割を果たすので、処理理内容を直感的に把握できる。出現待ち 制限時間(秒)⼈人間が⾏行行うオペレーションを同名のAPIとして提供する。スクリプト開発の基本は、操作内容をただ列列挙すること。細かなタイミング調整やエラー処理理はAPIに任せればよい。詳細情報をリソースとして分離離しているため、処理理⼿手順に変更更がない限り、スクリプトを修正する必要はない。
© 2017, Cygames, Inc., all rights reserved.スクリプト【バリデーション】画⾯面の表⽰示内容に問題がないか検証します。n APIn サンプルdef goto_cardpack(self):self.tap("/home/menubar/shop")self.validate("/shop/validation")self.tap("/shop/cardpack")self.validate("cardpack/validation")self.uncheck("cardpack/autoturn")validate(location, servirity=Servirity.Normal)URL 不不整合があった場合の深刻度度バリデーションのチェック内容をリソースに閉じ込めることで、仕様変更更の影響範囲を局所化できる。JSONファイルは、そのデータ構造さえ理理解すれば、エンジニアでなくてもメンテナンスできる。
© 2017, Cygames, Inc., all rights reserved.スクリプト【⽂文字列列抽出】画像の指定された領領域をテキスト化します。n APIn サンプルdef get_cardinfo(self):# 省省略略cardtype = check_cardtype()text = self.ocr("/cardpack/cardinfo/detail/" + cardtype)if not text is None or len(text) > 0:# 省省略略else:# 省省略略ocr(location, area=None)URL クリッピング領領域(複数の矩形を指定可能)OCRサービスへの問い合わせを外部に⾏行行っているため、レスポンスが得られるまでに若若⼲干のタイムラグがある。JSON形式の独⾃自プロトコルを使い、OCRサービスとの間でデータのやり取りを⾏行行っている。APIを経由することで、普通のメソッドコールのように使える。
© 2017, Cygames, Inc., all rights reserved.スクリプト【エビデンス保存】アプリケーションが取得した情報をエビデンスとして保存することができます。n APIn サンプルdef regist_cardinfo(self):# 省省略略path = self.screenshot("cardinfo")card, status = self.get_cardinfo(path)if card is None:self.evidence.regist(AppError.UnknownCard, path)elif status:self.evidence.regist(status)else:self.evidence.regist(path, card)self.evidence.save()evidence.regist(**args)evidence.save()仮登録するエビデンス(可変⻑⾧長引数)スクリーンショットを取得し、指定されたサブディレクトリに格納する。仮登録したエビデンスを⼀一括登録する。
© 2017, Cygames, Inc., all rights reserved.スクリプト【タイムアウト】Pythonのデコレータ機能を使って、メソッドの実⾏行行時間に制限を設けることができます。n APIn サンプル@util.timeout(seconds=CV_TIMEOUT)def tap_image(self, path, threshold, wait=True, area=None):count = 0while True:target = self.cv.template_match(path, threshold, 1, area)if not target is None or len(target) > 0:# 省省略略else:count += 1# 省省略略return False@timeout(seconds=60)タイムアウト(秒)名前の競合を避けるため、utilモジュールに格納している。メソッドの実⾏行行時間がデコレータで指定された秒数を超えると、アプリケーション例例外が発⽣生する。内部でOpenCVのラッパーを呼び出す。
© 2017, Cygames, Inc., all rights reserved.スクリプト【例例外処理理】これまでに紹介したAPIでエラーが発⽣生した場合、例例外が⾃自動的にスローされますが、スクリプト内で能動的に例例外を発⽣生させることも可能です。n APIn サンプルdef check_info(self):if self.cvexists("/home/sidebar/info/active"):# 省省略略else:self.throw(AppError.Inactive, "info button")throw(error, extra=None, cause=None)エラー種類このAPIの場合には、対象が存在しなくてもエラーは発⽣生しない。Pythonに⽤用意されている「raise」構⽂文を使って例例外をスローするのは得策ではない。ロギングをはじめとする、例例外発⽣生に伴う各種⼿手続きを⼀一元管理理すべきである。付加情報 誘発元の例例外
© 2017, Cygames, Inc., all rights reserved.データ⼤大規模なシステム開発では「データ」が⾃自動テストの成功の鍵を握ります。なぜそれほどまでに「データ」が重要なのか?具体的な例例を⾒見見ながら解説します。v 劣劣化速度度が速いv 影響範囲が広いv 天然もの VS 養殖ものv チェックデータv ノイズデータv フォーマットv ⾮非正規化v バインド情報
© 2017, Cygames, Inc., all rights reserved.データ【劣劣化速度度が速い】バグの発覚を除けば、仕様変更更が起こらない限り、テスト対象のコードを修正する必要はありません。⾃自動テストの「スクリプト」の⾒見見直しは、テスト対象のコードの修正タイミングと同期するはず。しかし、テスト対象のコードが⼀一切切変更更されていないにも関わらず、⾃自動テスト関連の開発資産について⾒見見直しを迫られることがあります。それは、データベースのスキーマに変更更の必要が⽣生じた場合です。つまり、「データ」は「スクリプト」に⽐比べて、劣劣化する速度度が速いと⾒見見なすことができます。
© 2017, Cygames, Inc., all rights reserved.データ【影響範囲が広い】あるテーブルにスキーマ変更更が発⽣生した場合、それを直接的または間接的に利利⽤用するすべてのコードに影響します。スキーマの変更更⾃自体は極めて容易易ですが、それに関連する修正は極めて広範囲に及びます。単に表⽰示状態に影響するだけではなく、⼊入⼒力力値のバリデーション処理理に関係することもあります。当然のことながら、それらの影響は⾃自動テストの開発資産にも波及します。「データ」だけではなく、「スクリプト」にも⾒見見直しが必要になります。
© 2017, Cygames, Inc., all rights reserved.データ【天然もの VS 養殖もの】テストデータは、その成り⽴立立ちによって次のように⼤大別できます。• 天然もの → 本番環境に由来するデータ• 養殖もの → ⼈人為的に作成されたデータ⾷食の世界であれば「天然もの」が重⽤用されますが、⾃自動テストの世界では「養殖もの」の⽅方が何かと都合が良良いのです。理理想的なテストデータは、しっかりと体系化され、規格化されている必要があります。そうでなければ、将来起こるであろう変化に(リーズナブルなコストで)対応できないからです。
© 2017, Cygames, Inc., all rights reserved.データ【チェックデータ】表⽰示崩れや⾒見見切切れ、⽂文字化け等の表⽰示状態を確認するために専⽤用のデータを⽤用意するべきです。• ルーラー• ⽂文字数(最⼩小桁、最⼤大桁)• 半⾓角⽂文字(英数字、記号、カナ)• 全⾓角⽂文字(英数字、記号、かな、漢字)• フォント(横書き、縦書き)• ⽂文字コード(ASCII、JIS、SJIS、UTF-8)• 禁忌⽂文字(外字、HTMLタグ)• その他(機種依存⽂文字、絵⽂文字)
© 2017, Cygames, Inc., all rights reserved.データ【ノイズデータ】ノイズデータはとても重要です。コアなデータのみでは、(想定しておくべき)想定外の状況に対応できません。• 境界値分析• 同値分割(有効同値、無効同値)• ページング(Overflow、Underflow)• レプリケーション、パーティショニング• 論論理理削除、物理理削除※ノイズデータはテストシナリオに合わせて、システム側で⾃自動⽣生成するのが理理想的です。
© 2017, Cygames, Inc., all rights reserved.データ【フォーマット】テストデータの管理理には、様々なフォーマットが⽤用いられます。• RDBMSダンプファイル• CSVファイル• Excelファイル• XMLファイル• JSONファイル• 独⾃自JSONファイル(プリプロセッサ拡張)※オリジナルのJSONにはない、コメントやインポート、継承などの機構をサポートすることによって保守性が⼤大幅に向上します。
© 2017, Cygames, Inc., all rights reserved.データ【⾮非正規化】本来、データは「階層的な構造」であるはずです。テーブル設計に影響され、データを「フラットな構造」に押し込めるべきではありません。{"id": "AD1582","name": "信⻑⾧長","home": {"postal": "604-8091","address": {"prefecture": "京都府","city": "京都市","other": "中京区寺町通御池下る下本能寺前町522"},"phone": "075-231-5335"},"follow": ["name:丹丹⽻羽", "name:柴⽥田", "id:AD1598"],"block": ["name:明智"]}スキーマ設計に由来する「正規化」という呪縛から逃れ、本来あるべき⾃自由な姿、理理想とするデータ構造に⽴立立ち戻るべき。データの動的⽣生成も、技術的に興味深いテーマである。プリプロセッサでJSONを拡張し、インポートや継承により管理理コストを軽減する。
© 2017, Cygames, Inc., all rights reserved.データ【バインド情報】呪縛から逃れるには、周到な準備が⽋欠かせません。テーブル設計との関係性を維持するために、双⽅方を紐紐づける「バインド情報」が必要です。{"id": "M_USER.ID","name": "M_USER.NAME","home": {"postal": "M_USER.HOME_POSTAL","address": {"prefecture": "(merge:1)M_USER.HOME_ADDREESS","city": "(merge:2)M_USER.HOME_ADDRESS","other": "(merge:3)M_USER.HOME_ADDRESS"},"phone": "M_USER.HOME_PHONE"},"follow": ["(refer:id)T_FOLLOW.ID,(refer:name)T_FOLLOW.NAME"],"block": ["(refer:id)T_BLOCK.ID,(refer:name)T_BLOCK.NAME"]}テーブルのカラムと1対1にマッピングしないケースでは、ローダー側での事前処理理が必要である。主キーと外部キーを使って、異異なるテーブルにロードする。
© 2017, Cygames, Inc., all rights reserved.後半のまとめ⾃自動テストでは、どうしても「スクリプト」に注⽬目が集まりがちです。しかし、開発資産として真に重要なのは「データ」です。テストシナリオに合わせて、必要⼗十分なレコードを⽤用意できれば、不不良良債権ではなく本当の開発資産になりまます。データ記述の表現⼒力力を追求すると、プログラミング⾔言語並みの柔軟性が求められます。リテラル表現に優れた Lightweight Languageこそが、究極のデータ記述⾔言語となります。データリソーススクリプト
© 2017, Cygames, Inc., all rights reserved.今後の課題現在進⾏行行形で開発が進んでいるプロジェクトは下記の通りです。いずれも早期の実戦投⼊入を⽬目論論む、野⼼心的なプロジェクトばかりです。• ⾃自⼰己学習型OCRツール• ボタン⾃自動検出ツール• PICT代替ツール(Python)• テストケース⾃自動⽣生成ツール• レコーディング機能• Appium代替ツール(Android/iOS)※弊社の技術ブログで最新の状況を定期報告する予定なので、ぜひウォッチしてください。
© 2017, Cygames, Inc., all rights reserved.質疑応答もし疑問や質問があれば、可能な範囲内でお答えします。