dely Tech Blog

クラシル・TRILLを運営するdely株式会社の開発ブログです

クラシルリワードにおける自動テストツール MagicPodの導入事例

はじめに

こんにちは!クラシルリワードで開発責任者をしているfunzinです。 この記事ではクラシルリワードに自動テストツールとしてMagicPodを導入したことについて紹介してきます。

導入背景

サービス概要

はじめにクラシルリワードについて紹介します。クラシルリワードは「日常のお買い物体験をお得に変える」アプリです。日常行動をアプリ内で行うことでポイントが貯まり、貯まったポイントを商品券などに交換できるサービスです。 現在、iOSAndroidWebの3つのプラットフォームで展開しています。

リリース頻度

クラシルリワードは1年前にリリースしたこともあり現在も機能開発が盛んに行われています。FeatureFlagを利用したトランクベース開発を行い、アプリは平均週2リリースを行うなど高頻度でリリースが行われています。

QA事情

リリースが高頻度のため開発速度に影響がないように下記のようにQAを行っていました。

  1. 機能追加・修正時に実装者がQA観点をまとめて、関係者に触ってもらい違和感がないかを確認

    SlackでのQA依頼例

  2. 大きい機能開発の場合、デグレをしていないかを確認するために一括テストを実行

    テストケースをスプレッドシートで管理

リリース当初から上記のようなQAを行っていましたが、サービス規模も大きくなっていく中でポイントやチラシを提供している小売の情報を扱ってるため、不具合が発生すると大きな影響が出てしまいます。
またリリース当初と比較すると機能が増えてきて、手動で既存機能のテストすることの難易度が上がってきました。
このような状態の解決をするために、自動テストツールを導入を検討しました。
(※各プラットフォームでUnitTestは書いていますが、今回はUIテストの自動化に着目しているため割愛します)

自動テストツールの要件

まずは自動テストツールを導入することで何を実現したいかを整理しました。

  1. 人が手動で行っていたテストケースを自動化
  2. テストケースのメンテナンスコストを低く保つ
  3. 引き継ぎを想定して、非エンジニアでもテストケースの対応が可能な状態

上記の要件を実現するために、自動テストツールの候補として下記を洗い出しました。

  1. 各プラットフォームでのUITest(iOS: XCTest, Android: Espresso)
  2. Maestroを利用したymlベースでのテスト実行
  3. MagicPodのようなGUI上での自動テストツール

事前に定義した自動テスト要件と自動テストツールの候補を照らし合わして整理していきました。

  • 1のUnitTestに関しては、それぞれのプラットフォームで開発工数がかかる、プラットフォームが別れているためどのようなテストケースを担保するかなどのコミュニケーションなどで工数を使うため見送り
  • 2のMaestroに関しては、yml管理できるのは魅力的なものの、非エンジニアの対応コストが高いため見送り
  • 3のMagicPodに関しては、GUI上でテストケースを作成できるので非エンジニアでも対応可能。共有ステップを利用すればメンテナンスコストも低く保てそう

そのため、要件と最もマッチしそうであるMagicPodを第一候補として検討しました。

トライアル時の検証

MagicPodを検討したとはいえ実際に触ってみないと判断がつかないため、まずは無料トライアルから始めました。 トライアル期間中に検証したことは下記です。

  1. 位置情報計測、ヘルスケアなどのサードパーティ製の仕組みを使った機能を含むためそれらのテストケースの作成が可能か
  2. テスト実行の自動化フローが組めるかどうか


1に関しては、事前にMagicPod側に懸念点の質問、実際にMagicPodでテストケースを書いて動作確認をしました。
2に関しては、本来であればCIを構築して検証するべきですがトライアル期間のため撤退する可能性もあります。そのため手元のPCでcrontabを利用して擬似的にローカルPCをCIと見立てて検証しました。

下記がcrontab, script, Makefileの例となります。

$ crontab -l
0 10 * * 1-5 TZ=Asia/Tokyo make build-and-upload # 平日朝10時に実行する
# Makefile
.PHONY: build-and-upload
build-and-upload:
    sh ./android.sh
    sh ./ios.sh
# android.sh
current_dir=$(pwd)
export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home
export PATH=$PATH:$JAVA_HOME/bin

# Build
cd ../android && git co develop && git pull && ./gradlew assembleDebug

# Renamed
FILENAME=Rewards-Dev-$(date +%Y%m%d%H%M%S).apk
cd app/build/outputs/apk/debug && mv app-debug.apk $FILENAME
export MAGICPOD_ORGANIZATION=org
export MAGICPOD_PROJECT=android

cd "$current_dir"

# Upload
./magicpod-api-client upload-app -a ../android/app/build/outputs/apk/debug/$FILENAME
# ios.sh
current_dir=$(pwd)
# Build
cd ../ios && git co master && git pull && \
xcodebuild \
  -workspace App.xcworkspace \
  -scheme App-Debug \
  -sdk iphonesimulator \
  -destination 'platform=iOS Simulator,name=iPhone 14' \
  -configuration Debug \
  -derivedDataPath DerivedData \
  clean build

# Renamed
FILENAME=Rewards-Dev-$(date +%Y%m%d%H%M%S).app
cd DerivedData/Build/Products/Debug-iphonesimulator && mv App-Dev.app $FILENAME
export MAGICPOD_ORGANIZATION=org
export MAGICPOD_PROJECT=ios

