Robolectric Tests laufen in Android Studio aber nicht auf der Kommandozeile

Ich versuche, Unit-Tests mit Robolectric zu betreiben; Sie laufen gut unter Android Studio, aber die exakt gleichen Tests scheitern, wenn sie in der Kommandozeile laufen – was eine große Sache ist, muss ich in der Lage sein, sie von meiner kontinuierlichen Integrationsplattform auszuführen, nicht nur von einer IDE.

Ich vermute, dass mir ein Kommandozeilenargument (zB ein Klassenpfad oder ähnliches) fehlt oder die falsche Aufgabe anruft – sonst würde der Test überhaupt nicht von Android Studio laufen. Einige relevante Details; Der Test sieht so aus:

  • So behandeln Sie Benachrichtigung, wenn App im Hintergrund in Firebase
  • So erstellen Sie eine .csv auf Android
  • Erweitern von Präferenzklassen in Android Lollipop = Animation erhöhen
  • Debugging auf meinem Handy (Eclipse, Android)
  • Empfehlen Sie eine Java / Android Game Library - Karte, Board, etc.?
  • Android um ein Layouts Hintergrundbild, nur obere oder untere Ecken
  • @RunWith(RobolectricTestRunner.class) @Config(manifest = "app/src/main/AndroidManifest.xml", resourceDir = "res", emulateSdk = 19) public class SplashActivityTest { @Test public void testActivity() { SplashActivity splashActivity = new SplashActivity(); String appName = splashActivity.getString(R.string.app_name); // HERE, line 20 assertEquals(appName, "App"); } } 

    Wie oben erwähnt, läuft es in Android Studio gut aus (indem man mit der rechten Maustaste auf die Testdatei klickt und Run 'SplashActivityTest' ), aber wenn es von der Befehlszeile aus ausgeführt wird, scheitert es in der mit HERE markierten Zeile mit der folgenden Stack-Trace:

     android.content.res.Resources$NotFoundException: unknown resource 2131492893 at org.robolectric.shadows.ShadowAssetManager.getAndResolve(ShadowAssetManager.java:309) at org.robolectric.shadows.ShadowAssetManager.getResourceText(ShadowAssetManager.java:69) at android.content.res.AssetManager.getResourceText(AssetManager.java) at android.content.res.Resources.getText(Resources.java:240) at org.robolectric.shadows.ShadowResources.getText(ShadowResources.java:361) at android.content.res.Resources.getText(Resources.java) at android.content.res.Resources.getString(Resources.java:330) at org.robolectric.shadows.ShadowContext.getString(ShadowContext.java:39) at org.robolectric.shadows.ShadowContextWrapper.getString(ShadowContextWrapper.java:69) at android.content.Context.getString(Context.java) at path.to.myApp.activities.SplashActivityTest.testActivity(SplashActivityTest.java:20) // ... and so on ... 

    Ich benutze das, um von der Kommandozeile aus zu laufen (beachten Sie, dass hier und im Android Studio ich den Gradle Wrapper verwende):

     project-root$ ./gradlew test --continue 

    Auch: Ich benutze Android Studio 1.1.0 , Gradle Version ist 2.3 , Robolectric's Version ist 3.0-SNAPSHOT und Robolectric's Gradle Plugin Version ist 1.0.1

  • SwipeRefreshLayout keine Animation zur Fragment-Erstellung
  • SwipeRefreshLayout deaktiviere die Drag-Animation beim Ausrollen
  • Wie platziere ich Widgets über und unter einer Listenansicht?
  • Warum Google Play Store zeigt nicht den Grund für Gerät nicht verfügbar für App?
  • Ionic build Android | Fehler: Es wurden keine installierten Build-Tools gefunden. Bitte installieren Sie die Android-Build-Tools
  • Ist ein 45% Active installiert auf androiden Marktplatz "hoch / niedrig / weiß nicht" für die Anwendung?
  • 2 Solutions collect form web for “Robolectric Tests laufen in Android Studio aber nicht auf der Kommandozeile”

    Es stellt sich heraus, dass dies ein bekanntes Problem ist. Die Ressourcen eines Projekts werden im falschen Verzeichnis gesucht, wenn Tests aus der Befehlszeile ausgeführt werden, hier ist ein Link zum Problem; Denn jetzt ist der Workaround, um einen benutzerdefinierten Testläufer zu schreiben, wie hier gezeigt :

     public class RobolectricGradleTestRunner extends RobolectricTestRunner { public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError { super(testClass); String buildVariant = (BuildConfig.FLAVOR.isEmpty() ? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE; String intermediatesPath = BuildConfig.class.getResource("").toString().replace("file:", ""); intermediatesPath = intermediatesPath.substring(0, intermediatesPath.indexOf("/classes")); System.setProperty("android.package", BuildConfig.APPLICATION_ID); System.setProperty("android.manifest", intermediatesPath + "/manifests/full/" + buildVariant + "/AndroidManifest.xml"); System.setProperty("android.resources", intermediatesPath + "/res/" + buildVariant); System.setProperty("android.assets", intermediatesPath + "/assets/" + buildVariant); } } 

    Die Testfälle müssen entsprechend aktualisiert werden, um den benutzerdefinierten Testlaufer anstelle der @Config Annotation zu verwenden:

     @RunWith(RobolectricGradleTestRunner.class) public class SplashActivityTest { // tests same as before } 

    Außerdem empfiehlt es sich, beim Ausführen der Tests von der Befehlszeile aus clean , da der Workaround vom Inhalt des Build-Verzeichnisses abhängt, wir wollen dort keine abgestandenen Daten haben:

     project-root$ ./gradlew clean test --continue 

    Ich habe den gleichen Fehler gelöst, aber auf andere Weise. Ich habe benutzerdefinierte Schatten in Tests verwendet, also muss ich meine eigene TestRunner-Klasse erstellen, wie folgt:

     public class MyRobolectricTestRunner extends RobolectricTestRunner { public MyRobolectricTestRunner(Class<?> klass) throws InitializationError { super(klass); } public InstrumentationConfiguration createClassLoaderConfig() { InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); builder.addInstrumentedClass(AppUtils.class.getName()); return builder.build(); } } 

    Aber über Code funktionierte nur, wenn ich den Unit-Test aus dem Andorid Studio betreibe. Bitte überprüfen Sie den Code, der für mich auf beide Arten funktioniert: im Studio und von der Kommandozeile :

     public class MyRobolectricTestRunner extends RobolectricTestRunner { public MyRobolectricTestRunner(Class<?> klass) throws InitializationError { super(klass); } @Override public InstrumentationConfiguration createClassLoaderConfig() { InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder(); builder.addInstrumentedPackage(com.example.stackoverflow.AppUtils.class.getPackage().getName()); return builder.build(); } } 

    Bitte beachten Sie, ich habe die Abhängigkeit:

     testCompile 'org.robolectric:robolectric:3.0' 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.