summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBogDan Vatra <bogdan@kde.org>2020-04-08 14:07:21 +0300
committerAssam Boudjelthia <assam.boudjelthia@qt.io>2020-08-24 14:50:56 +0300
commit45b56d86bb6bdbc96a04b21587b8c9bc24087113 (patch)
tree14a784df21b1b00d797799dab27e234958882e49
parent556a7e7318fce42e154439dd7157f44551a7f1ae (diff)
Fix running qml tests on Android
First and foremost the condition was wrong ... In order to help running qml test cases on Android without any android specific hack on user's .pro files we copy the entire project folder to assets. I copy the entire folder and not only the tst_*.qml files because it might contain data which is needed by the tests to run. Change-Id: I06323d9d52904317410dd2f440de65a0766a48b5 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
-rw-r--r--mkspecs/features/qmltestcase.prf8
-rw-r--r--mkspecs/features/testcase.prf58
-rw-r--r--src/tools/androidtestrunner/main.cpp62
3 files changed, 70 insertions, 58 deletions
diff --git a/mkspecs/features/qmltestcase.prf b/mkspecs/features/qmltestcase.prf
index ae4ebef513..95e20a8a4f 100644
--- a/mkspecs/features/qmltestcase.prf
+++ b/mkspecs/features/qmltestcase.prf
@@ -5,8 +5,12 @@
contains(TEMPLATE, vc.*): DEFINES += QUICK_TEST_SOURCE_DIR=\"$$_PRO_FILE_PWD_\"
else: DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\"$$_PRO_FILE_PWD_\")
} else {
- !isEmpty(RESOURCES): warning("The RESOURCES qmake variable is empty, the test will probably fail to run")
- DEFINES += QUICK_TEST_SOURCE_DIR=\":/\"
+ isEmpty(RESOURCES) {
+ ANDROID_EXTRA_PLUGINS *= $$_PRO_FILE_PWD_
+ DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\"assets:/$$basename(_PRO_FILE_PWD_)\")
+ } else {
+ DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\":/\")
+ }
}
} else {
diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf
index 4cce55fe04..53704c8787 100644
--- a/mkspecs/features/testcase.prf
+++ b/mkspecs/features/testcase.prf
@@ -63,33 +63,41 @@ debug_and_release:debug_and_release_target {
# Allow for a custom test runner script
android: isEmpty($(TESTRUNNER)) {
- APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
- qtPrepareTool(ANDROIDTESTRUNNER, androidtestrunner)
- qtPrepareTool(ANDROIDDEPLOYQT, androiddeployqt)
- isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET-deployment-settings.json
- contains(QMAKE_HOST.os, Windows): extension = .exe
- $${type}.commands = $$ANDROIDTESTRUNNER --androiddeployqt \"$$ANDROIDDEPLOYQT --input $$ANDROID_DEPLOYMENT_SETTINGS_FILE\"
- $${type}.commands += --path \"$$OUT_PWD/android-build\"
- $${type}.commands += --adb \"$$shell_path($${ANDROID_SDK_ROOT}$${QMAKE_DIR_SEP}platform-tools$${QMAKE_DIR_SEP}adb$${extension})\"
- $${type}.commands += --make \"$(MAKE) -f $(MAKEFILE)\"
- $${type}.commands += --apk $$APK_PATH
-} else: $${type}.commands += $(TESTRUNNER)
-
-unix {
- isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = .
-
- app_bundle: \
- $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
- else: !android: \
- $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
+ build_pass {
+ APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
+ qtPrepareTool(ANDROIDTESTRUNNER, androidtestrunner)
+ qtPrepareTool(ANDROIDDEPLOYQT, androiddeployqt)
+ isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET-deployment-settings.json
+ contains(QMAKE_HOST.os, Windows): extension = .exe
+ $${type}.commands = $$ANDROIDTESTRUNNER --path \"$$OUT_PWD/android-build\"
+ $${type}.commands += --adb \"$$shell_path($${ANDROID_SDK_ROOT}$${QMAKE_DIR_SEP}platform-tools$${QMAKE_DIR_SEP}adb$${extension})\"
+ $${type}.commands += --make \"$(MAKE) apk\"
+ $${type}.commands += --apk $$APK_PATH
+ # Allow for custom arguments to tests
+ !catch: $${type}.commands += $(TESTARGS)
+ $${type}.commands += "--"
+ for(import, IMPORTPATH): $${type}.commands *= -import \"assets:/$$basename(_PRO_FILE_PWD_)/$$import\"
+ } else {
+ $${type}.commands = "echo \"Pass\""
+ }
} else {
- # Windows
- !isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $$shell_path($$TEST_TARGET_DIR)$${QMAKE_DIR_SEP}
- $${type}.commands += $${TEST_TARGET_DIR}$(TARGET)
-}
+ $${type}.commands += $(TESTRUNNER)
+
+ unix {
+ isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = .
-# Allow for custom arguments to tests
-!catch: $${type}.commands += $(TESTARGS)
+ app_bundle: \
+ $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
+ else: !android: \
+ $${type}.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
+ } else {
+ # Windows
+ !isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $$shell_path($$TEST_TARGET_DIR)$${QMAKE_DIR_SEP}
+ $${type}.commands += $${TEST_TARGET_DIR}$(TARGET)
+ }
+ # Allow for custom arguments to tests
+ !catch: $${type}.commands += $(TESTARGS)
+}
!isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD, ^\\./?): \
$${type}.commands = $$QMAKE_CD $$shell_path($$TESTRUN_CWD) && $$eval($${type}.commands)
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp
index f826ce8eeb..955c8c920c 100644
--- a/src/tools/androidtestrunner/main.cpp
+++ b/src/tools/androidtestrunner/main.cpp
@@ -53,7 +53,6 @@ struct Options
bool verbose = false;
bool skipAddInstallRoot = false;
std::chrono::seconds timeout{300}; // 5minutes
- QString androidDeployQtCommand;
QString buildPath;
QString adbCommand{QStringLiteral("adb")};
QString makeCommand;
@@ -110,11 +109,11 @@ static Options g_options;
static bool execCommand(const QString &command, QByteArray *output = nullptr, bool verbose = false)
{
if (verbose)
- fprintf(stdout, "Execute %s\n", command.toUtf8().constData());
+ fprintf(stdout, "Execute %s.\n", command.toUtf8().constData());
FILE *process = popen(command.toUtf8().constData(), QT_POPEN_READ);
if (!process) {
- fprintf(stderr, "Cannot execute command %s", qPrintable(command));
+ fprintf(stderr, "Cannot execute command %s.\n", qPrintable(command));
return false;
}
char buffer[512];
@@ -204,12 +203,7 @@ static bool parseOptions()
int i = 1;
for (; i < arguments.size(); ++i) {
const QString &argument = arguments.at(i);
- if (argument.compare(QStringLiteral("--androiddeployqt"), Qt::CaseInsensitive) == 0) {
- if (i + 1 == arguments.size())
- g_options.helpRequested = true;
- else
- g_options.androidDeployQtCommand = arguments.at(++i).trimmed();
- } else if (argument.compare(QStringLiteral("--adb"), Qt::CaseInsensitive) == 0) {
+ if (argument.compare(QStringLiteral("--adb"), Qt::CaseInsensitive) == 0) {
if (i + 1 == arguments.size())
g_options.helpRequested = true;
else
@@ -255,7 +249,7 @@ static bool parseOptions()
for (;i < arguments.size(); ++i)
g_options.testArgsList << arguments.at(i);
- if (g_options.helpRequested || g_options.androidDeployQtCommand.isEmpty() || g_options.buildPath.isEmpty())
+ if (g_options.helpRequested || g_options.buildPath.isEmpty() || g_options.apkPath.isEmpty())
return false;
QString serial = qEnvironmentVariable("ANDROID_DEVICE_SERIAL");
@@ -272,20 +266,18 @@ static void printHelp()
" runs it on the default emulator/device or on the one specified by\n"
" \"ANDROID_DEVICE_SERIAL\" environment variable.\n\n"
" Mandatory arguments:\n"
- " --androiddeployqt <androiddeployqt cmd>: The androiddeployqt:\n"
- " path including its additional arguments.\n"
- " --path <path>: The path where androiddeployqt will build the .apk.\n"
+ " --path <path>: The path where androiddeployqt builds the android package.\n"
+ " --apk <apk path>: The test apk path. The apk has to exist already, if it"
+ " does not exist the make command must be provided for building the apk.\n\n"
" Optional arguments:\n"
+ " --make <make cmd>: make command, needed to install the qt library.\n"
+ " For Qt 5.14+ this can be \"make apk\".\n"
" --adb <adb cmd>: The Android ADB command. If missing the one from\n"
" $PATH will be used.\n"
" --activity <acitvity>: The Activity to run. If missing the first\n"
" activity from AndroidManifest.qml file will be used.\n"
" --timeout <seconds>: Timeout to run the test.\n"
" Default is 5 minutes.\n"
- " --make <make cmd>: make command, needed to install the qt library.\n"
- " If make is missing make sure the --path is set.\n"
- " --apk <apk path>: If the apk is specified and if exists, we'll skip\n"
- " the package building.\n"
" --skip-install-root: Do not append INSTALL_ROOT=... to the make command.\n"
" -- arguments that will be passed to the test application.\n"
" --verbose: Prints out information during processing.\n"
@@ -342,6 +334,8 @@ static bool parseTestArgs()
QString unhandledArgs;
for (int i = 0; i < g_options.testArgsList.size(); ++i) {
const QString &arg = g_options.testArgsList[i].trimmed();
+ if (arg == QStringLiteral("--"))
+ continue;
if (arg == QStringLiteral("-o")) {
if (i >= g_options.testArgsList.size() - 1)
return false; // missing file argument
@@ -452,14 +446,15 @@ int main(int argc, char *argv[])
return 1;
}
- RunnerLocker lock; // do not install or run packages while another test is running
- if (!g_options.apkPath.isEmpty() && QFile::exists(g_options.apkPath)) {
- if (!execCommand(QStringLiteral("%1 install -r %2")
- .arg(g_options.adbCommand, g_options.apkPath), nullptr, g_options.verbose)) {
+ if (!QFile::exists(g_options.apkPath)) {
+ if (g_options.makeCommand.isEmpty()) {
+ fprintf(stderr,
+ "No apk found at \"%s\". Provide a make command with the \"--make\" parameter "
+ "to generate it first.\n",
+ qPrintable(g_options.apkPath));
return 1;
}
- } else {
- if (!g_options.makeCommand.isEmpty()) {
+ if (!execCommand(g_options.makeCommand, nullptr, g_options.verbose)) {
if (!g_options.skipAddInstallRoot) {
// we need to run make INSTALL_ROOT=path install to install the application file(s) first
if (!execCommand(QStringLiteral("%1 INSTALL_ROOT=%2 install")
@@ -473,15 +468,20 @@ int main(int argc, char *argv[])
}
}
}
+ }
- // Run androiddeployqt
- static auto verbose = g_options.verbose ? QStringLiteral("--verbose") : QString();
- if (!execCommand(QStringLiteral("%1 %3 --reinstall --output %2 --apk %4").arg(g_options.androidDeployQtCommand,
- g_options.buildPath,
- verbose,
- g_options.apkPath), nullptr, true)) {
- return 1;
- }
+ if (!QFile::exists(g_options.apkPath)) {
+ fprintf(stderr,
+ "No apk \"%s\" found after running the make command. Check the provided path and "
+ "the make command.\n",
+ qPrintable(g_options.apkPath));
+ return 1;
+ }
+
+ RunnerLocker lock; // do not install or run packages while another test is running
+ if (!execCommand(QStringLiteral("%1 install -r %2")
+ .arg(g_options.adbCommand, g_options.apkPath), nullptr, g_options.verbose)) {
+ return 1;
}
QString manifest = g_options.buildPath + QStringLiteral("/AndroidManifest.xml");