4

首先,有类似herehere的类似问题,但我既没有一些外部库,也没有lib文件夹,也没有一些包含的jar或其他东西,所以我想知道运行Android Junit测试我做错了什么。

我的项目结构如下所示:
在此处输入图像描述

如您所见,我有一个单独的 Android JUnit 测试项目。测试类如下所示:

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();
    }
}

这是它的测试用例:

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);
    }
}

测试项目的清单如下所示:

<?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 是 Instrumentation 对象将运行的应用程序,由元素在其清单文件中分配的包名称标识。(来源:http: //developer.android.com/guide/topics/manifest/instrumentation-element.html

我的主项目中包的名称是

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

所以它正是 targetPackage 指向的地方。如果我作为“Android JUnit 测试”运行,我总是会收到 NoClassDefFoundError 但为什么呢?有任何想法吗?我正在使用ADT 20.0.3Eclipse Juno

最后是 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): 在net.devgems.android.kurzparkzonewien.androidtests.PersistenceManagerTest.testPersistAndRead(PersistenceManagerTest.java:32) 09-22 16:00:12.745: I/TestRunner(1528): at java.lang.reflect.Method.invokeNative(Native Method) 09-22 16:00:12.745: I/TestRunner(1528): at 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): at junit.framework.TestCase.runBare(TestCase.java:127) 09-22 16: 00:12.745: I/TestRunner(1528): at junit.framework.TestResult$1.protect(TestResult.java:106) 09-22 16:00:12.745:I/TestRunner(1528): 在 junit.framework.TestResult.runProtected(TestResult.java:124) 09-22 16:00:12.745: I/TestRunner(1528): 在 junit.framework.TestResult.run(TestResult.java :109) 09-22 16:00:12.745: I/TestRunner(1528): at junit.framework.TestCase.run(TestCase.java:118) 09-22 16:00:12.745: I/TestRunner(1528):在 android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169) 09-22 16:00:12.745: I/TestRunner(1528): 在 android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154) 09-22 16 :00:12.745: I/TestRunner(1528): 在 android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430) 09-22 16:00:12.745: I/TestRunner(1528): 在 android.app.Instrumentation$ InstrumentationThread.run(Instrumentation.java:1447) 09-22 16:00:12.745: I/TestRunner(1528): ----- 结束异常 ---------- 结束异常 -----

4

1 回答 1

2

我找到了解决方案。但这实际上是一种解决方法,因为我无法想象我通常需要像这样修补(也许有人知道更好的解决方案?):

我的主要项目是一个 Maven 项目,在这个项目中,我必须将配置的输出文件夹从/bin...设置为 / target/classestarget/test-classestarget/generated-sources。我这样做是因为否则只要我不运行mvn install,我在主项目中的 JUnit 测试就不会找到最新的代码更改。. 如果输出文件夹是target/...,我不需要运行mvn install来获得我的测试中的最新更改。
现在的问题是,当 Android 测试项目存储在主项目的目标中时,它们找不到已编译的源代码。当我将主项目中的输出文件夹设置为 bin 并运行mvn install,Android测试项目现在可以找到类了。我必须这样做一次。当我将它设置回target时,我的 Android 测试仍然运行,我的主要 JUnit 测试运行。当我更改主项目中的方法时,测试项目立即识别更改,这意味着它没有使用二进制jar或其他东西(这确实很好,虽然我不明白为什么它现在找到它,虽然我将其设置回目标?)。

[更新]
将这两行添加到主项目的 pom to build 部分解决了这个问题,所以我不再需要解决方法了。

    <outputDirectory>bin/classes</outputDirectory>
    <testOutputDirectory>bin/test-classes</testOutputDirectory>
于 2012-09-27T20:11:18.410 回答