是否有可能找出Android应用程序是否作为检测测试的一部分运行

时间:2011-07-21 13:18:35

标签: android unit-testing instrumentation

是否有应用程序的运行时检查,以确定它是否作为检测测试的一部分运行?

背景:我们的应用程序在启动时执行数据库同步。但这应该只在定期开始时才会发生。它尤其会干扰测试db sync的检测测试。毫不奇怪。

通过所有其他测试,这只是浪费CPU周期。

9 个答案:

答案 0 :(得分:5)

自API级别11以来,ActivityManager.isRunningInTestHarness()方法可用。这可能会做你想要的。

答案 1 :(得分:3)

一个更简单的解决方案是检查一个只存在于测试类路径中的类,与JUnit 4一起使用(与使用ActivityUnitTestCase的解决方案不同),并且不需要向您的活动/服务发送自定义意图(可能在某些情况下甚至不可能)

private boolean isTesting() {
    try {
        Class.forName("com.company.SomeTestClass");
        return true;
    } catch (ClassNotFoundException e) {
        return false;
    }
}

答案 2 :(得分:2)

如果您正在使用ActivityUnitTestCase,您可以使用setApplication设置自定义Application对象,并在其中有一个标志来打开或关闭数据库同步?在我的博客上有一个使用自定义Application对象的例子:

http://www.paulbutcher.com/2011/03/mock-objects-on-android-with-borachio-part-3/

答案 3 :(得分:1)

您可以将额外的意图传递给您的活动,表明它正在接受测试。

1)在你的测试中,通过" testMode"额外的活动:

public void setUp() throws Exception {
    super.setUp();

    Intent activityIntent = new Intent();
    activityIntent.putExtra("testMode", true);
    setActivityIntent(activityIntent);
}

2)在您的活动中,检查testMode:

Bundle extras = getIntent().getExtras();
if (extras != null && extras.getBoolean("testMode")) {
    // disable your database sync
}

答案 4 :(得分:1)

d= (◕‿↼ ) Great answer,但是如果某些库开发人员(如我)想知道是否正在测试主机(或使用该库的应用程序),请尝试:

import android.content.pm.ApplicationInfo;

// ...

private static int wasTestRun = 0xDEAD;

/**
 * Should only be used to speed up testing (no behavior change).
 * @return true in tests, if Gradle has the right dependencies.
 */
public static boolean isTestRun(@NonNull Context context) {
    if (wasTestRun != 0xDEAD) {
        return wasTestRun != 0;
    }
    // Ignore release builds (as App may be using JUnit by mistake).
    if (isDebuggable(context)) {
        try {
            Class.forName("org.junit.runner.Runner");
            wasTestRun = 1;
            return true;
        } catch (ClassNotFoundException ignored) {
        }
    }
    wasTestRun = 0;
    return false;
}

public static boolean isDebuggable(@Nullable Context context) {
    return context != null && (context.getApplicationContext()
            .getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
}

<块引用>

注意,我没有使用任何 AtomicBoolean 或其他帮助程序,因为它已经非常快了(锁定可能只会降低速度)。

答案 5 :(得分:0)

这对我来说是因为没有实际的设备正在运行

public static boolean isUnitTest() {
    return Build.BRAND.startsWith(Build.UNKNOWN) && Build.DEVICE.startsWith(Build.UNKNOWN) && Build.DEVICE.startsWith(Build.UNKNOWN) && Build.PRODUCT.startsWith(Build.UNKNOWN);
}

答案 6 :(得分:0)

如果您使用的是Robolectric,您可以这样做:

public boolean isUnitTest() {
        String device = Build.DEVICE;
        String product = Build.PRODUCT;
        if (device == null) {
            device = "";
        }

        if (product == null) {
            product = "";
        }
        return device.equals("robolectric") && product.equals("robolectric");
    }

答案 7 :(得分:0)

您可以尝试

if (isRunningTest == null) {
        isRunningTest = false;
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        List<StackTraceElement> list = Arrays.asList(stackTrace);
        for (StackTraceElement element : list) {
            if (element.getClassName().startsWith("androidx.test.runner.MonitoringInstrumentation")) {
                isRunningTest = true;
                break;
            }
        }
    }

答案 8 :(得分:0)

自API级别29开始,静态ActivityManager.isRunningInUserTestHarness()方法可用。

但对于29以下的API:

开发人员可以添加自己的自定义属性:

subprojects {
    tasks.withType(Test).all {
        systemProperty "is-test-run", "true"
    }
}

然后需要以某种方式对其进行检查:

public static boolean isTestRun() {
     return "true".equals(System.getProperty("is-test-run", "false"));
}