SquishでAndroid向けQt Quickテスト
7月 09, 2025 by Qt Group 日本オフィス | Comments
以前のブログ記事(リンク: [1], [2], [3] )では、QML コンポーネントをネイティブ Android アプリに組み込む方法について説明しました。この概念を、Qt Quick for Android と呼んでいます。これにより、Android Studio や Android ビルドシステムの使い慣れた環境から離れることなく、Qt を使用して Android アプリケーションに QML の機能を追加したり、UI 全体を QML で記述したりすることが簡単にできます。このブログ記事では、この技術で作成したアプリをテストするために、Qt Quality Assuranceツールを活用する方法について説明します。
GUI のテストに選んだツールは、優れたクロスプラットフォーム対応を提供する Squish です。しかし、「ちょっと待ってください。Squish を使ったことがありますが、Android と Qt では異なるエディションを選択しなければならないはずです。1 つのエディションだけでどのように機能するのですか?」という疑問が湧くかもしれません。実は、Squish は、この古いブログ記事で強調されているように、Qt と Android のコンテンツを一緒にテストすることをサポートしており、いくつかのビルドの違いがあるだけで、ここで同じ概念を使用することができます。
要約すると、前述ブログ記事では、Squish がネイティブ Android 要素を含む Qt アプリケーションのテストを、別々の Application Context を使用してサポートすることが説明されています。まず、Qt コンポーネントに Squish フックを追加し、最終的な APK からテストパッケージを作成して、Android 部分にインストルメンテーションを追加する必要があります。これらが完了すると、Squish for Androidでアプリケーションに接続し、コンテキストを切り替えることで、Qt Quick for AndroidアプリケーションのQt QuickコンポーネントとネイティブAndroidコンポーネントの両方を簡単にテストできます。素晴らしいですね!次に、テスト可能なアプリケーションの作成方法とテストケースの実行方法を見ていきましょう。Qtに付属のサンプルを起点として利用できます。
アプリのインストルメンテーション
アプリと通信するには、Squish はアプリケーションをテスト可能にするためにインストルメンテーションを行う必要があります。このケースでは、テスト対象アプリケーション (AUT) が異なるアーキテクチャ (Qt とネイティブ Android) の 2 つのコンポーネントで構成されているため、両方をインストルメンテーションする必要があります。Qt Quick コンポーネントは、APK ではなく Android Archive (AAR) ファイルとしてビルドするため、少し手間がかかります。
Qt Quick コンポーネントへのフック処理
Qt 部分については、Android テスト用の Squish のインストールに関する 公式ドキュメントに従ってください。Squish の Qt 組み込みフックを使用します。まず、Qt Quick プロジェクトの CMakeLists.txt に以下の内容を追加して、フックをビルドに追加します。
Set(SquishQtbuiltinHook_DIR /Users/<ユーザー名>/squish-9.0.1-qt69x-android-arm64-v8a)
# Look for Squish, optional and allowed to fail
find_package(SquishQtBuiltinHook)
# Add Squish to application target if found
if(SquishQtBuiltinHook_FOUND)
squish_qt_add_builtin_hook(qtquickview ATTACH_PORT 4567)
endif()
ポート番号は、システムポート以外から自由に選択できます。次に、IDE(Squish for Android)またはコマンドラインから、Qt Quick アプリを Squish に AUT として登録する必要があります。Squish のツールを使用すると、コマンドラインからの操作も簡単です。
$ squishserver --config addAttachableAUT qtquickview localhost:4567
また、ADB を使用してデバイスまたはエミュレータに接続しているため、ローカルポートをターゲットデバイスに転送する必要があります。
$ adb forward tcp:4567 tcp:4567
通常の Android 用 Qt アプリケーションを構築している場合、この時点で完了しています。しかし、Qt コンポーネントが APK ではなく、Qt Gradle プラグインを使用して AAR に組み込まれているため、Squish フックの自動化の一部が機能していません(本記事投稿現時)。そのため、最終的な APK にいくつかのライブラリを手動で追加する必要があります。
今回は arm64-v8a デバイスでテストしているため、Android プロジェクトの下にディレクトリを作成し、そこに Squish ライブラリをコピーします。
mkdir –p app/libs/arm64-v8a
cp ~/squish-9.0.1-qt69x-android-arm64-v8a/libs/*.so app/libs/arm64-v8a
cp ~/squish-9.0.1-qt69x-android-arm64-v8a/libs/extensions/qt/*.so app/libs/arm64-v8a
そして、これらのファイルを APK にバンドルするには、app/build.gradle.kts の「android」セクションを変更する必要があります。
android {
sourceSets.getByName("main").jniLibs.srcDir("libs")
...
昔ながらの方法で Groovy DSL をまだ使用している場合は、次のようにします。
android {
SourceSets.main.jniLibs.srcDir 'libs'
...
もちろん、これらはすべて自動化することができます(そしておそらくそうすべきでしょう)。サンプルアプリを構築すると、アプリの Qt Quick 側が接続可能になり、テスト可能になります。やった!
ネイティブ Android コンポーネントのインストルメンテーション
Android 部分については、Squish は、アプリケーションをインストルメンテーションし、1 つのコマンドでターゲットデバイス/エミュレータにインストールする便利な apk-tool ツールを提供しています。以下のようなコマンドを実行します。
$ /Applications/Squish_for_Android_9.0.0/bin/apk-tool -j $JAVA_HOME -pkg
my_first_testable_app.apk -d emulator-5554 -o instrumented_app.apk
これにより、素晴らしい Qt Quick for Android アプリケーションが、インストルメンテーションされ、「emulator-5554」デバイスにインストールされます。
テストの実行
次に、両方のコンテキストでアプリ内のフックを起動して接続します。ここでは、汎用性が高く読みやすい Python を使用しますが、Squish のテストケースは 複数の言語でスクリプト化できます。
利便性を考慮し、アプリケーションコンテキストをSquishのテストモジュール内のinit()関数内で保存します。Android用のSquishのstartApplication()は、パッケージ名(この例ではcom.example.qtquickview_java)でアプリケーションを起動し、それにフックします。その後、attachToApplication()を使用して、登録されたAUT「qtquickview」に接続できます。
import test
application_name = "qtquickview"
package_name = “com.example.qtquickview_java”
def init():
test.log(“Start application in Android context”)
test.ctx_android = squish.startApplication(package_name)
test.log(“Connect to application in Qt context”)
test.ctx_qt = squish.attachToApplication(application_name)
実際のテストケースでは、コンテキストをすばやく切り替えて、コンポーネント間の相互作用や、必要なテストを実行できます。やった!以下の例では、Qt Quick for Androidを使用するアプリ(当社の例の一つ)に、Qt QuickコンポーネントとネイティブAndroidコンポーネントがあり、これらのコンポーネントが互いに影響し合っています。より具体的に説明すると、コードスニペットを理解するために、ネイティブAndroidの「Change Color」(色を変更) ボタンがQt Quickコンポーネントの背景色を変更します。これをテストするには、次のようなコードを書くことができます:
def main():
test.log("Read Qt Quick component background color")
qt_background_color = squish.waitForObjectExists(names.qt_MainRectangle).color
test.log("Switch to Android context")
squish.setApplicationContext(test.ctx_android)
android_button = squish.waitForObjectExists(names.android_ChangeColor_Button)
test.log("Tap on native Android Change Color button")
squish.tapObject(android_button)
test.log("Switch to Qt Quick context")
squish.setApplicationContext(test.ctx_qt)
test.log("Verify the Qt Quick component background color has changed")
new_background_color = squish.waitForObjectExists(names.qt_MainRectangle).color
test.verify(new_background_color != qt_background_color)
Squish でテストコードを実行すると、すべてが正常に動作していることが確認できます。
それだけです。
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.9 Now!
Download the latest release here: www.qt.io/download.
Qt 6.9 is now available, with new features and improvements for application developers and device creators.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.