如何确定Android应用程序是否使用JUnit测试工具启动?

问题描述 投票:0回答:4

我需要在运行时从代码确定应用程序是否在 TestInstrumentation 下运行。

我可以使用一些环境/系统变量初始化测试环境,但 Eclipse ADK 启动配置不允许我这样做。

默认的Android系统属性和环境没有任何相关数据。此外,无论应用程序是定期启动还是测试中,它们都是完全相同的。

这可能是一种解决方案:是否可以查明 Android 应用程序是否作为仪器测试的一部分运行,但由于我不测试活动,因此所有建议的方法都不起作用。 ActivityManager.isRunningInTestHarness() 方法在底层使用了这个:

SystemProperties.getBoolean("ro.test_harness") 

在我的例子中总是返回 false。 (为了使用隐藏的 android.os.SystemProperties 类,我使用反射)。

我还能做什么来尝试从应用程序内部确定它是否正在测试?

android junit bootstrapping
4个回答
33
投票

我找到了一种巧妙的解决方案:在应用程序之外,可以尝试从测试包中加载一个类。令人惊讶的是,如果测试项目在测试下运行,应用程序类加载器可以按名称从测试项目加载类。在其他情况下找不到该类。

private static boolean isTestMode() {
  boolean result;
  try {
    application.getClassLoader().loadClass("foo.bar.test.SomeTest");
    // alternatively (see the comment below):
    // Class.forName("foo.bar.test.SomeTest");
    result = true;
  } catch (final Exception e) {
result = false;
  }
  return result;
}

我承认这并不优雅,但它确实有效。将不胜感激正确的解决方案。


16
投票

isTestMode() 解决方案在 Android Studio 1.2.1.1 上对我不起作用。我们公司的全能 Krzysztof 通过使用以下方法调整了您的方法:

Class.forName("foo.bar.test.SomeTest");

而不是 getClassLoader()。感谢克日什托夫!


3
投票

我们创建了一个解决方案,将参数传递给 MainActivity 并在 onCreate 方法中使用它,使您能够定义如何创建 Activity。

MainActivity
类中,我们创建了一些常量,它们也可以是枚举。我们也创建了一个静态属性。

public class MainActivity {
    public static final int APPLICATION_MODE = 5;
    public static final int UNIT_TEST_MODE = 10;
    public static final int OTHER_MODE = 15;

    public static int activityMode = APPLICATION_MODE;
    (...)

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        switch (activityMode) {
            case OTHER_MODE:
                (...)
                break;

            case UNIT_TEST_MODE:
                Log.d(TAG, "Is in Test Mode!");
                break;

            case APPLICATION_MODE:
                (...)
                break;
        }
        (...)
    }
    (...)
}

我们将

MainActivityTest
类抽象化,创建了
setApplicationMode
并在调用
setUp()
方法之前在
super.setUp()
方法中调用此方法。

public abstract class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

    protected void setUp() throws Exception {
        setApplicationMode();  // <=====
        super.setUp();
        getActivity();
        (...)
    }

    (...)
    public void setApplicationMode() {
        MainActivity.activityMode = MainActivity.UNIT_TEST_MODE;
    }
}

所有其他测试类都继承自

MainActivityTest
,如果我们希望它有其他行为,我们可以简单地重写
setApplicationMode
方法。

public class OtherMainActivityTest extends MainActivityTest {
    (...)
    @Override
    public void setApplicationMode() {
        MainActivity.activityMode = MainActivity.OTHER_MODE;
    }
}

用户 nathan-almeida 是该解决方案的共同作者的朋友。


0
投票

JUnit 测试解决方案

fun isRunningTests(): Boolean {
    return try {
        Class.forName("org.junit.runner.JUnitCore")
        true
    } catch (e: ClassNotFoundException) {
        false
    }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.