1

我正在构建一个 android 应用程序,我想使用 JUnit 测试而不是 Android JUnit 测试进行单元测试(因为使用模拟器运行 Android 测试需要很长时间)。

环境:

  • 安卓项目
  • Android测试项目(目标包=android项目包)
  • JUnit4 / Mockito
  • 使用 JUnit 运行单元测试(故意不是Android JUnit)

只要我测试自己编写的不依赖于 Android 类的类,一切顺利。Log.i()但是,当我想为包含例如语句或引用a 的类编写测试时TextView,会遇到以下错误:

java.lang.NoClassDefFoundError: android/text/TextWatcher at java.lang.ClassLoader.defineClass1(Native Method)

Android 应用程序清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cleancode.lifesaver"
    android:versionCode="1"
    android:versionName="1.0" >

Android 测试项目清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cleancode.lifesaver.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.cleancode.lifesaver" />

测试类:

import android.widget.TextView;

public class CapCharacterTextValidator extends TextValidator {

    public CapCharacterTextValidator(TextView textView) {
        super(textView);
    }

    @Override
    public void validate(TextView textView, String text) {

    }
}

测试类:

import org.junit.Test;
import com.cleancode.lifesaver.utils.CapCharacterTextValidator;

public class CapCharactersTextValidatorTests {

    @Test
    public void validateCharacters() {
        new CapCharacterTextValidator(null);
    }
}

我尝试在 Android 应用程序和 Android 测试应用程序或两者之一的导出库中添加 android 库,但仍然没有给我一个绿色测试。无论我尝试什么,我都会遇到这个NoClassDefFoundError

我阅读了大部分 android 文档,但他们似乎真的很喜欢在模拟器上使用 Android JUnit 的方法(对我来说太慢了)。

以下问答帖子也没有进一步帮助我:

任何帮助将不胜感激!

4

3 回答 3

1

要在单元测试中运行任何依赖于 Android 框架的东西,您必须使用 Android 测试运行器。没有其他方法会起作用。框架必须存在。

于 2013-09-16T21:43:46.683 回答
0

嗯,找到了一个替代方案,这可能是“唯一的方法”,因为我将一起转而使用 Android JUnit 测试。

如果我创建一个测试项目(只是一个使用 JUnit 和 Android 作为库而不是Android测试项目的普通 Java 项目),那么我可以运行单元测试,而不会在类路径中找到 Android 库。

如果您有冲动遵循与我相同的方法,您可能还会遇到下一个问题,即您的代码中不能有 Android Log 语句,因为 Android 框架会RuntimeException在您执行时抛出例如Log.i("tag", "msg").

由于我仍然喜欢记录,因此我将Log课程包装如下:

import android.util.Log;

public class Logger {

    private static boolean AllowLogging = true;

    public void disableAndroidLogging() {
        AllowLogging = false;
    }

    public static int d(String label, String message) {
        if (AllowLogging) {
            return Log.d(label, message);
        }
        return 0;
    }
}

我在测试类的设置中禁用了 Logger。这样我就避开了 Android 框架的异常。

如果有人有更好的解决方案,我非常愿意提供建议。

非常感谢。

巴斯

于 2013-09-16T20:51:54.413 回答
0

使用Robolectric。它为你模拟了所有的 Android 类。

于 2013-09-17T11:33:29.337 回答