我需要在运行时从代码确定应用程序是否在 TestInstrumentation 下运行。
我可以使用一些环境/系统变量初始化测试环境,但 Eclipse ADK 启动配置不允许我这样做。
默认的Android系统属性和环境没有任何相关数据。此外,无论应用程序是定期启动还是测试中,它们都是完全相同的。
这可能是一种解决方案:是否可以查明 Android 应用程序是否作为仪器测试的一部分运行,但由于我不测试活动,因此所有建议的方法都不起作用。 ActivityManager.isRunningInTestHarness() 方法在底层使用了这个:
SystemProperties.getBoolean("ro.test_harness")
在我的例子中总是返回 false。 (为了使用隐藏的 android.os.SystemProperties 类,我使用反射)。
我还能做什么来尝试从应用程序内部确定它是否正在测试?
我找到了一种巧妙的解决方案:在应用程序之外,可以尝试从测试包中加载一个类。令人惊讶的是,如果测试项目在测试下运行,应用程序类加载器可以按名称从测试项目加载类。在其他情况下找不到该类。
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;
}
我承认这并不优雅,但它确实有效。将不胜感激正确的解决方案。
isTestMode() 解决方案在 Android Studio 1.2.1.1 上对我不起作用。我们公司的全能 Krzysztof 通过使用以下方法调整了您的方法:
Class.forName("foo.bar.test.SomeTest");
而不是 getClassLoader()。感谢克日什托夫!
我们创建了一个解决方案,将参数传递给 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 是该解决方案的共同作者的朋友。
JUnit 测试解决方案
fun isRunningTests(): Boolean {
return try {
Class.forName("org.junit.runner.JUnitCore")
true
} catch (e: ClassNotFoundException) {
false
}
}