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

リリース前のリグレッションテストをUIテストで自動化、1年間運用した話

 リリース前のリグレッションテストをUIテストで自動化、1年間運用した話

2019/7/25のAndroidTestNightで発表した資料です

yu mitsuhori

July 25, 2019
Tweet

More Decks by yu mitsuhori

Other Decks in Programming

Transcript

  1. リリース前のリグレッションテストをUIテ
    ストで自動化、1年間運用した話
    養命酒(Yu Mitsuhori)/ @1013Youmeee
    Android Test Night #7 at DeNA

    View Slide

  2. 自己紹介
    2
    - 三堀 裕(みつほり ゆう)
    - 養命酒(youmeee, youmitsu)
    - メインはAndroid
    - 新宿の隣でヘルスケア系アプリを開発していました
    (7/19に最終出社でした。有給消化中)
    - Github: youmitsu
    - Twitter: @1013Youmeee

    View Slide

  3. この発表の目的
    - 某アプリLでのAndroid Instrumented Testを用いたリグレッションテストの自動化の
    取り組みについての事例の紹介
    - 1年間運用してみてよかった点や、注意点、課題点などの紹介
    3

    View Slide

  4. こんな話をしていきます
    - 自動化の経緯
    - 某アプリLでのテスト
    - テストの種類
    - タイミング
    - 構成と構築について
    - テスト方針
    - システム構成図
    - 選定技術とテスト実装について
    - 1年間運用してみた所感
    - 良かった点、現時点での課題点、改善策
    - まとめ
    4

    View Slide

  5. 自動化の経緯
    5

    View Slide

  6. - 2015年にリニューアル
    - MAU約400万
    - 中〜大規模
    - 開発チーム:Android 2人, iOS 3人
    - QAチームなどはいない。開発チームが仕様検討、設計、実装、テスト、リリースを一
    貫して行う
    - ベースはClean Architecture
    6
    某アプリLの概要

    View Slide

  7. 某アプリLの悩みの種
    - 保守運用フェーズ、開発人員も減らされている
    - これからも長く存続しつづけるであろう
    - 開発人員が少ない中での作業効率化(自動化できるものはしていきたい)
    - テスト実施における精神的負担の軽減
    7

    View Slide

  8. 某アプリLでのリグレッションテスト
    8

    View Slide

  9. 某アプリLでのリグレッションテスト
    - リリース前に改修していない部分に影響がないかをテストする(E2Eテスト)
    =>手動での実施だと全ケース約1人日かかる
    参考
    - 単体テスト
    - 各レイヤーごと、View以外
    - 結合テスト
    - 修正された機能においてテストケースを作成し、実機を操作してテストする
    9

    View Slide

  10. 主な開発フローとテスト
    10
    Develop
    Feature1
    Feature2
    Release
    Master
    : 単体テスト
    : 結合テスト
    : リグレッションテスト
    PlayStoreへ
    デプロイ

    View Slide

  11. 自動テスト構築について
    11

    View Slide

  12. 当初の自動化方針
    - 基本的な方針は今までのリグレッションテストと同じ
    - E2Eテスト。できるだけ実働環境に近い状態で実行する
    - Releaseブランチにて実施する
    - 自動化できない部分は手動で実施する
    - 主にWebView
    - TestSuiteはActivityやFragment単位ではなく、ユーザタイプ&課金タイプごとに定義
    する
    - APIやWebサーバはテスト環境を使用
    - テストファーム(Visual Studio AppCenter)で走らせることを想定
    12

    View Slide

  13. テスト実行時の構成
    - Android Instrumented Test(AndroidJUnitRunner)
    - Espresso
    - Assertion, Action
    - UiAutomator
    - バックグラウンド復帰の実装
    - RxIdler2
    - RxJava2のBackground Taskの終了を待つ
    - AppCenter SDK
    - 画面のキャプチャ
    - Page Object Pattern(リファクタリング中)
    - 画面ごとをObjectとして定義する。UIテストにおけるデザインパターン
    13

    View Slide

  14. テストコード実装にあたって
    - アプリをインストールしてからすべての機能を順番にチェックしていく
    - 画面に表示されているコンポーネントのチェック(Espresso)
    - onView()で要素取得(条件はwithIdやwithText)
    - isDisplayed()による表示確認
    - 実際にユーザが操作するのと同じシチュエーションで実行したいため、
    API通信はモックせず実際のネットワーク通信でテストを実行する
    14

    View Slide

  15. アーキテクチャ
    15
    Runner TestCase Page
    テストを実行するクラス。
    エントリポイント
    各Feature単位で定義。
    Pageオブジェクトを使っ
    てユーザシナリオを組み
    立てる
    画面単位で定義。
    assert,perform系のメ
    ソッドを持ち、TestCase
    から呼び出される
    1 n n
    n

    View Slide

  16. 簡単なコードイメージ(Runnerクラス)
    @RunWith(AndroidJUnit4.class)
    @LargeTest
    public class RegressionRunner {
    @Inject NoticeTest noticeTest; // 各機能ごとにテストケースクラスを定義
    @Rule public ReportHelper reportHelper = Factory.getReportHelper(); // AppCenterSDKの画像キャプチャ用インスタンス
    @Rule public ActivityTestRule mainActivityActivityTestRule = new ActivityTestRule(MainActivity.class, false, false);
    @Test
    // ゲストユーザ&&TypeAのシナリオテストを実行
    public void GuestUserTypeA_regression() {
    reportHelper.label("A_freeUser_regression Start"); // AppCenterSDKによる画面キャプチャ
    splashActivityActivityTestRule.launchActivity(new Intent()); // アプリの起動
    noticeTest.assertNotice(); // お知らせ画面のテスト実行
    ...
    }
    // 有料ユーザ&&TypeBなどのシナリオテストを以下に続けて定義
    }
    16
    Runnerクラス

    View Slide

  17. 簡単なコードイメージ(TestCase, Pageクラス)
    class NoticePage : Page {
    private fun isShowedCouponBanner() =
    onView(withId(R.id.coupon_view)).check(matches(isDisplayed()))
    fun clickBanner() = apply {
    onView(withId(R.id.coupon_view)).perform(click())
    label("clickBanner")
    }
    }
    17
    Pageクラス
    class NoticeTest @Inject constructor(
    context: Context
    ) : BaseTest(context) {
    fun assertNotice() {
    NoticePage()
    .assert {
    isShowedCouponBanner()
    }
    .clickBanner()
    .assert {
    // クリック後の画面状態を
    assert
    }
    }
    }
    TestCaseクラス

    View Slide

  18. システム構成について
    18

    View Slide

  19. 自動化におけるシステム構成
    19
    Schedule
    Build & Distribute
    App
    Test app
    Run Test & Report
    Azure Pipeline
    Visual Studio
    App Center
    Outlook
    Flow
    Teams
    Developer
    Notification
    テスト完了通知は
    メールでしか
    受け取れないため
    Check Result
    以下のIPを許可しておく
    ・195.249.159.238/32
    ・195.249.159.239/32

    View Slide

  20. AppCenterの紹介
    - Microsoftが提供するモバイル向けCI/CDプラットフォーム
    - Build, Test, Distributeなど
    テスト
    - DeviceFarm上で実行可能
    - デバイス数が豊富
    - 100ドルずつ課金していくと並列実行数を増やせる
    - 直列のみ: 98ドル, 2並列: 198ドル, n並列: 98nドル
    - 30日間は無料トライアル期間
    - AppCenterSDKを使うと、スクリーンショットの撮影も可能
    (動画は撮れない...はず)
    20

    View Slide

  21. 1年間運用してみた所感
    21

    View Slide

  22. 良かった点
    - 全ケース中の60%ほどテスト工数が削減できた
    - 手動でやる作業が削減されたことで、効率的、精神衛生的にもGood
    - とりあえずこれを回しておけばOKという点では安心感もある
    - テスト実施頻度が高くなった
    - カスタムビューで実装していた部分はEspressoのonViewで取得できないことがあっ
    たので、UIテストにおいてのテスタビリティを意識するきっかけになった
    22

    View Slide

  23. 辛い点、出てきた問題点
    - 不安定(特にAppCenterでの実行時)
    通らないとリリースできないので、逆にリリースまでのスピードが落ちる
    - ネットワーク起因(タイムアウト)
    => API通信のモック化を検討中
    - AppCenterの実機がアニメーションオフにしていない
    - 安定しないので、手動でスケジューリングすることになる、、
    => 安定してきたらCIとして自動スケジューリングさせたい
    - 実行速度が遅い(テスト実行: 15~20分、テスト結果作成: 15~20分)
    - 3つのOSバージョンで直列実行するため、全部終わるのに 1時間くらいかかる
    - WebView辛い
    - 非同期にレンダリングされる要素は取得に失敗しやすい( Espresso Web)
    23

    View Slide

  24. まとめ
    24

    View Slide

  25. まとめ
    - 某アプリLにおいて、リリース前のリグレッションテストを自動化した事例について紹

    - UIテスト安定化させるのは難しい、継続的にテスト自体をメンテしていく必要があり
    そう
    - 通信のタイムアウト
    - デバイス起因
    - 実行時間
    - WebView
    - いくつかの工夫によって安定化を目指していく
    - WebViewに対しては深いテストをしない
    - APIClientをモックする
    25

    View Slide