Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~

CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~

CEDEC 2021 の講演資料です。
ノートに講演で話した内容をそのまま記載ありますので、
講演内容を完全に把握したい方はダウンロードしての閲覧をお勧めします。

株式会社セガ 開発技術部 廣島岳史/竹原涼

SEGADevTech

July 15, 2022
Tweet

More Decks by SEGADevTech

Other Decks in Programming

Transcript

  1. Android/iOS 実機上での⾃動テストを
    より楽に有意義にする為に
    〜端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有〜

    View full-size slide

  2. © SEGA
    ⽬次 - Android Android
    端末情報の取得
    ミラーリングの準備
    Androidビルド
    アプリを転送
    録画用ソフトの起動
    アプリを起動
    ミラーリング映像の録画開始
    テストの実行
    ミラーリング映像の録画停止
    アプリを終了
    録画ファイルのリネーム
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ

    View full-size slide

  3. © SEGA
    ⽬次 -iOS
    端末情報の取得
    ミラーリングの準備
    録画用ソフトの起動
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ
    iOS
    XCodeビルド
    アプリを転送・起動
    ミラーリング映像の録画開始
    テスト実行
    ミラーリング映像の録画停止
    アプリの終了
    録画ファイルのリネーム

    View full-size slide

  4. © SEGA
    ゲームコンテンツ&サービス事業本部 技術本部 開発技術部
    廣島 岳史
    ⾃⼰紹介
    SEGA⼊社後
    アーケード向けのライブラリ開発やツール作成などに従事
    最近ではプランナー・デザイナに向けたGitHubEnterprise⽤のツール
    の作成やUnity向け⾃動テスト⽀援ソリューションを開発しています

    View full-size slide

  5. © SEGA
    • 本講演内容の撮影、SNS投稿は OK
    • 後⽇、CEDIL で資料を公開
    • 講演中も質疑が可能です。
    コメントに書き込んでください
    • 講演後にZoomによる質疑応答を実施
    • 資料に記載されている会社名、システム名、製品名、サービス名は各社の登録商標または商標です
    • Android ロボットは、Google が作成および提供している作品から複製または変更したものであり、
    クリエイティブ・コモンズ表⽰ 3.0 ライセンスに記載された条件に従って使⽤しています

    View full-size slide

  6. © SEGA
    • ⾃動テスト全体の流れ
    • テストとその周辺環境に関して
    • 具体的な環境構築の説明
    • 運⽤時に発⽣した問題とその解決⽅法の共有
    • 今後の展望
    アジェンダ

    View full-size slide

  7. © SEGA
    ⾃動テスト環境の構成

    View full-size slide

  8. © SEGA
    構築した⾃動テスト環境の構成図
    USB
    テストフレームワーク
    通信による操作
    パラメータ送受信
    テストの実行
    ネットワーク

    View full-size slide

  9. © SEGA
    本講演で取り上げる部分

    View full-size slide

  10. © SEGA
    使⽤しているソフトウェア
    ミラーリング
    (Android)
    sndcpy
    サウンドのミラーリング用のソフトのみ
    ミラーリング
    (iOS)
    Quick Time Player
    ミラーリング
    (Android)
    scrcpy
    VLC
    RPA Automator
    録画 OBS Studio

    View full-size slide

  11. © SEGA
    ビルド&端末制御&録画担当(Mac)
    アプリケーションのビルド
    端末へのアプリケーションのインストール
    端末情報の収集
    テスト画面の録画
    iOSアプリのビルドを行う事からMacを採用
    Macのバージョンは Big Sur : 11.4
    使用しているMacは Intel CPU

    View full-size slide

  12. © SEGA
    モバイル端末 (iOS / Android)
    主な役割
    アプリケーションの実行
    テストフレームワークとの通信
    ビルドマシンとはUSBを用いて接続
    テストフレームワークとはWi-Fiで通信

    View full-size slide

  13. © SEGA
    全体の流れ(Android) Android
    端末情報の取得
    ミラーリングの準備
    Androidビルド
    アプリを転送
    録画用ソフトの起動
    アプリを起動
    ミラーリング映像の録画開始
    テストの実行
    ミラーリング映像の録画停止
    アプリを終了
    録画ファイルのリネーム
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ

    View full-size slide

  14. © SEGA
    全体の流れ(iOS)
    端末情報の取得
    ミラーリングの準備
    録画用ソフトの起動
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ
    iOS
    XCodeビルド
    アプリを転送・起動
    ミラーリング映像の録画開始
    テスト実行
    ミラーリング映像の録画停止
    アプリの終了
    録画ファイルのリネーム

    View full-size slide

  15. © SEGA
    これらに関してはこの講演では共有しません
    • Android/iOS アプリのビルド
    • テストの実⾏
    • テスト結果の解析や通知
    共有しない項⽬

    View full-size slide

  16. © SEGA
    準備フェーズ
    USB
    端末情報の
    取得
    ミラーリン
    グの準備
    ビルド
    (Android)
    アプリケー
    ションを転送
    (Android)
    録画用ソフ
    トの起動
    1 2 3 4 5

    View full-size slide

  17. © SEGA
    テスト実⾏フェーズ(Android)
    USB
    アプリを起動
    ミラーリン
    グした映像
    の録画開始
    テストの実

    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイ
    ルのリネー

    1 2 3 4 5 6

    View full-size slide

  18. © SEGA
    テスト実⾏フェーズ(iOS)
    USB
    XCodeビルド
    アプリを転
    送・起動
    ミラーリン
    グした映像
    の録画開始
    テスト実行
    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイル
    のリネーム
    3
    2
    1 4 5 6 7

    View full-size slide

  19. © SEGA
    終了フェーズ
    USB
    録画用ソフトの
    終了
    端末映像のミ
    ラーリング停止
    テスト結果の解
    析と通知処理
    1 2 3

    View full-size slide

  20. © SEGA
    Ø なぜ実機テストが必要か
    Ø テストフレームワークについて
    Ø オンプレ⾃前環境 vs クラウドサービス
    Ø ⾃動テストと録画の関係
    本題に⼊る前に

    View full-size slide

  21. © SEGA
    • エミュレータ―を⽤いたテストだけでは不⼗分
    • 端末でのみ発⽣する問題
    なぜ実機でテストを⾏うのか

    View full-size slide

  22. © SEGA
    Ø そもそも関数が無かった
    Ø ネイティブの関数の挙動が変わっていた
    特定の端末・特定のバージョンで発⽣した
    動かしてみるまで分からない
    特定の端末で発⽣した不具合

    View full-size slide

  23. © SEGA
    テストフレームワークについて

    View full-size slide

  24. © SEGA
    • テストプロジェクトの作成
    • テストスクリプトの作成
    • テストスクリプトの実⾏
    • テストレポートの出⼒
    テストフレームワークの主な役割

    View full-size slide

  25. © SEGA
    ØNUnit
    Øxunit
    ØMSTest.TestFramework
    ØSelenium
    ØAppium
    代表的なテストフレームワーク
    ブラウザ
    .NET
    .NET
    .NET
    モバイル

    View full-size slide

  26. © SEGA
    • テストフレームワークとアプリケーションが
    どのようにやり取りをするのかがポイント
    テストフレームワークと環境構築
    テストコード

    View full-size slide

  27. © SEGA
    • ゲームでは独⾃フレームワークの場合も多い
    環境構築を視野に⼊れる事が重要
    テストフレームワークを選定・実装する際
    は、自動テスト環境の構築まで視野に入れて
    選定を行う事をお勧めします

    View full-size slide

  28. © SEGA
    ⾃動テスト環境の準備

    View full-size slide

  29. © SEGA
    クラウドのテストサービス
    近年端末の種類も豊富なクラウドのテストサービ
    スが多く登場
    ü AWS Device Farmなどが有名
    ü サービスを介して実機でテストを実行
    ü 端末を用意する必要が無い
    ü 端末の種類も豊富
    テストコード

    View full-size slide

  30. © SEGA
    • 以前はオンプレしか選択肢は無かった
    • プロジェクトの都合や予算で判断
    オンプレミス vs クラウドサービス

    View full-size slide

  31. © SEGA
    • 並列実⾏に強み
    • 端末を⽤意する必要が無い
    • 端末の種類が豊富
    クラウドサービスの特徴(メリット)

    View full-size slide

  32. © SEGA
    • お値段
    • 使⽤可能なテストフレームワークに制限がかか
    る事もある
    • 他の⼈が端末を利⽤していて使えない事も
    クラウドサービスの特徴(デメリット)

    View full-size slide

  33. © SEGA
    • お値段
    • ⾃前のテストフレームワークの採⽤が可能
    • テスト実⾏していない時は別の⽤途に転⽤可能
    オンプレミス環境の特徴(メリット)

    View full-size slide

  34. © SEGA
    • 端末を⽤意する必要がある
    • 構築・運⽤については全て⾃前
    • 構築に関する知識が必要
    ü当講演で解消可能︕
    オンプレミス環境の特徴(デメリット)

    View full-size slide

  35. © SEGA
    ハイブリッド(クラウド+オンプレミス)
    USB
    Azure pipelines self hosted agent
    ビルドからデプロイまでをクラウドで実行
    テストをオンプレミスで実行
    Azure Pipelines self –hosted agent を使う

    View full-size slide

  36. © SEGA
    • お値段
    • 独⾃形式のテストフレームワーク
    • 導⼊するプロジェクトの秘匿性が⾼くテスト環
    境を外に出すリスクが取れなかった
    オンプレミスを採⽤しました

    View full-size slide

  37. © SEGA
    テスト実⾏中の録画について

    View full-size slide

  38. © SEGA
    • 再現性の低いバグの発⽣⼿順の確⽴
    • 不具合の内容確認の容易性
    実機テストでの録画の必要性
    Ø 自動テストレポートにテスト動画を含める
    Ø BugTrackingSystemに動画付きで投稿する
    効果的な使用例

    View full-size slide

  39. © SEGA
    • ミラーリングしたものを録画
    • 端末で録画
    • HDMI分配器を利⽤する
    • カメラを⽤いて直接撮影する
    録画⼿法について

    View full-size slide

  40. © SEGA
    ミラーリング
    メリット
    • タイトル毎に録画機能を実装しな
    くて良い
    • 録画ファイルの取り扱いが簡単
    デメリット
    • 複数端末同時録画が難しい
    ミラーリングソフト
    録画を行うデバイス

    View full-size slide

  41. © SEGA
    端末で録画
    メリット
    • 複数端末同時録画が可能
    • 並列でテストが可能
    デメリット
    • タイトル毎に録画機能の実装が必要
    • 端末毎にデバッグ
    • 録画ファイルの取り扱いが複雑
    画面を録画
    録画データ転送

    View full-size slide

  42. © SEGA
    HDMI分配器を利⽤する
    メリット
    • 環境構築が容易
    • 録画機能を実装しなくて良い
    デメリット
    • 端末との相性問題
    • 端末数分の分配器⽤意する必
    要がある
    MHL変換アダプタ
    HDMI分配器
    録画を行うデバイス

    View full-size slide

  43. © SEGA
    カメラで録画
    メリット
    • 環境構築が⽐較的容易
    デメリット
    • 録画データの取り扱いが複雑
    • 録画データのエンコーディン
    グを⾃分で⾏う必要がある
    • 複数端末分の機材が必要

    View full-size slide

  44. © SEGA
    採⽤理由
    • タイトル毎に録画機能を実装しなくて良い
    • データの取り扱いが容易な点
    • 複数端末での実⾏が可能な点
    が決め⼿になりました
    ミラーリングを採⽤しました

    View full-size slide

  45. © SEGA
    • Andoroidでの録画⽅法
    – MediaProjection APIで録画
    – REQUEST_MEDIA_PROJECTIONなどの権限
    が必要
    • iOSでの録画⽅法
    – ReplayKit について
    端末での録画を⾏う場合(補⾜)

    View full-size slide

  46. © SEGA
    前半まとめ
    テストフレームワーク 自動化を視野に選定・実装しましょう
    自動化環境 クラウドサービスも多く存在します
    録画
    自動テストと録画は相性◎
    積極的に利用しましょう

    View full-size slide

  47. © SEGA
    ゲームコンテンツ&サービス事業本部 技術本部 開発技術部
    ⽵原 涼
    ⾃⼰紹介
    【登壇歴】
    CEDEC 2020 「技術同⼈作家になろう 〜働き⽅改⾰時代におけるエン
    ジニアのレベルアップの⼀例〜」
    Unite Tokyo 2019 「⼤量のアセットも怖くない︕〜HTTP/2による⾼
    速な通信の実装例〜」
    CEDEC 2018、CEDEC 2016、CEDEC 2015 プロダクション関連のラ
    ウンドテーブル
    GDC2016 報告会 「GDC16にみる⾃動化技術とテストのトレンド」

    View full-size slide

  48. © SEGA
    具体的な環境構築の流れ

    View full-size slide

  49. © SEGA
    • 右上にプラットフォームを⽰すアイコンがあります
    資料の⾒⽅ Android
    iOS

    View full-size slide

  50. © SEGA
    準備フェーズ
    端末情報の取得
    ミラーリングの準備
    Androidビルド
    アプリを転送
    録画用ソフトの起動
    アプリを起動
    ミラーリング映像の録画開始
    テストの実行
    ミラーリング映像の録画停止
    アプリを終了
    録画ファイルのリネーム
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ

    View full-size slide

  51. © SEGA
    端末情報の
    取得
    ミラーリン
    グの準備
    ビルド
    (Android)
    アプリケー
    ションを転送
    (Android)
    録画用ソフ
    トの起動
    端末情報の取得
    USB
    1 2 3 4 5

    View full-size slide

  52. © SEGA
    • 実機へのアプリ転送・実⾏には端末情報が必要
    • Android
    ü デバイス名/デバイスID
    • iOS
    ü デバイス名/UUID
    • IPアドレスも必要な場合はここで取得しておくと楽
    端末情報の取得

    View full-size slide

  53. © SEGA
    • adbコマンド結果をパースすることにより取得
    • デバイス名/ID
    ü adb devices –l
    • IPアドレス
    ü adb -s “デバイスID” shell ip addr show
    端末情報の取得 Android

    View full-size slide

  54. © SEGA
    Extended Choice Parameter Plugin を利⽤してビルドパラメータで
    端末IDを選択可能に
    def p = "adb devices -l".execute()
    p.waitFor()
    def idList = []
    def deviceNameList = []
    def lines = p.inputStream.readLines()
    lines.each {
    def matcher = (it =~ /([0-9a-zA-Z]+) (.+)model:(.+) device:/)
    while (matcher.find()) {
    idList.add(matcher.group(1))
    deviceNameList.add(matcher.group(3))
    }
    }
    return deviceNameList
    端末情報の取得 - Jenkins例 Android

    View full-size slide

  55. © SEGA
    選択されたデバイスIDからIPアドレスを取得する
    def id = ““ // id には先ほど選択された値を⼊れる
    def ip = ”“
    def ipaddr = String.format(“adb -s %s shell ip addr show”, id).execute()
    ipaddr.waitFor()
    def ipLines = ipaddr.inputStream.readLines()
    ipLines.each {
    def ipMatcher = (it =~ /inet ([0-9.]+)¥/([0-9]+) brd/)
    while (ipMatcher.find()) {
    ip = ipMatcher.group(1)
    }
    }
    // ここでipをファイルに書き込むなり何なりして下流に受け渡す
    端末情報の取得 - Jenkins例 Android
    VPNを張っている場合はVPNソフトに合わせた条件に
    変えてあげる必要有り

    def ipMatcher = (it =~ /inet ([0-9.]+)¥/([0-9]+) scope global tun0/)

    View full-size slide

  56. © SEGA
    • xcrunコマンド結果をパースすることにより取得
    • デバイス名/UUID
    ü xcrun instruments –s
    • IPアドレス
    ü Bonjourの利⽤がお勧め
    端末情報の取得 iOS

    View full-size slide

  57. © SEGA
    • 対応端末にデバイス名指定でアクセスできる
    • デバイス名に.localを付けてアクセス
    ü デバイス名は準備フェーズで取得したものを流⽤
    Bonjour iOS

    View full-size slide

  58. © SEGA
    • 以下のいずれかで実現
    ü ⾃前でBonjourを実装しIPアドレス取得
    ü Bonjour対応アプリをMacOS上で起動しておく
    Bonjourを使ったアクセス iOS

    View full-size slide

  59. © SEGA
    • 同⼀LAN内限定
    • ActiveDirectoryと併⽤する場合に注意
    ü ローカルドメイン名に.localは使わない
    Bonjour注意事項 iOS

    View full-size slide

  60. © SEGA
    • パケットキャプチャをすることで対応可能
    ü 特殊な事例且つ⻑くなるので詳細はAppendixで
    ü Unityの場合の具体例が掲載されています
    ⾮同⼀LAN環境への対応 iOS

    View full-size slide

  61. © SEGA
    Android同様Extended Choice Parameterでビルドパラメータ化
    def devices = “xcrun instruments -s”.execute()
    devices.waitFor()
    def deviceNameList = []
    def lines = devices.inputStream.readLines()
    lines.each {
    def matcher = (it =~ /([^ ]+) ¥(([0-9.]+)¥) ¥[([¥-A-Za-z0-9]+)¥]$/)
    while (matcher.find()) {
    deviceNameList.add(matcher.group(1))
    }
    }
    return deviceNameList
    端末情報の取得 - Jenkins例 iOS

    View full-size slide

  62. © SEGA
    ミラーリングの準備
    端末情報の
    取得
    ミラーリン
    グの準備
    ビルド
    (Android)
    アプリケー
    ションを転送
    (Android)
    録画用ソフ
    トの起動
    USB
    1 2 3 4 5

    View full-size slide

  63. © SEGA
    • 公式のミラーリングソフトは存在しない
    ü OSS やフリーのツールを利⽤するのが⼀般的
    • 検証を⾏ったもの
    ü 〇 scrcpy 採⽤︕
    ü △ ApowerMirror
    ü ✖ Androidtool-mac, Vysor, Mobizen
    ソフトウェアの選定 Android

    View full-size slide

  64. © SEGA
    • shell から操作可能
    • オプションが豊富
    • 端末にアプリケーションのインストールが不要
    • USB経由でミラーリング可能
    • ミラーリングされた画⾯からタッチ操作可能
    scrcpyの特徴 Android

    View full-size slide

  65. © SEGA
    • ⾳声ミラーリング機能はない
    • 録画機能は可能だが無圧縮
    • コマンドで起動後、処理が返ってこない
    scrcpy注意事項 Android

    View full-size slide

  66. © SEGA
    • 以下の3通りのいずれかで対応可能
    1. ProcessTreeKillerから逃れる (お勧め︕)
    2. Pipelineで並列化する
    3. AppleScriptを使ってJenkinsから切り離す
    scrcpyをJenkinsで使う場合 Android

    View full-size slide

  67. © SEGA
    • Jenkinsはジョブ中に起動したプロセスをその
    ジョブ終了時に強制終了する
    ü https://wiki.jenkins.io/display/JENKINS/ProcessTreeKiller
    • nohup & を使ってもジョブを抜ける際にアウト
    ProcessTreeKiller補⾜ Android

    View full-size slide

  68. © SEGA
    • shellの場合は環境変数 BUILD_ID に
    dontKillMe プロセスパス(名) を⼊れて回避
    • shell設定例
    ü export BUILD_ID=dontKillMe scrcpy
    nohup scrcpy &
    ProcessTreeKiller補⾜ Android

    View full-size slide

  69. © SEGA
    • PipelineはJENKINS_NODE_COOKIEに設定
    • Pipeline実⾏例
    ü steps {
    sh '''
    export JENKINS_NODE_COOKIE=dontkillMe
    nohup scrcpy &
    '''
    }
    ProcessTreeKiller補⾜ Android

    View full-size slide

  70. © SEGA
    • sndcpyを使う
    ü scrcpyと⼀緒に使う為に作成されたOSS
    ⾳声ミラーリングしたい Android

    View full-size slide

  71. © SEGA
    • Android 10から使⽤可能
    ü 内部的にAudioPlaybackCapture APIを使⽤
    • 端末へのアプリケーションインストールが必要
    sndcpy注意事項 Android

    View full-size slide

  72. © SEGA
    sndcpyというスクリプト内で以下が実⾏される
    1. sndcpyを端末へインストール
    2. 端末上でsndcpy起動
    3. 端末側でポップアップが出る
    4. ポップアップを閉じる (⼿動で「今すぐ開始」を押す)
    5. PC側でVLCを起動する
    ⾳声ミラーリングまでの流れ Android
    ここを⾃動化したい

    View full-size slide

  73. © SEGA
    • ポップアップはAndroid側が出しているので抑制
    できない
    • 最終⼿段のAutomatorを利⽤
    ü MacOSに標準搭載されているというRPAツール
    sndcpyカスタマイズ Android

    View full-size slide

  74. © SEGA
    • ユーザ操作を記録・再現するRPAツール
    ü アプリケーションとして保存できる
    ü 内部的にはAppleScript(後述)に落とし込まれる
    • レイアウトの変更には弱い
    ü なるべく座標指定しないような実装にはなっている
    Automator Android

    View full-size slide

  75. © SEGA
    • Apple 独⾃のスクリプト⾔語
    • shellから呼び出し可能
    ü shellの先頭に #!/usr/bin/env osascript を付ける
    • キーボードやマウス等の操作が可能
    AppleScript Android

    View full-size slide

  76. © SEGA
    • 資料が少ない
    ü オンラインの公式ドキュメントは情報が古いことも
    • AppleScriptメニュー内にある⽤語説明がお勧め
    AppleScript注意事項 Android

    View full-size slide

  77. © SEGA
    • 画⾯ロック中は操作できないものがある
    ü キーボード、マウス操作
    AppleScript注意事項 Android

    View full-size slide

  78. © SEGA
    • 簡単な操作ならAppleScript単体で実装する
    • 複雑な操作はAutomatorで実装する
    ü AppleScriptに変換して細部を修正可能
    Automator運⽤⽅針 Android

    View full-size slide

  79. © SEGA
    ポップアップクローズの⾃動化 Android

    View full-size slide

  80. © SEGA
    Automatorで記憶された操作 Android

    View full-size slide

  81. © SEGA
    Automatorの修正 Android
    ドラッグ&ドロップ
    項⽬の内容がコピーされる

    View full-size slide

  82. © SEGA
    Automatorの修正 Android
    ドラッグ&ドロップ
    コピーなので保存してもこの中の項⽬には反映されない
    これは1個⽬のコピー(編集はコピーしかできない)
    これは2個⽬のコピー

    View full-size slide

  83. © SEGA
    Automatorの修正 Android
    イベントをここから全部消せる

    View full-size slide

  84. © SEGA
    Automatorの修正 Android

    View full-size slide

  85. © SEGA
    • ポップアップを閉じたことを確認してから次の
    処理に進みたい
    ü openコマンドでは終了を待てない
    • Automatorアプリ終了を待つAppleScriptを作成
    Automatorアプリの終了を待つ Android

    View full-size slide

  86. © SEGA
    !"#$!%#&'()*"+,--.-/
    !"#$%'()#*)+,-%.%/&(01
    -),&$),23-4/-55.)36,0&-/*%%4).5*7
    1*88,.008(/.1(-),9:*&5().89
    3- %/&(01,3-4/-55.)3,() /$&&*)1:.'
    3*8.;,<=>
    1*88,.008(/.1(-),9?;%1*5,@+*)1%9
    &*0*.1
    (A )-1,B*C(%1%,0&-/*%%,0&-/*%%4).5*D,1E*)
    *C(1 &*0*.1
    *)3,(A
    3*8.;,<=>
    *)3,&*0*.1
    *)3,1*88
    *)3,1*88
    *)3,&$)
    Automatorアプリの終了を待つ Android
    引数で受け取ったコマンドを実⾏
    起動したプロセスが存在する限り待つ

    View full-size slide

  87. © SEGA
    1. sndcpyを端末へインストール
    2. sndcpy起動
    3. 端末側でポップアップが出る
    4. ポップアップを閉じる
    5. PC側でVLCを起動する
    ⾳声ミラーリングまでの流れ Android
    sndcpyを分割して⾃前のAutomatorの処理を挟む
    strat_vlc.sh
    sndcpy
    Automator処理

    View full-size slide

  88. © SEGA
    #!/bin/bash
    set –e
    ADB=${ADB:-adb}
    SNDCPY_APK=${SNDCPY_APK:-sndcpy.apk}
    SNDCPY_PORT=${SNDCPY_PORT:-28200}
    serial=
    if [[ $# -ge 1 ]]
    then
    serial="-s $1“
    echo "Waiting for device $1...“
    else
    echo 'Waiting for device...ʻ
    fi
    "$ADB" $serial wait-for-device
    "$ADB" $serial install -t -r -g "$SNDCPY_APK" ||
    {
    echo 'Uninstalling existing version first...ʻ
    "$ADB" $serial uninstall com.rom1v.sndcpy
    "$ADB" $serial install -t -g "$SNDCPY_APK“
    }
    "$ADB" $serial forward tcp:$SNDCPY_PORT localabstract:sndcpy
    "$ADB" $serial shell am start com.rom1v.sndcpy/.MainActivity
    sndcpy分割 (sndcpy) Android

    View full-size slide

  89. © SEGA
    #!/bin/bash
    set –e
    export VLC=/Applications/VLC.app/Contents/MacOS/VLC
    VLC=${VLC:-vlc}
    SNDCPY_PORT=${SNDCPY_PORT:-28200}
    "$VLC" -Idummy --demux rawaud --network-caching=50 --play-and-exit tcp://localhost:"$SNDCPY_PORT"
    sndcpy分割 (start_vlc) Android

    View full-size slide

  90. © SEGA
    export BUILD_ID=dontKillMe scrcpy
    nohup scrcpy –b 30M –window-title ʻTitleʼ –turn-screen-off –serial $ANDROID_ID &
    scrcpy - Jenkins例 Android
    オプションの意味は以下の通り
    • 端末のモニタの電源を切って起動
    • ビットレートは30Mbps
    • ウィンドウのタイトルを「Title」にする
    ü 後述する録画の際に必要になってくるので必ず付ける
    • ANDROID_IDで指定したIDの端末をミラーリング

    View full-size slide

  91. © SEGA
    # sndcpyインストールと起動
    ./sndcpy
    # ポップアップの抑制
    ./doandwait_process.sh "exec open -a SupSndcpyPopup" "SupSndcpyPopup"
    # VLCの起動
    export BUILD_ID=dontKillMe start_vlc
    nohup ./start_vlc &
    sndcpy - Jenkins例 Android

    View full-size slide

  92. © SEGA
    • scrcpy/sndcpyはWindowsにも対応
    ü sndcpy.batを使う等細かい差異はあるが基本同じ対
    応で⾃動化可能
    • ポップアップの抑制にはWindows対応のRPA
    ツールで代⽤を
    Windowsでミラーリング Android

    View full-size slide

  93. © SEGA
    • Quick Time Playerでミラーリングが可能
    ü MacOSに標準インストール
    • Quick Time Player以外の候補は⾒つからず
    • ⾃動化についてはハマり所がいくつかある
    ソフトウェアの選定 iOS

    View full-size slide

  94. © SEGA
    • Quick Time Playerで録画することは可能
    ü ただしエンコーディング無し
    Quick Time Playerでの録画 iOS

    View full-size slide

  95. © SEGA
    • ミラーリング映像から操作が可能
    • shell経由での細かい実⾏をサポートしていない
    • 最終的に再びAutomatorに頼ることに
    Quick Time Playerの⾃動化 iOS

    View full-size slide

  96. © SEGA
    Automatorでの起動 iOS

    View full-size slide

  97. © SEGA
    export BUILD_ID=dontKillMe start_iphone_mirroring
    nohup open -a start_iphone_mirroring &
    Quick Time Player – Jenkins例 iOS

    View full-size slide

  98. © SEGA
    • 複数のiPhoneが接続されている場合、Android
    同様に端末を指定したい
    複数デバイス対応 iOS

    View full-size slide

  99. © SEGA
    • Automatorアプリは起動時引数に制限がある
    ü ファイルパスしか渡せない
    • 環境変数にデバイス名を保存しておき、それを
    Automator内のAppleScriptで読み込む
    複数デバイス対応 - Automator iOS

    View full-size slide

  100. © SEGA
    AppleScriptを実⾏(devtech-iphoneを選択)の書き換え
    元の実装
    set uiScript to “click menu item ¥”devtech-iphone¥“ of menu 1 of UI Element 5 of window 1 of application process ¥”QuickTime Player¥““
    修正後の実装
    set deviceName to system attribute "DeviceName“
    set uiScript to "click menu item ¥"" & deviceName & "¥" of menu 1 of UI Element 5 of window 1 of application process ¥"QuickTime Player¥""
    複数デバイス対応 -AppleScript iOS
    デバイス名が埋まっているのでここを動的に差し替える
    • 呼び出し元で環境変数DeviceNameにデバイス名をexportしておく
    • 環境変数はAppleScriptからは to system attribute で読める

    View full-size slide

  101. © SEGA
    複数デバイス対応- Jenkins例 iOS
    export BUILD_ID=dontKillMe start_iphone_mirroring
    export DeviceName=“devtech-iphone“
    nohup open -a start_iphone_mirroring &
    Jenkins側は環境変数設定を挟むだけでOK
    “あいふぉん”のような⽇本語はアウトなので注意

    View full-size slide

  102. © SEGA
    録画⽤ソフトの起動
    端末情報の
    取得
    ミラーリン
    グの準備
    ビルド
    (Android)
    アプリケー
    ションを転送
    (Android)
    録画用ソフ
    トの起動
    USB
    1 2 3 4 5
    Android

    View full-size slide

  103. © SEGA
    テスト実⾏フェーズ Android
    端末情報の取得
    ミラーリングの準備
    Androidビルド
    アプリを転送
    録画用ソフトの起動
    アプリを起動
    ミラーリング映像の録画開始
    テストの実行
    ミラーリング映像の録画停止
    アプリを終了
    録画ファイルのリネーム
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ
    ビルド・転送は準備フェーズに実⾏
    起動のみテスト毎に実⾏することで効率アップ

    View full-size slide

  104. © SEGA
    • adb.exeを使⽤する
    ü adb -s “デバイスID” install ”アプリケーションイメージのパス”
    アプリの転送 Android

    View full-size slide

  105. © SEGA
    adb -s $ANDROID_ID install $APPLICATION_PATH
    アプリの転送 – Jenkins例 Android

    View full-size slide

  106. © SEGA
    録画⽤ソフトの起動
    端末情報の
    取得
    ミラーリン
    グの準備
    ビルド
    (Android)
    アプリケー
    ションを転送
    (Android)
    録画用ソフ
    トの起動
    USB
    1 2 3 4 5

    View full-size slide

  107. © SEGA
    • 検証を⾏ったもの
    ü 〇 OBS Studio 採⽤︕
    ü △ scrcpy/Quick Time Player
    ソフトウェアの選定 Android iOS

    View full-size slide

  108. © SEGA
    • シェルから起動オプションが指定可能
    • ほぼ全ての操作のキーボードショートカット有
    • websocketによる操作も可能
    • 録画と同時にエンコーディング可能
    • 配信でよく利⽤されており更新が⾮常に活発
    OBS Studioの特徴 Android iOS

    View full-size slide

  109. © SEGA
    • OBSはプロファイル単位で種々の設定が可能
    ü 起動時の引数でこのプロファイルを指定できる
    • ⾃動化⽤にプロファイルを作成しておく
    ü プロファイル名にIDやデバイス名を使うと楽
    事前設定 - プロファイル Android iOS

    View full-size slide

  110. © SEGA
    • プロファイル毎に設定可能
    • 複数の端末でテストを⾏う場合
    ü プロファイルを端末毎に作成
    Ø 端末数が多い場合にプロファイルの作成が⼿間
    ü 全ての解像度を包含できるような解像度で作成
    Ø 余⽩ができてしまい⾒栄えが悪い(がテスト⽤途なので気にしない)
    事前設定 – キャンバス Android iOS

    View full-size slide

  111. © SEGA
    • 録画対象のウィンドウの設定が必要
    • 名前で指定する
    ü iOSはQuickTimePlayerのウィンドウ名をそのまま
    ü Androidはscrcpyのオプションで指定
    事前設定 – シーン Android iOS

    View full-size slide

  112. © SEGA
    • シェル経由で終了することができない
    • 録画中にkillすると映像ファイルが壊れる
    • 「録画開始」、「録画終了」のキーボード
    ショートカットを設定し操作
    事前設定 – ショートカット Android iOS

    View full-size slide

  113. © SEGA
    • SoundFlowerというツールが必要
    • OSとOBS両⽅でSoundFlowerの設定を⾏う
    事前設定 – 録⾳ Android iOS

    View full-size slide

  114. © SEGA
    • --startrecording で起動後⾃動で録画開始する
    • --profile “name” でプロファイル指定可能
    • その他のパラメータは公式ドキュメント参照
    ü https://github.com/obsproject/obs-studio/wiki/Launch-Parameters
    OBSの起動時引数 Android iOS

    View full-size slide

  115. © SEGA
    export BUILD_ID=dontKillMe obs
    nohup open -a obs --args --profile $PROFILE_NAME &
    OBS – Jenkins例 Android iOS
    • 起動後自動で録画開始したい場合は --startrecording を入れる
    • 構築した環境ではテスト毎にOBS起動するコストが無駄なので起動と録
    画開始は切り離している為にここでは –startrecording は入れていない

    View full-size slide

  116. © SEGA
    • OBSもWindowsに対応
    • キーストロークを⾏うアプリでショートカット
    を操作する
    Windowsで録画 Android

    View full-size slide

  117. © SEGA
    • ロック中やRDPで運⽤しているPCでの録画は⼀
    ⼯夫必要
    ü Macはロック中でも録画可能
    • 資料末尾にAppendixとして記載
    Windowsで録画

    View full-size slide

  118. © SEGA
    テスト実⾏フェーズ Android
    端末情報の取得
    ミラーリングの準備
    Androidビルド
    アプリを転送
    録画用ソフトの起動
    アプリを起動
    ミラーリング映像の録画開始
    テストの実行
    ミラーリング映像の録画停止
    アプリを終了
    録画ファイルのリネーム
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ

    View full-size slide

  119. © SEGA
    アプリケーションを転送・起動
    USB
    アプリケー
    ションを起動
    ミラーリング
    した映像の録
    画開始
    テストの実行
    ミラーリング
    した映像の録
    画停止
    録画ファイル
    のリネーム
    1 2 3 4 5
    Android

    View full-size slide

  120. © SEGA
    • 転送同様にadb.exeを使⽤する
    ü adb -s “デバイスID” shell am start “パッケージ名/アクティビティ名”
    アプリの起動 Android

    View full-size slide

  121. © SEGA
    adb -s $ANDROID_ID shell am start "$PACKAGE_NAME/$ACTIVITY_NAME"
    アプリの起動 – Jenkins例 Android

    View full-size slide

  122. © SEGA
    全体の流れ(iOS) iOS
    端末情報の取得
    ミラーリングの準備
    録画用ソフトの起動
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ
    XCodeビルド
    アプリを転送・起動
    ミラーリング映像の録画開始
    テスト実行
    ミラーリング映像の録画停止
    アプリの終了
    録画ファイルのリネーム

    View full-size slide

  123. © SEGA
    USB
    XCodeビルド
    アプリを転
    送・起動
    ミラーリン
    グした映像
    の録画開始
    テスト実行
    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイル
    のリネーム
    3
    2
    1 4 5 6 7
    アプリケーションを転送・起動

    View full-size slide

  124. © SEGA
    • 転送/起動にはxcodebuildを⽤いる
    • xcodebuildでビルドと転送/起動を分ける
    ü build-for-testing : ビルドのみ実⾏
    ü test-without-building : 転送/起動を実⾏
    アプリの転送/起動 iOS

    View full-size slide

  125. © SEGA
    • 連続実⾏すると失敗する
    ü 端末側の状態がリセットされない
    ü フルビルドで解消
    test-without-building注意事項 iOS

    View full-size slide

  126. © SEGA
    アプリのビルド/転送/起動
    端末情報の取得
    ミラーリングの準備
    録画用ソフトの起動
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ
    XCodeビルド
    アプリを転送・起動
    ミラーリング映像の録画開始
    テスト実行
    ミラーリング映像の録画停止
    アプリの終了
    録画ファイルのリネーム
    毎回フルビルドしたくない︕︕
    iOS

    View full-size slide

  127. © SEGA
    • XCodeのキャッシュ内に⽣成された.appを削除
    してbuild-for-testingすることで回避
    ü .appの再⽣成だけなのでビルド時間は短い
    test-without-building連続実⾏ iOS

    View full-size slide

  128. © SEGA
    • キャッシュされた.appのパス
    ü /Library/Developer/Xcode/DerivedData/"xcodeproj名"-"ハッシュ値"
    /Build/Products/Debug-iphoneos/"プロダクト名".app
    • ハッシュ値の動的取得⽅法は不明
    ü ⼀度決まると変わることはないので、環境構築時に⼀
    度⼿動でビルドして確認
    test-without-building連続実⾏ iOS

    View full-size slide

  129. © SEGA
    • Xcodeのテストであるxctestが必要
    • 何もせずに永久に待機し続けるxctestを実⾏する
    ことにより疑似的にアプリの起動を再現する
    test-without-buildingを使うには iOS

    View full-size slide

  130. © SEGA
    cd "Xcodeプロジェクト配置パス"
    # .appを削除
    rm -rf /Library/Developer/Xcode/DerivedData/$XCODE_PROJ_NAME-
    $XCODE_DERIVED_HASH/Build/Products/Debug-iphoneos/$PRODUCT_NAME.app
    # xcodebuildでアプリケーションビルドのみ実⾏
    xcodebuild build-for-testing "platform=iOS,id=$IPHONE_UUID" -scheme "実⾏したいXcodeのScheme名"
    ARCHS=$ARCH_TYPE
    アプリのビルド – Jenkins例 iOS

    View full-size slide

  131. © SEGA
    cd “Xcodeプロジェクト配置パス”
    # xcodebuildでアプリケーションを転送/起動する
    xcodebuild test-without-building -destination “platform=iOS,id=$IPHONE_UUID” -scheme
    “実⾏したいXcodeのScheme名" ARCHS=$ARCH_TYPE
    アプリの転送/起動 – Jenkins例 iOS

    View full-size slide

  132. © SEGA
    • 現在βのXcode13に追加される以下のオプション
    で再ビルド不要になりそう(未検証)
    ü -test-itreations
    ü -retry-tests-on-failure
    ü -run-tests-until-failure
    補⾜① - test-without-building iOS

    View full-size slide

  133. © SEGA
    • Xcode(GUI)からキーボードショートカット経由
    で転送/起動する⼿もある
    ü Automator(AppleScript)から操作
    • RPAツールの利⽤はあくまで最終⼿段
    ü 他の解決⽅法がある場合はそちらの採⽤がお勧め
    補⾜② - Xcodeをキーボード操作 iOS

    View full-size slide

  134. © SEGA
    USB
    アプリを起動
    ミラーリン
    グした映像
    の録画開始
    テストの実

    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイ
    ルのリネー

    1 2 3 4 5 6
    録画開始 Android

    View full-size slide

  135. © SEGA
    USB
    XCodeビルド
    アプリを転
    送・起動
    ミラーリン
    グした映像
    の録画開始
    テスト実行
    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイル
    のリネーム
    3
    2
    1 4 5 6 7
    録画開始 iOS

    View full-size slide

  136. © SEGA
    • OBSの事前設定で決めたキーボードショート
    カットを使⽤する
    • 呼び出しはAppleScriptを⽤いる
    録画開始 Android iOS

    View full-size slide

  137. © SEGA
    ショートカットに設定したキーを押下する
    #!/usr/bin/env osascript
    tell application "OBS“
    activate
    tell application "System Events“
    keystroke "s" using {command down, option down}
    end tell
    end tell
    録画開始(AppleScript) Android iOS

    View full-size slide

  138. © SEGA
    USB
    アプリを起動
    ミラーリン
    グした映像
    の録画開始
    テストの実

    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイ
    ルのリネー

    1 2 3 4 5 6
    テストの実⾏ Android iOS

    View full-size slide

  139. © SEGA
    • テストフレームワーク次第ではこのタイミング
    で実⾏開始が必要
    テストの実⾏ Android iOS
    通信による操作
    パラメータ送受信
    テストの実行

    View full-size slide

  140. © SEGA
    • 例︓今回構築した環境
    テストの実⾏(例) Android iOS
    Jsonでテストしたい動作を指定
    • テストケースに沿って操作を送信
    • 返信結果からテストの成否を判定
    Jsonを解析して侵入型の
    テストを実行
    指定した動作の結果を返信

    View full-size slide

  141. © SEGA
    • アプリの起動タイミングに仕込む
    ü 実⾏時の引数
    Ø adbは引数オプション有り
    Ø xcodebuildはプリプロセッサマクロを活⽤
    ü テスト⽤コンフィグファイル
    Ø アプリ起動前に毎回端末に転送し直す等
    テストの実⾏(⾮通信型) Android iOS

    View full-size slide

  142. © SEGA
    録画停⽌ Android iOS
    USB
    アプリを起動
    ミラーリン
    グした映像
    の録画開始
    テストの実

    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイ
    ルのリネー

    1 2 3 4 5 6

    View full-size slide

  143. © SEGA
    • 録画開始同様キーボードショートカットを使⽤
    #!/usr/bin/env osascript
    tell application "OBS“
    activate
    tell application "System Events“
    keystroke “q" using {command down, option down}
    end tell
    end tell
    録画終了 Android iOS

    View full-size slide

  144. © SEGA
    USB
    アプリを起動
    ミラーリン
    グした映像
    の録画開始
    テストの実

    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイ
    ルのリネー

    1 2 3 4 5 6
    アプリの終了 Android iOS

    View full-size slide

  145. © SEGA
    • adb.exeで終了させる
    ü adb -s “デバイスID” shell am force-stop “パッケージ名”
    アプリの終了 Android

    View full-size slide

  146. © SEGA
    adb -s $ANDROID_ID shell am force-stop $PACKAGE_NAME
    アプリの終了 – Jenkins例 Android

    View full-size slide

  147. © SEGA
    • xcodebuildをpkillする
    ü pkill “xcodebuild"
    アプリの終了 iOS

    View full-size slide

  148. © SEGA
    USB
    アプリを起動
    ミラーリン
    グした映像
    の録画開始
    テストの実

    ミラーリン
    グした映像
    の録画停止
    アプリを終了
    録画ファイ
    ルのリネー

    1 2 3 4 5 6
    録画停⽌ Android iOS

    View full-size slide

  149. © SEGA
    • OBSのファイル名書式は⽇時等柔軟に指定可能
    • しかし、起動時引数のようなものでテスト名を
    動的に付与することはできない
    録画ファイルのリネーム Android iOS

    View full-size slide

  150. © SEGA
    • テスト終了毎にファイルをテスト名を付与した
    ものにリネームしてあげると結果確認時に分か
    り易い
    • shell例(移動するついでにリネーム)
    ü mv -f $OBS_OUTPUT_PATH/*.mp4 $STORAGE_PATH/$TEST_NAME¥_`date "+%Y%m%d%H%M"`.mp4
    録画ファイルのリネーム Android iOS
    ※CatchExceptionTest_202104021241.mp4のような名前で保存される

    View full-size slide

  151. © SEGA
    具体的な環境構築の流れ
    端末情報の取得
    ミラーリングの準備
    Androidビルド
    アプリを転送
    録画用ソフトの起動
    アプリを起動
    ミラーリング映像の録画開始
    テストの実行
    ミラーリング映像の録画停止
    アプリを終了
    録画ファイルのリネーム
    録画用ソフトの終了
    ミラーリングの停止
    結果の解析と通知処理
    準備フェーズ テスト実行フェーズ(繰り返し) 終了フェーズ

    View full-size slide

  152. © SEGA
    録画⽤ソフトの終了
    USB
    録画用ソフトの
    終了
    端末映像のミ
    ラーリング停止
    テスト結果の解
    析と通知処理
    1 2 3
    Android iOS

    View full-size slide

  153. © SEGA
    • pkillすればOK
    ü pkill "obs"
    OBSの終了 Android iOS

    View full-size slide

  154. © SEGA
    ミラーリング停⽌
    USB
    録画用ソフトの
    終了
    端末映像のミ
    ラーリング停止
    テスト結果の解
    析と通知処理
    1 2 3
    Android iOS

    View full-size slide

  155. © SEGA
    • scrcpyはOBS同様pkillすればOK
    ü pkill "scrcpy“
    • sndcpyはアンインストールする
    ü adb uninstall com.rom1v.sndcpy
    scrcpy/sndcpyの終了 Android

    View full-size slide

  156. © SEGA
    • 他のプロセス同様にpkillでOK
    ü pkill "QuickTime Player"
    Quick Time Playerの終了 iOS

    View full-size slide

  157. © SEGA
    運⽤時に発⽣した問題とその解決⽅法の共有

    View full-size slide

  158. © SEGA
    • Android/iOS共にOSの⾃動アップデート通知が
    テスト中に割り込みで⼊る
    ü 操作不能になりテストが失敗する原因に
    • どちらのOSも⾃動アップデートは抑⽌できるの
    で設定を忘れずにしておく
    OSアップデート通知問題

    View full-size slide

  159. © SEGA
    • Automatorで記録したままの設定だとウェイト
    値が不適切で動作が安定しないことがある
    ü Automator運⽤⽅針項で述べたように、複雑な操作
    をAutomatorで実装する場合はAppleScriptで細かい
    調整を⾏おう
    Automator操作が時々失敗する

    View full-size slide

  160. © SEGA
    • 録画映像に妙な余⽩が……
    ノッチ対応アプリ録画映像の余⽩
    ここ

    View full-size slide

  161. © SEGA
    • ノッチ対応している為にできた余⽩だった
    ü 逆説的に余⽩はノッチ対応の証拠なので確認に使える
    ノッチ対応アプリ録画映像の余⽩

    View full-size slide

  162. © SEGA
    ポップアップクローズ失敗 Android

    View full-size slide

  163. © SEGA
    今後の展望

    View full-size slide

  164. © SEGA
    • 複数端末を並列でテストしたい
    ü 録画をどうするかが課題
    ü OBSのキャンバスをうまく活⽤すれば……︖
    • テスト中のパフォーマンスを取得したい
    ü ミラーリングの負荷の影響がどうしても出る
    展望

    View full-size slide

  165. © SEGA
    良い実機テストライフを︕︕

    View full-size slide

  166. © SEGA
    Appendix

    View full-size slide

  167. © SEGA
    Appendix
    Windowsで録画(ロック時の注意)

    View full-size slide

  168. © SEGA
    • 以下の実装ではロック画⾯そのものを録画して
    しまう
    ü Desktop Duplication API
    ü (最新の)WinRTのWindows.Graphics.Capture
    ロック時に録画できないケース

    View full-size slide

  169. © SEGA
    • アプリケーションの描画した結果画像を直接取
    得する⽅法であれば録画可能
    ü 例︓DXGIのPresentにフックを仕掛ける
    ⾃⼒で録画機能を実装する案

    View full-size slide

  170. © SEGA
    • OBSの録画も前者の録画できない⽅式に該当
    • そこで、RDP等でロック解除して⾃動処理を実
    ⾏する必要がある
    • しかしRDP接続に関しても録画は注意しないと
    いけない点がある
    OBSの場合

    View full-size slide

  171. © SEGA
    Appendix
    Windowsで録画(RDP接続時の注意)

    View full-size slide

  172. © SEGA
    • RDPで接続した状態であれば、ロック中でも録画
    が可能
    ü しかし常時RDP接続しておくわけにはいかない
    • テスト実⾏時にRDPが繋がっていなければ⾃動
    的に接続を⾏う処理を挟む
    OBSとRDP接続を組み合わせて録画

    View full-size slide

  173. © SEGA
    • 例えば、DockerでUbuntuを動作させ、その中
    でRemminaというOSSでRDP接続を⾏えるよう
    な環境を構築する
    • テスト開始時に録画を⾏いたいPCのセッション
    の有無を確認し、存在していない場合は前述し
    たUbuntuからRemmina経由でRDPにて接続を
    ⾏う
    テスト実⾏時にRDP接続

    View full-size slide

  174. © SEGA
    • RemminaによるRDP接続処理はUbuntuを
    Jenkinsのagentとして登録することにより実現
    可能
    • Ubuntu環境からRDP接続しているので画⾯ロッ
    クをしなくてもセキュリティが担保できる
    ü 物理画⾯はログイン画⾯が表⽰される
    • PC再起動を考慮してUbuntuの起動やログイン処
    理も⾃動化しておくのがお勧め
    補⾜

    View full-size slide

  175. © SEGA
    set CURRENT_SESSION_ID=-1
    for /f "tokens=3-4" %%a in ('query session %username%') do @if "%%b"=="Active" set CURRENT_SESSION_ID=%%a
    echo %CURRENT_SESSION_ID%
    exit /b %CURRENT_SESSION_ID%
    セッションの確認実装例

    View full-size slide

  176. © SEGA
    • RDP切断時にtsconを⽤いてアクティブなセッ
    ションを切り替える⽅法も有り
    ü tscon <現在のセッションID> /dest:console
    • tsconを忘れると録画が失敗してしまうので運⽤
    には注意が必要
    ⾃動RDP接続対応が⾯倒な場合

    View full-size slide

  177. © SEGA
    Appendix
    iOSのIPアドレス取得(⾮同⼀LAN環境)

    View full-size slide

  178. © SEGA
    • パケットキャプチャ結果からIPアドレスをパー
    スする
    • rvictlを使ってMacOSから端末に仮想インター
    フェースをマウントし、これをtcpdumpするこ
    とでパケットキャプチャ可能
    ü MacとiOS端末が⾮同⼀LAN内でも取得可能︕
    パケットキャプチャ iOS

    View full-size slide

  179. © SEGA
    • 仮想インターフェースを作成するアプリを⽴ち
    上げると rvictl が切断させることがある
    ü 例 : Quick Time Playerでミラーリングを⾏う
    • tcpdumpはsudoが必要
    • 端末側からMacOSへ何らかのパケットを送信す
    る必要がある
    パケットキャプチャ注意事項 iOS

    View full-size slide

  180. © SEGA
    • ⾃作以外のアプリはshellから起動が難しい
    ü xcodebuild経由でないといけない
    ü QuickTimePlayerでミラーリングした画⾯をAutomator
    で操作してアプリ起動する⽅法は前述の切断問題がある為
    にNG
    • ⾃前で以下の対応をするしかない
    ü 専⽤のアプリを作成する
    ü テストを⾏うアプリに仕込みを⼊れる
    端末から通信を⾏う iOS

    View full-size slide

  181. © SEGA
    • UnityはDevelopmentフラグが有効の場合に
    ポート54997でデバッグ情報をマルチキャスト
    で投げる
    ü https://docs.unity3d.com/Manual/TroubleShootingIPhone.html
    • マルチキャストでフィルタするとrvictlが出して
    いるパケットまでキャッチしてしまうので注意
    端末から通信を⾏う – Unityの例 iOS

    View full-size slide

  182. © SEGA
    • 投げられるパケット情報
    端末から通信を⾏う – Unityの例 iOS
    IPが埋まっているので
    パースして活用

    View full-size slide

  183. © SEGA
    rvictlを使って仮想インターフェースを作成(Pipeline)
    def rviStart = "rvictl -s ${params.IPHONE_UUID}".execute()
    rviStart.waitFor()
    def rviLines = rviStart.inputStream.readLines()
    def viName = "“
    rviLines.each {
    def matcher = (it =~ /interface ([0-9a-zA-Z]+)/)
    while (matcher.find()) {
    viName = matcher.group(1)
    }
    }
    Jenkins - Unity例 iOS

    View full-size slide

  184. © SEGA
    ポート54997のパケットからIPを抽出(Pipeline)
    def dump = "sudo tcpdump -i ${viName} -t -c 1 dst port 54997".execute()
    dump.waitFor()
    def lines = dump.inputStream.readLines()
    def ip = "“
    lines.each {
    def matcher = (it =~ /IP ([0-9]+.[0-9]+.[0-9]+.[0-9]+)/)
    while (matcher.find()) {
    ip = matcher.group(1)
    }
    }
    Jenkins - Unity例 iOS
    前ページで作成した仮想インターフェース名

    View full-size slide

  185. © SEGA
    rvictlを終了(Pipeline)
    def rviEnd = "rvictl -x ${params.IPHONE_UUID}".execute()
    rviEnd.waitFor()
    Jenkins - Unity例 iOS
    終了を忘れると仮想インターフェースが残ってしまうので注意

    View full-size slide

  186. © SEGA
    • iOS14からマルチキャストでの通信に強い制限が
    掛かった
    ü Multicast Networking Entitlement申請が必要
    ü 更に端末側でのローカルネットワーク設定の許可も
    • Unityのデバッグパケットも上記対応をしないと
    キャプチャできない
    補⾜ - iOS14からの注意事項 iOS

    View full-size slide

  187. © SEGA
    • マルチキャストを使わずに端末側からMacOS側
    へ送信するような処理を⾃前で実装する必要が
    ある
    • HTTPでMacOCに向け通信を⾏うのが楽
    ü MacOS側にサーバを⽤意しなくても送信パケットを
    キャプチャすればOK
    補⾜ - iOS14からの注意事項 iOS

    View full-size slide

  188. © SEGA
    • VPN接続しているとrvictlでキャプチャできない
    ü VPNで⽣成された仮想インターフェース側にパケット
    が流れてしまう
    • 環境はVPN不要なネットワーク上に構築しよう
    ü scrcpyもQuickTimePlayerもミラーリング映像をマ
    ウスで操作できるので、いざという時でもVPN越しに
    端末の操作を⾏うことが可能
    補⾜ - VPN環境下の問題

    View full-size slide