Appiumを利用したDark Mode自動化テスト

初めに
KINTOテクノロジーズのグローバル開発グループに所属しているパンヌウェイ(PannNuWai)です。グロバール開発グループでテスト自動化チームの担当としてプロダクト開発チーム用のテスト自動化環境の構築と整備をしていたり、プロダクトのテストチームでテストスクリプトを書いています。
私は、KINTOテクノロジーズに入社するまでもテスティングは担当していましたが、入社してから初めてAppiumの自動化テストを経験し、この間、様々なものを学びました。
Appiumは経験が無く、ゼロから勉強するところからのスタートでした。最初の環境設定から手探りで行いサーバーのアーキテクチャデザインまで行うことができようになりました。
この自動化テストでは、スマホアプリをメインにテストしましたが、その中で解決した課題を共有いたします。
本記事では自動化テストのためAppium version 1.22.3を使ってDarkMode(ダークモード)に切り替える方法を話したいと思います。
自動化テストとは
ソフトウェアテストは不具合のある製品をリリースしてしまわないよう、ソフトウェアの問題を発見するために行う作業のことです。
本記事で「自動化テスト」とは支援ツールを用いてソフトウェアテストのプロセスを自動化することを言います。
自動化テストのメリット [1]
- 不具合の早期発見
- コストを抑えながら品質を高められる
- 人的リソースが不足していてもテストできる
- テストを高速で実施できる
- ヒューマンエラーを排除できる
- 営業時間外でもテストできる
Appium とは
iOSアプリ、Androidアプリ、およびデスクトッププラットフォームではネイティブ、ウェブビュー、ハイブリッドアプリをテストするためのオープンソースツールです。[2]
AppiumはJava,PHP,Pythonのプログラミング言語をサポートしているのでテスト者が好きな言語を選びながら簡単に使える自動化テストツールです。
Appiumのアーキテクチャでは
- Appium Client
- Appium Server
- End Device
という三つのコンポーネントが有ります。
Appium Clientの中にはモバイルデバイスとアプリの詳細を設定されています。
Appium ServerにはNode.js言語を利用してjsonファイルを起動しながらシミュレーター(iOS)またはエミュレータ(Android)の接続を行います。
最後には起動されたAppium ServerによってEnd Deviceが発行されます。
Appium Inspector とは
Appium InspectorはモバイルアプリのUI要系を一意に識別するための標準的な手順です。実際のデバイスまたはシミュレーター(iOS)またはエミュレータ(Android)の両方で動作します。
注意点- Appium Inspectorツールはネイティブモバイルアプリケーションの属性のみを取得するように特別に設計されているため、Web ブラウザ(Chrome)でロケーターを見つけることをサポートしていません。
Appiumデスクトップアプリケーションは、Appiumサーバー自体とElementインスペクタの組み合わせで、テストスクリプトの開発中にモバイルアプリケーションのすべての目に見える要素を検出できるように設計されています。[3]
Dark Mode(ダークモード)とは
ダークモードはスマートフォンやノートパソコンなどのユーザーインターフェースの表示設定です。
明るい画面に対して暗いテキスト(ダークモード)が表示されている代わりに、黒い画面に対して明るい色のテキスト(ライトモード)が表示されることです。
現在ではスマートフォンのAndroidとiOS両方の既存ダークモード機能だけではなく、アプリの中にもダークモード機能をよく使います。モバイルアプリの自動化テストを行う場合はダークモード機能のテストも重要なチェック項目になりました。ですので、今回はAppiumを利用してモバイルアプリのダークモードについて話したいと思います。
問題点
Appiumを利用してダークモードのテストを行う場合、問題点があります。例えば、ログイン画面にusernameとpasswordの文字が表示されているかをテストする際、Appium inspectorからusernameとpasswordのelement存在する場所を取得します。通常は以下の通りでelementが表示されているのをチェックするのみです。
AssertTrue(driver.findElementByXPath("USER_NAME").isDisplayed());
AssertTrue(driver.findElementByXPath("PASSWORD").isDisplayed());
ですが、ダークモードの場合、elementの存在する場所を取得して表示をチェックするだけは不十分です。画面が黒い色に変更されているかをチェックするのはダークモードの大事な点です。黒い色と白い色のhexadecimal値をチェックする必要があります。
テスト方法
では、実際にAppiumでダークモードテストケースのソースコードを書いてみましょう。
changeToDarkTheme
ステップ 1
Appium inspectorからelementの存在する場所(ElementId)を取得します。
ステップ 2
デフォルト設定がライトモードになっているかどうかを
assertElementColorMode(MobileElement elementId, ColorMode colorMode)
で確認します。
ステップ 3
ダークモードのボタンを押下します。
ステップ 4
Display設定が ダークモードに変わるかどうかを
assertElementColorMode(MobileElement elementId, ColorMode colorMode)
で確認します。
public class DisplayChangePage extends Base {
public static final String THEME_CELL_ID = "id/theme_parent";
@Test(groups = "DisplayChangePage", dependsOnGroups = "Setting")
public void changeToDarkTheme() {
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
MobileElement themeCell = getDriver().findElementById(THEME_CELL_ID);
assertElementColorMode(themeCell, ColorMode.LIGHT);
themeCell.click();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
tapElement(
findElementByTextContains(ViewType.CHECKED_TEXT, resourceText("darkTheme"))
);
themeCell = getDriver().findElementById(THEME_CELL_ID);
assertElementColorMode(themeCell, ColorMode.DARK);
}
}
assertElementColorMode
Theme cellが存在しているElementIdと変更したいColorModeをパラメータとして設定しています。
ステップ 1
Theme cellが存在しているElementのエビデンスを取得します。getElementBufferedImage(MobileElement element)を使ってエビデンスを画像ファイルとして保存します。
ステップ 2
保存されている画像ファイルがnullにならないようにチェックします。
ステップ 3
画像ファイル(x = 10, y = 10)のポイントからカラーを取得して変更したいダークモードのカラーをチェックします。
public interface AppiumHelpersInterface extends FindElementsInterface {
AppiumDriver<MobileElement> getDriver();
Device getDevice();
/**
* Get buffered image of mobile element
*
* @param element Mobile element
* @return Buffered image
*/
default BufferedImage getElementBufferedImage(MobileElement element) {
File image = element.getScreenshotAs(OutputType.FILE);
try {
return ImageIO.read(image);
} catch (IOException e) {
return null;
}
}
/**
* Assert element's color mode
*
* @param element Mobile Element
* @param mode Color mode
*/
default void assertElementColorMode(MobileElement element, ColorMode mode) {
BufferedImage image = getElementBufferedImage(element);
Assert.assertNotNull(image);
Assert.assertTrue(Utils.getColorString(image, 10, 10).matches(mode.cellRegex()));
}
}
getColorString
取得した画像のx-point, y-pointのカラーをhexadecimalに変更して配列を返却します。
/**
* Get color string from image at point x and y
*
* @param image BufferedImage
* @param x int
* @param y int
* @return Hexadecimal Color String
*/
public static String getColorString(BufferedImage image, int x, int y) {
int rgba = image.getRGB(x, y);
int[] rgb = new int[]{
(rgba >> 16) & 0xff,
(rgba >> 8) & 0xff,
(rgba) & 0xff
};
return String.format("%02x%02x%02x", rgb[0], rgb[1], rgb[2]);
}
cellRegex
ダークモードとライトモードの値を判断します。
public enum ColorMode {
LIGHT,
DARK;
public String cellRegex() {
// 22222 - lighter black
if (this == DARK) return "2[(0-9|a-f)]2[(0-9|a-f)]2[(0-9|a-f)]";
// ffffff
return "f[(0-9|a-f)]f[(0-9|a-f)]f[(0-9|a-f)]";
}
}
public interface ColorModeInterface {
String darkModeScript();
Map<String, Object> darkModeSettings();
Map<String, Object> lightModeSettings();
default void configureDarkMode(ColorMode mode) {
getDriver().executeScript(darkModeScript(), mode == ColorMode.DARK ? darkModeSettings() : lightModeSettings());
}
}
注意点
この方法はAppiumを利用したケースなのでNative Appのダークモード機能だけ使えます。
まとめ
本記事では、ダークモードの切り替える方法について説明しました。
ダークモードの自動化テストのためiOS(version13以上)とAndroid(version 5.0以上)両方で使えます。
今回はNative Appのダークモードテスト機能を行いましたが、今後はWeb Appのダークモードテストも試してみたいと思います。
グローバル開発内のテスト自動化チームは12月から増員しました。今後は、チームメンバーと一緒に、Appiumだけでなく、Katalonなど他のツールも用いた自動化テストに取り組んでいきたいです。
参考
関連記事 | Related Posts

