是否有应用程序的运行时检查,以确定它是否作为检测测试的一部分运行?
背景:我们的应用程序在启动时执行数据库同步。但这应该只在定期开始时才会发生。它尤其会干扰测试db sync的检测测试。毫不奇怪。
通过所有其他测试,这只是浪费CPU周期。
答案 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()方法可用。
开发人员可以添加自己的自定义属性:
subprojects {
tasks.withType(Test).all {
systemProperty "is-test-run", "true"
}
}
然后需要以某种方式对其进行检查:
public static boolean isTestRun() {
return "true".equals(System.getProperty("is-test-run", "false"));
}