cd "$current_dir"

# Upload
./magicpod-api-client upload-app -a ../ios/DerivedData/Build/Products/Debug-iphonesimulator/$FILENAME

MagicPodの実行はmagicpod-api-clientを利用しました。
crontabで出社時間の毎朝10:00に実行し、MagicPodのテストスケジューラーは10:30に実行するようにしていたため、iOS・Androidの最新ビルドがMagicPodで実行されるようになり自動化フローを検証を進めることができました。

crontab経由でslack通知

上記の検証をトライアル期間中に行い、ある程度利用できることが確認できたため、本格導入に踏み切りました。
(トライアル期間でも多くの質問に答えていただいたMagicPodのCS担当者の皆様には感謝です。)

実際の運用事例

実際にMagicPodを導入してみてどうだったかを次のセクションからお話しします。

実数値

2023/12時点での実数値です。

  • テストケース数
    • iOS: 23テストケース
    • Android: 23テストケース
  • 平均テスト実行時間: 30分~1時間
  • MagicPodの運用者: 1名

それぞれ抜粋して補足説明していきます。

テストケース

基本的にはユーザー体験として優先度が高いものからMagicPodのテストケースとして作成しています。クラシルリワードではオンボーディング突破や、チラシ閲覧からのコイン獲得などがあげられます。 スプレッドシートで管理していたテストケースも考慮しつつ導入初期は一気にテストケースを作成するのではなく、Highのテストケースを一つずつ作成していきました。

テストケースをNotionで一覧化

MagicPodでは開発中のテストケースと一括テスト用のケースが存在するため「Morning Build」, 「Development」という2つのタグを使って管理しています。「Development」タグでは一括テスト対象から除外することで、一括テストに影響がないようにしています。

MagicPodのテストケース一覧

運用体制

MagicPodの運用体制としてQAチームを作る or アプリエンジニアに運用を任せるかで悩みましたが、現状は自分1人で運用しています。 理由としては下記です。

  • 両OSの仕様を把握してる人間がどちらもメンテナンスすることで、OS間の差分を検知しやすい
  • QA専任がいない中での複数人運用は、コミュニケーションコストが大きい
    • 最終的にテストケースがメンテナンスされなくなって形骸化する可能性が大きい
  • 一度テストケースを作って慣れたらそこまで時間はかからない

まずは1人での運用を安定的に行い、将来的には引き継ぐことを想定して複数人で運用できる体制にできればと考えています。

実際のテスト運用フロー

次に実際のテスト運用フローについて説明します。 以下の図のように2つのタイミングで実行しています。

  1. 朝7:00の定期実行
  2. リリースタグ付与時に実行

MagicPodでは主に機能開発によるデグレの検知を行っています。
リリース前のブロック用途としても利用可能ですが、テストがまだ不安定にこけることがあり開発者が都度確認するのが現状の開発速度を阻害してしまうためこのような運用にしています。 何回か再実行しても同様の失敗をする場合は開発者に確認するフローをとっています。

開発者への確認例

MagicPodを運用してみてどうだったか

実際に運用してみて、良かったところと運用してみないとわからなかったところがあるので紹介していきます。

良かったところ

  1. 手動で一括テストをしていた箇所がほぼMagicPodに置き換えができたこと
    もちろん全てのテストを置き換えることは難しいですが、手動でやっていたテストケースの大半を置き換えることができました。 実際にMagicPodを導入して、肌感は下記のような感覚値になりました。

  2. 開発者の心理安全性が高まったという声が増えた
    毎朝定期実行やリリース前の実行によってデグレ検知ができる認知が開発チームに芽生え、既存機能のデグレを恐れずに安心して開発を行うことができるようになりました。

  3. 自動修復機能が便利
    MagicPodの自動修復機能を利用すると、文言系などの細かい修正はMagicPodが自動で直してくれるのは、メンテナンス観点でもとても助かっています。

自動修正例

運用してみないとわからなかったところ

  1. 一度通ったテストが思ったよりもよくこける
    個人的には一度テストが通っても、その精度は70%程度と考えています(感覚値)。
    複数回実行しないと不安定な箇所は特定ができないため、それを逐一修正していく必要があります。 毎回修正していくことで精度を100%に近づけていくイメージです。
    2023/12時点だとテストケースも精度が上がってきてだいぶ落ち着いてきましたが、導入当初は毎朝テストケースを直すところから始めていました。

  2. 機能開発が活発な画面だとメンテナンスコストが大きすぎる。
    冒頭でも述べたように、リリース数が多いため下手にテストケースを追加すると毎日メンテナンスすることになります。
    その場合、開発者とテストケース作成者のコミュニケーションコストが発生するためにお互いに幸せになりません。 このようなケースでは一定の開発期間は落ち着くまで、テストケースを書かない方が良いと判断しました。

まとめ

この記事では自動テストツールとしてMagicPodを導入した経緯と実際の運用事例についてまとめました。
初めはリリースサイクルが早いプロダクトにおいて導入できるか懸念がありましたが、現状はワークしており導入して良かったと感じています。
MagicPodの導入検討している方はトライアルでお試ししてみて、自社サービスや組織にマッチするかを検討してみるのがおすすめです。