Appiumを利用したDark Mode自動化テスト

Appium: Creating Automation Source Code Based on Test Specifications

Struggle Story of QAG Members Who Joined in 2025

テスト仕様書に基づいてAppium 自動化ソースコードを作成する方法
Key Aspects of QA Testing for Native Apps
Implementing Screenshot Testing in the Unlimited Android App Was Tougher Than Expected
We are hiring!
【QAエンジニア(リーダークラス)】QAG/東京・大阪・福岡
QAグループについて QAグループでは、自社サービスである『KINTO』サービスサイトをはじめ、提供する各種サービスにおいて、リリース前の品質保証、およびサービス品質の向上に向けたQA業務を行なっております。QAグループはまだ成⾧途中の組織ですが、テスト管理ツールの導入や自動化の一部導入など、QAプロセスの最適化に向けて、積極的な取り組みを行っています。
【63】シニア/フロントエンドエンジニア(React/Typescript)/KINTO中古車開発G/東京・大阪・福岡
KINTO開発部KINTO中古車開発グループについて◉KINTO開発部 :66名 KINTO中古車開発G:9名★ KINTOプロダクトマネジメントG:3名 KINTOバックエンド開発G:16名 契約管理開発G :9名 KINTO開発推進G:8名 KINTOフロントエンド開発G...

