Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
受け入れテストの自動化 ~ OpenCVの「眼」で捉え、Pythonの「脳」が思考し、Appi...
Search
Cygames
February 08, 2017
Technology
69
33k
受け入れテストの自動化 ~ OpenCVの「眼」で捉え、Pythonの「脳」が思考し、Appiumの「指」で動かす
2017/02/03 JaSST’17 Tokyo
Cygames
February 08, 2017
Tweet
Share
More Decks by Cygames
See All by Cygames
TiDBにおけるテーブル設計と最適化の事例
cygames
3
2k
『グランブルーファンタジー』100万行を超える大規模なシステム再構築~10周年のその先へ~
cygames
11
32k
グラブルミュージアム蒼の追想 MX4Dシアターのサウンド制作事例〜ゲームの世界観とアトラクション体験の両立に必要なこと〜
cygames
0
1.1k
AIによる自然言語処理・音声解析を用いたゲーム内会話パートの感情分析への取り組み
cygames
0
1.9k
最大100倍高速化!PHPからJavaへのFFIを実現する、JNIを用いた高速なサーバAPIの実装方法
cygames
0
410
AIによる自然言語処理を活用したゲームシナリオの誤字検出への取り組み
cygames
0
270
ツール保守コスト大幅削減!テクニカルアーティストによるツールログサービスの開発と運用事例
cygames
0
320
C#によるクライアント/サーバーの開発言語統一がもたらす高効率な開発体制 ~プリコネ!グランドマスターズ開発事例~
cygames
25
21k
「最高のコンテンツ」を支える、Cygamesのデータベース技術の今までとこれから 〜次世代データベース「TiDB」の検証を開始したCygamesの取り組み〜
cygames
0
5.7k
Other Decks in Technology
See All in Technology
Datadogの便利な使い方 - 意外と知らない?CoScreenとCloudcraft
taijihagino
PRO
1
600
Oracle Base Database Service:サービス概要のご紹介
oracle4engineer
PRO
0
13k
Azure Cosmos DB での時系列ログの運用と改善
sansantech
PRO
0
190
waitany と waitall を作った話
mrkn
0
110
標準ライブラリの奥深アップデートを掘り下げよう!
logica0419
2
380
エンジニアリングマネージャーが紐解く、事業視点から組織文化まで、包括的アプローチの探求 / READYFOR
9ma3r
13
2.2k
LLM を現場で評価する
asei
4
660
[RSJ24] Task Success Prediction for Open-Vocabulary Manipulation Based on Multi-Level Aligned Representations
keio_smilab
PRO
0
200
New Relicで実践する外形監視
aeonpeople
1
110
分野に潜むツールの紹介
pojiro
1
330
「名前解決」から振り返るAmazon VPC
yuki_ink
0
320
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
1
160
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
Done Done
chrislema
180
16k
Building Better People: How to give real-time feedback that sticks.
wjessup
359
18k
The World Runs on Bad Software
bkeepers
PRO
64
11k
Large-scale JavaScript Application Architecture
addyosmani
508
110k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
28
2.2k
Designing Experiences People Love
moore
138
23k
Typedesign – Prime Four
hannesfritz
38
2.3k
Building a Scalable Design System with Sketch
lauravandoore
458
32k
RailsConf 2023
tenderlove
26
790
Navigating Team Friction
lara
183
13k
Transcript
© 2017, Cygames, Inc., all rights reserved. © 2017, Cygames,
Inc., all rights reserved. 株式会社 Cygames 折⽥田 武⼰己 受け⼊入れテストの⾃自動化 〜~ OpenCVの「眼」で捉え、Pythonの「脳」が思考し、Appiumの「指」で動かす
© 2017, Cygames, Inc., all rights reserved. © 2017, Cygames,
Inc., all rights reserved. 株式会社Cygames CTO室 ソフトウェアエンジニア 折⽥田 武⼰己 ざまざまな基幹系システムの設計・ 開発を経て、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
OpenCV v Python v 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 PC
Android端末 USB USB MHL変換アダプタ HDMI USB WiFi HDMI分配器 HDMI HDMI ビデオキャプチャ デバイス USB HDMI WiFi OpenCV Python Appium 【Tips】画像取得の⾼高速化 【Tips】WiFi経由で制御 【Tips】DRMの解除 【Tips】60 fpsに対応
© 2017, Cygames, Inc., all rights reserved. システム構成【iOSの場合】 Macintosh iOSシミュレータ
OpenCV Python Appium iOSシミュレータは実機と遜⾊色のない速度度で動作するので、 実機を使わずに済ませることも可能です。 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 IDE v Appium Inspector v ⾃自動⽣生成の問題点 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 button purchase.png home json home shop cardpack.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 API n サンプル def check_rarerity(self): if self.cvexists("/cardpack/cardinfo/rarerity/legend"): rarerity = Rarerity.Legend elif self.cvexists("/cardpack/cardinfo/rarerity/gold"): rarerity = Rarerity.Gold elif self.cvexists("/cardpack/cardinfo/rarerity/silver"): rarerity = Rarerity.Silver elif self.cvexists("/cardpack/cardinfo/rarerity/bronze"): rarerity = Rarerity.Bronze else: rarerity = Rarerity.Unknown return rarerity cvexists(location, threshold=0.75) URL マッチングの閾値 指定されたリソース定義の中で、メソッドの 実⾏行行に必要なパラメータ情報を取得する。 本来であれば、ifの制御構⽂文は 出現頻度度の⾼高い順に並べるべき。
© 2017, Cygames, Inc., all rights reserved. スクリプト【画像検索索②】 OpenCVのテンプレートマッチングを利利⽤用して、 画像の検索索を⾏行行います。
n API n サンプル 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 API n サンプル 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 API
n サンプル 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 API
n サンプル 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 API n サンプル 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 API n サンプル @util.timeout(seconds=CV_TIMEOUT) def tap_image(self, path, threshold, wait=True, area=None): count = 0 while 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 API n サンプル 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. 質疑応答 もし疑問や質問があれば、 可能な範囲内でお答えします。