Slide 1

Slide 1 text

TIPSTARの自動化 ~泣いて笑って捲られて~ 2022/06/28 テクバン株式会社 市川 駿          株式会社ミクシィ 村田 雄人

Slide 2

Slide 2 text

©mixi, Inc, All rights reserverd. ①自己紹介 ②プロダクト紹介 ③使用ツール ④初アプリ自動化の所感~泣いて~ ⑤第一の壁をどう乗り越えたか~笑って~ ⑥第二の壁~捲られて~ ⑦まとめ アジェンダ 2

Slide 3

Slide 3 text

①自己紹介

Slide 4

Slide 4 text

©mixi, Inc, All rights reserverd. 市川 駿 (テクバン株式会社) • 2021年6月 JOIN • 車券購入機能周りのQAを担当しつつ、自動化担当大臣を兼任 • QA歴=自動化歴:4年(2018年~) • 前の現場ではSelenium WebDriver×Java→Pythonで Webブラウザの自動化を担当 • 趣味:歌、ゴルフ、ヨガ、料理 村田 雄人 (株式会社ミクシィ) • 2019年10月 JOIN • リリース前QAを経て、現在は新機能実装QAを担当しつつPJ改善を推進 • QA歴:6年(QAベンダー→ミクシィ) • JSTQB AL(TM)取得に向けて鋭意勉強中 • 趣味:筋トレ 4 ①自己紹介

Slide 5

Slide 5 text

②プロダクト紹介

Slide 6

Slide 6 text

©mixi, Inc, All rights reserverd. TIPSTAR TIPSTARとは、365日配信されるレース映像と、 競輪・PIST6・オートレースのネット投票を、 基本無料で楽しむことができるサービスです。 6 ②プロダクト紹介

Slide 7

Slide 7 text

③使用ツール

Slide 8

Slide 8 text

©mixi, Inc, All rights reserverd. ①MagicPod • QAメンバー全員が「ノンコーディングによるテスト自動化」を体験 ②UI Automator • UI Automator:AndroidのUIテストフレームワーク • 言語はKotlin(TIPSTARの実装言語なのでエンジニアの方もやりやすい) • IDEはAndroidStudio • 一部のQAメンバー(有志)が、Androidエンジニアの方にサポートいただきながら実装 • 1つのツール(MagicPod)に依存するというリスク回避 8 ③使用ツール

Slide 9

Slide 9 text

④初アプリ自動化の所感 〜泣いて〜

Slide 10

Slide 10 text

©mixi, Inc, All rights reserverd. • 第一の壁:想像以上に苦戦 ①Webブラウザの自動化の知識だけでは太刀打ちできない(似て非なるもの) • Androidエンジニアのサポート必須 • 正規表現、アプリの構造 ②少なからずKotlinの記法知識が必要 ③時間に制約がある仕様だと自動化しづらい(例:レースの時間) ④(Seleniumと比べて)Webに参考になる記事が少ない 10 ④初アプリ自動化の所感〜泣いて〜

Slide 11

Slide 11 text

⑤第一の壁をどう乗り越えたか 〜笑って〜

Slide 12

Slide 12 text

©mixi, Inc, All rights reserverd. • 第一の壁:想像以上に苦戦 ①Webブラウザの自動化の知識だけでは太刀打ちできない(似て非なるもの)   →正規表現:エンジニアの方に聞く、アプリ構造:UI Automator Viewer ②少なからずKotlinの記法知識が必要 ③時間に制約がある仕様だと自動化しづらい(例:レースの締切時間)  →とにかく調べまくる、エンジニアの方に聞く、自分でも勉強する(スクール通ってます) ④(Seleniumと比べて)Webに参考になる記事が少ない  →無いなら作ればいいじゃない  →ミクシィさんの社内ナレッジ共有ツールで記事を都度公開 12 ⑤第一の壁をどう乗り越えたか〜笑って〜

Slide 13

Slide 13 text

©mixi, Inc, All rights reserverd. ①Webブラウザの自動化の知識だけでは太刀打ちできない(似て非なるもの) ▼正規表現 例:TIPSTARの資産であるTIPメダルを取得する val beforeMedal = device.findObject(By.text("^.[,|0-9]+枚$".toRegex().toPattern())) .text .replace(Regex("\\D"), "") .toInt() ▼UI Automator Viewer  スクショすると アプリの構造を見れる 環境構築すれば デフォルトで入ってる 13 ⑤第一の壁をどう乗り越えたか〜笑って〜

Slide 14

Slide 14 text

©mixi, Inc, All rights reserverd. ②少なからずKotlinの記法知識が必要 package com.tipstar.uitest.step
 
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.tipstar.uitest.common.*
 
 class BuyTicketStep(appPackageName: String) : SharedStep(appPackageName) {
 
 /**
 * 競輪で3連単1-2-3をTIPメダルで購入します 
 */
 fun buyKeirinTrifectaByMedal() {
 val toolbarStep = ToolbarUtilStep(appPackageName)
 toolbarStep.waitTitle(“予想を追加”)
 val playerListObject = device.findRecyclerView() // 選手情報をリスト化して取得 
 val wakuObjects = playerListObject?.children // 枠単位のObjectリストを生成 14 ⑤第一の壁をどう乗り越えたか〜笑って〜

Slide 15

Slide 15 text

©mixi, Inc, All rights reserverd. ③時間に制約がある仕様だと自動化しづらい 例:レースの締切時間が近いレースの車券を買いたい // 自分でベット場一覧をリスト化して取得
 val listObject = UiScrollableUtil.findRecyclerView()
 
 // 「締切あと」または「締切 」が含むテキストのパターン
 val votablePattern = "^締切(あと| ).+?$".toRegex().toPattern()
 
 listObject.findObjectWithScrolling(device,By.text(votablePattern))
 ?.click()
 toolbarStep.waitTitle("自分でベット")
 device.waitNotNull(Until.findObjects(By.text("自分でベット")))[1]
 .click() 15 ⑤第一の壁をどう乗り越えたか〜笑って〜

Slide 16

Slide 16 text

⑥第二の壁 〜捲られて〜

Slide 17

Slide 17 text

©mixi, Inc, All rights reserverd. • 第二の壁:ある程度自動化できたが…運用にまたもや苦戦中 • ケース単体では動くが、一括実行すると何故か動かない • 一括で動かすと重いのか…と思ったが、どうやらケースの不備が原因 • 簡単に解決できるものだけではなく、アプリの実装内容を見ないと解決できないものが多い • 例:A機能 •   アプリ側:TrueかFalseかを画面に遷移してから取得している •   UIA側:True(非活性)かFalse(活性)か判断せず、問答無用で連携ボタンを押しに行くのでコケる • 待機(wait) • 待ってほしい時に待ってくれない、待たなくていいのにすごく待つ 17 ⑥第二の壁〜捲られて〜

Slide 18

Slide 18 text

⑦まとめ

Slide 19

Slide 19 text

©mixi, Inc, All rights reserverd. ①コーディングによるアプリ自動化は、最初相当しんどい • Webブラウザ自動化を経験しているとなおさら • ゆくゆくはアプリの実装内容を見ることになる(エンジニアとやっていること変わらない) ②類まれなる努力&エンジニアサポートで、実装に光が差す ③運用でまた曇ったけど、いつかは晴れると信じる • もちろん努力した上での話 19 ⑦まとめ

Slide 20

Slide 20 text

No content