Wie kann ich verhindern, dass Gradle Instrumented Test Runs die App deinstallieren?

8

Wenn ich:

  • Erstellen Sie ein brandneues Android Studio 3.5.1-Projekt (Kotlin, API 21, Vorlage "Leere Aktivität").
  • Führen Sie die App in der IDE aus
  • Vergewissern Sie sich, dass die App installiert ist und über ein Startsymbol verfügt
  • Führen Sie die connectedAndroidDebugTestGradle-Aufgabe aus (in Android Studio oder über gradlew)

Die App wird beim Testlauf deinstalliert. Ich erhalte dieses Verhalten auch dann, wenn ich einen testApplicationIdWert hinzufüge defaultConfig, damit der Testcode eine andere Anwendungs-ID verwendet.

Wie stoppe ich dieses Verhalten? Wie kann ich instrumentierte Tests über die Befehlszeile ausführen, ohne eine vorhandene App-Installation zu stören?

CommonsWare
quelle
2
Ähnlich wie bei stackoverflow.com/questions/47670066/… (sie haben keine Lösung bekommen, nur einige Problemumgehungen)
Tyler V
@ TylerV: Die Sache ist, ich schwöre, das hat es vor einem Jahr nicht getan. Ich verwende eine Gradle-Aufgabe für einen einheitlichen Abdeckungsbericht (Zusammenführen der Ausgabe von instrumentierten Tests und Komponententests). Ich habe das vor einem Jahr für ein Projekt verwendet, und ich kann mich nicht erinnern, auf dieses Problem gestoßen zu sein. Ich habe den Bericht gerade erneut für ein neues Projekt implementiert und sehe jetzt das Deinstallationsproblem. Es ist möglich, dass meine Erinnerung an das, was vor einem Jahr passiert ist, verschwommen ist, aber die Deinstallation einer App, für die eine Authentifizierung erforderlich ist, ist ärgerlich. Daher würde ich gerne glauben, dass ich mich daran erinnern würde.
CommonsWare
Wenn ich mit der rechten Maustaste auf eine einzelne Testdatei klicke und sie auf diese Weise ausführe, wird die App auch nicht deinstalliert, wenn sie fertig ist (ich mache dies manchmal, um einige vorab ausgefüllte Daten in die App zu laden). Es ist wahrscheinlich ein zusätzlicher Schritt in der verbundenen Testaufgabe ...
Tyler V

Antworten:

2

Die connectedCheckAufgabe hat den Typ DeviceProviderInstrumentTestTask. Für einen einfachen Testlauf auf einem Gerät wird a verwendet SimpleTestRunner, das wiederum a verwendet SimpleTestRunnable, um den Test tatsächlich auszuführen. Hier finden Sie eine Struktur von

try {
    // connect to device
    // install all APKs
    // run tests
} catch(Exception e) {
    // handle error
} finally {
    // get test report
    // uninstall all APKs
    // disconnect from device
}

Ich bin mir nicht ganz sicher, ob ich die neuesten Implementierungen gefunden habe, aber dieses genaue Verhalten reicht mehrere Jahre zurück. Ich denke, Sie können nicht erreichen, wonach Sie fragen.

tynn
quelle
3

Versuchen Sie es vielleicht adbso:

adb shell am instrument -w com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner

Ihre App wird nicht deinstalliert.

hier wird es ausführlicher beschrieben.

Pavlo Ostasha
quelle
1
Das kann in manchen Situationen praktisch sein. In meinem Fall ist die Aufgabe, die ich wirklich ausführen möchte createDebugCoverageReport, die davon abhängt connectedAndroidDebugTest. Also kann ich es nicht vermeiden connectedAndroidDebugTest, das irgendwie neu zu schreiben createDebugCoverageReport.
CommonsWare
Unter dem Link zu der offiziellen Dokumentation, die ich in der Antwort angegeben habe, finden Sie eine Liste möglicher ADB-Befehlsoptionen am instrument, mit denen Sie arbeiten können am instrument. Und Sie können einen Bericht über die Abdeckung mit Hilfe der emmaOption auf adb erstellen true. Sie können auch eine Zieldatei des Abdeckungsberichts mithilfe der coverageFile Option ändern . Ich hoffe es hilft.
Pavlo Ostasha
"Und Sie können einen Bericht über adb mit Hilfe der Option emma erstellen, die auf true gesetzt ist." - AFAIK, Android verwendet seit Jahren keine Emma-Abdeckung mehr, da es vor langer Zeit zu Jacoco gewechselt ist. Ich nehme an, sie hätten den Optionsnamen beim Ändern der Implementierung
beibehalten können
Vielleicht - ich kenne die Details nicht. Aber es gibt eine solche Möglichkeit.
Pavlo Ostasha
2

Die Instrumentierung installiert 2 APKs: die zu testende APK und die APK mit dem Testcode.

Außerdem werden beide APKs deinstalliert, bevor versucht wird, die neuen zu installieren, und ich weiß nicht, ob es möglich ist, die Deinstallation selbst zu verhindern.

testApplicationIdÄndert nur die Anwendungs-ID für die APK mit dem Testcode (der normalerweise dieselbe ist wie für die Haupt-APK mit angehängtem ".test"). Die Anwendungs-ID der zu testenden APK bleibt unverändert. Es ist jedoch möglich, einen separaten buildType für das zu testende APK zu erstellen (mit genau der gleichen Konfiguration wie der Debug-Build-Typ) und diesen zu verwenden.

Dann connectedAndroidXYZTestkönnte verwendet werden, um die Tests (oder createXYZCoverageReport) auszuführen .

Josef Adamcik
quelle
1
Ich akzeptiere Tynns Antwort, weil es die genaueste für die Frage ist. Ich gebe Ihnen die Prämie für die sicherste Problemumgehung ... vorausgesetzt, Ihr Code versucht zur Laufzeit nichts, basierend auf dem Build-Typ. In diesem Fall müssen Sie daran denken, den XYZBuild-Typ für diesen Code zu berücksichtigen.
CommonsWare
@CoommonsWare das ist richtig. Normalerweise vermeide ich die direkte Überprüfung des Build-Typs und verwende eine "buildConfigField" -Direktive in gradle, um boolesche Flags (oder was auch immer zum Problem passt) in der BuildConfigKlasse zu generieren .
Josef Adamcik