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í:
- Twitter Fabric + MultiDex causa NoClassDefFoundError
- La biblioteca de Android no funciona con Java 8
- Java.lang.NoClassDefFoundError con todos los R classess cuando se utiliza la biblioteca de Android
- Java.lang.NoClassDefFoundError en versiones anteriores de Android SDK
- Android JavaCV dilema, NoClassDefFoundError lanzado dentro del método 'dibujar' cuando se crea IplImage
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 —–
- NoClassDefFoundError en la muestra de Cocos2D
- ERROR: java.lang.NoClassDefFoundError: android.support.v4.content.LocalBroadcastManager
- Android: NoClassDefFound
- HtmlUnit en Android: Dependencias
- No se pudo encontrar la clase referenciada desde el método android java.lang.NoClassDefFoundError
- NoClassDefFoundError: android.app.ANRManagerProxy
- NoClassDefFoundError al usar greenDao
- Java.lang.NoClassDefFoundError: android.support.v7.app.AppCompatDelegateImplV14 en Android Studio
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>
- Cómo puedo saber dónde en mi imagen he tocado si me he movido y cambiar el tamaño de mi imagen con pinch, arrastrar y zoom
- Cómo actualizar parcialmente las vistas en un widget de aplicación sin reconstruir todas las RemoteViews