NoClassDefFoundError durante la ejecución de la prueba de Android JUnit

En primer lugar, hay preguntas similares como aquí o aquí, pero no tengo ni librerías externas, ni una carpeta lib, ni algunos jarros incluidos o algo así, así que me pregunto qué estoy haciendo mal al ejecutar pruebas de Junit de Android.

Mi estructura de proyecto se ve así:
Introduzca aquí la descripción de la imagen

Como puedes ver, tengo un proyecto separado para las pruebas de Android JUnit. La clase de prueba se ve así:

public class PersistenceManager { private static final String FILENAME = "kpzwien_storage"; public static void persist(String data, Context context) throws IOException { FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(data.getBytes()); fos.close(); } public static String read(Context context) throws IOException { FileInputStream fis = context.openFileInput(FILENAME); StringBuffer fileContent = new StringBuffer(""); byte[] buffer = new byte[1024]; while (fis.read(buffer) != -1) { fileContent.append(new String(buffer)); } return fileContent.toString(); } } 

Y aquí está su caso de prueba:

 public class PersistenceManagerTest extends AndroidTestCase { private final String FILENAME_PREFIX = "test."; @Before public void setUp() { MockContentResolver resolver = new MockContentResolver(); RenamingDelegatingContext renamingDelegatingContext = new RenamingDelegatingContext(new MockContext(), getContext(), FILENAME_PREFIX); Context context = new IsolatedContext(resolver, renamingDelegatingContext); setContext(context); } public void testPersistAndRead() throws IOException { String testData = "foobar"; PersistenceManager.persist(testData, getContext()); String result = PersistenceManager.read(getContext()); assertEquals(testData, result); } } 

El manifiesto del proyecto de prueba tiene este aspecto:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.devgems.android.kurzparkzonewien.androidtests" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="4" /> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="net.devgems.android.kurzparkzonewien.activities" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <uses-library android:name="android.test.runner" /> </application> </manifest> 

TargetPackage es la aplicación que ejecutará el objeto Instrumentation en contra de la cual está identificada por el nombre del paquete asignado en su archivo de manifiesto por el elemento. (Fuente: http://developer.android.com/guide/topics/manifest/instrumentation-element.html

El nombre del paquete en mi proyecto principal es

Package = "net.devgems.android.kurzparkzonewien.activities"

Así que es exactamente donde targetPackage apunta. Si ejecuto como "prueba de JUnit para Android", siempre obtengo un NoClassDefFoundError pero ¿por qué? ¿Algunas ideas? Estoy usando ADT 20.0.3 , Eclipse Juno .

Por fin aquí está la salida logcat:

09-22 16: 00: 12.745: I / TestRunner (1528): java.lang.NoClassDefFoundError: net.devgems.android.kurzparkzonewien.controller.PersistenceManager 09-22 16: 00: 12.745: I / TestRunner (1528): at Net.devgems.android.kurzparkzonewien.androidtests.PersistenceManagerTest.testPersistAndRead (PersistenceManagerTest.java:32) 09-22 16: 00: 12.745: I / TestRunner (1528): en java.lang.reflect.Method.invokeNative (Método nativo) 09-22 16: 00: 12.745: I / TestRunner (1528): en java.lang.reflect.Method.invoke (Method.java:521) 09-22 16: 00: 12.745: I / TestRunner (1528): at Junit.framework.TestCase.runTest (TestCase.java:154) 09-22 16: 00: 12.745: I / TestRunner (1528): en junit.framework.TestCase.runBare (TestCase.java:127) 09-22 16: 00: 12.745: I / TestRunner (1528): en junit.framework.TestResult $ 1.protect (TestResult.java:106) 09-22 16: 00: 12.745: I / TestRunner (1528): en junit.framework.TestResult. RunProtected (TestResult.java:124) 09-22 16: 00: 12.745: I / TestRunner (1528): en junit.framework.TestResult.run (TestResult.java:109) 09-22 16: 00: 12.7 45: I / TestRunner (1528): en junit.framework.TestCase.run (TestCase.java:118) 09-22 16: 00: 12.745: I / TestRunner (1528): en android.test.AndroidTestRunner.runTest (AndroidTestRunner .java: 169) 09-22 16: 00: 12.745: I / TestRunner (1528): en android.test.AndroidTestRunner.runTest (AndroidTestRunner.java:154) 09-22 16: 00: 12.745: I / TestRunner (1528 ): En android.test.InstrumentationTestRunner.onStart (InstrumentationTestRunner.java:430) 09-22 16: 00: 12.745: I / TestRunner (1528): en android.app.Instrumentation $ InstrumentationThread.run (Instrumentation.java:1447) 09-22 16: 00: 12.745: I / TestRunner (1528): —– extremo excepción —–

Encontré la solución. Pero en realidad es algún tipo de solución porque no puedo imaginar que normalmente necesito hacer esto (quizás alguien conoce una mejor solución?):

Mi proyecto principal es un proyecto Maven, en este proyecto tengo que configurar las carpetas de salida de / bin … a / target / classes , target / test-classes y target / generated-sources . Lo he hecho porque de lo contrario mis pruebas JUnit desde el proyecto principal no encontraría los últimos cambios de código siempre y cuando no ejecute mvn install. . Si las carpetas de salida son target / … , no necesito ejecutar mvn install para tener los últimos cambios en mis pruebas.
El problema ahora es que el proyecto de prueba de Android no encuentra las fuentes compiladas cuando se almacenan en el destino del proyecto principal. Cuando pongo la carpeta de salida en el proyecto principal a bin y ejecute mvn install , el proyecto de prueba de Android puede encontrar las clases ahora. Tengo que hacer esto solo una vez. Cuando la vuelvo a establecer, ambas pruebas de Android siguen funcionando y se ejecutan las pruebas principales de JUnit. Cuando cambio los métodos en el proyecto principal, el proyecto de prueba reconoce inmediatamente los cambios, por lo que significa que no utiliza jar binario o algo (que es realmente muy bueno, aunque no entiendo por qué lo encuentra ahora, aunque ¿Lo puse de nuevo a la blanco?).

[ACTUALIZAR]
La adición de estas dos líneas a la sección pom para construir del proyecto principal soluciona el problema, por lo que ya no necesito una solución.

  <outputDirectory>bin/classes</outputDirectory> <testOutputDirectory>bin/test-classes</testOutputDirectory> 
  • ¿Enfoque para la fijación de NoClassDefFoundError?
  • QMOBILE, TECNO, ALPES java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder
  • NoClassDefFoundError debajo de SDK 21
  • ¿Cómo arreglar NoClassDefFoundError en twitter4j usando Android Studio?
  • ActionBarSherlock: java.lang.NoClassDefFoundError: com.actionbarsherlock.R $ styleable
  • Error al iniciar la actividad debido a ClassNotFoundException
  • NoClassDefFoundError en un jar anidado (Android)
  • Excepción de mapas de Android java.lang.NoClassDefFoundError: android.security.MessageDigest
  • Problemas de inicialización de la clase cargando java.util.logging.LogManager en Android Dalvik VM
  • Error de Eclipse: NoClassDefFoundError: java / lang / ref / FinalReference
  • Java.lang.NoClassDefFoundError: com.facebook.android.Facebook
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.