如何检测Android应用程序是否正在用Espresso进行UItesting

我正在为Android编写一些Espressotesting。 我正在运行在以下问题:

为了使某个testing用例正常运行,我需要禁用应用程序中的某些function。 因此,在我的应用程序中,我需要检测是否正在运行Espressotesting,以便可以禁用它。 但是,我不想使用BuildConfig.DEBUG ,因为我不希望这些function在debugging版本中被禁用。 另外,我想避免创build一个新的buildConfig来避免创build太多的构build变体(我们已经定义了很多的flavor)。

我正在寻找一种方法来定义buildConfigField进行testing,但是我在Google上找不到任何参考。

Solutions Collecting From Web of "如何检测Android应用程序是否正在用Espresso进行UItesting"

结合CommonsWare的答案。 这是我的解决scheme:

我定义了一个AtomicBooleanvariables和一个函数来检查它是否正在运行testing:

 private AtomicBoolean isRunningTest; public synchronized boolean isRunningTest () { if (null == isRunningTest) { boolean istest; try { Class.forName ("myApp.package.name.test.class.name"); istest = true; } catch (ClassNotFoundException e) { istest = false; } isRunningTest = new AtomicBoolean (istest); } return isRunningTest.get (); } 

这样可以避免每次需要检查值时执行try-catch检查,并且只在您第一次调用此函数时才执行检查。

结合Commonsware评论+ Comtaler的解决scheme,这是一个使用Espresso框架进行testing的方法。

 public static synchronized boolean isRunningTest () { if (null == isRunningTest) { boolean istest; try { Class.forName ("android.support.test.espresso.Espresso"); istest = true; } catch (ClassNotFoundException e) { istest = false; } isRunningTest = new AtomicBoolean (istest); } return isRunningTest.get(); } 

build立在以上Kotlin代码上面的答案是等价的:

 val isRunningTest : Boolean by lazy { try { Class.forName("android.support.test.espresso.Espresso") true } catch (e: ClassNotFoundException) { false } } 

然后你可以检查财产的价值:

 if (isRunningTest) { // Espresso only code } 

你可以为此使用SharedPreferences。

设置debugging模式:

 boolean isDebug = true; SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); editor.putInt("DEBUG_MODE", isDebug); editor.commit(); 

检查debugging模式:

 SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); boolean isDebug = sharedPref.getBoolean("DEBUG_MODE", false); if(isDebug){ //Activate debug features }else{ //Disable debug features } 

我更喜欢不使用在Android上慢的reflection。 我们大多数人都为dependency injection设置了dagger2。 我有一个testing组件进行testing。 这里是获取应用程序模式的简要方法(testing或正常):

创build一个枚举:

 public enum ApplicationMode { NORMAL,TESTING; } 

和一个正常的AppModule:

 @Module public class AppModule { @Provides public ApplicationMode provideApplicationMode(){ return ApplicationMode.NORMAL; } } 

创build一个像我这样的testing赛跑者:

 public class PomeloTestRunner extends AndroidJUnitRunner { @Override public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return super.newApplication(cl, MyTestApplication.class.getName(), context); } } 

不要忘记像这样在gradle中声明它:

 defaultConfig { testInstrumentationRunner "com.mobile.pomelo.base.PomeloTestRunner" } 

现在用override方法创build一个AppModule的子类,看起来和这个完全一样,不要把它标记为类定义之上的模块:

 public class TestAppModule extends AppModule{ public TestAppModule(Application application) { super(application); } @Override public ApplicationMode provideApplicationMode(){ return ApplicationMode.TESTING; //notice we are testing here } } 

现在在您定制的testing运行器中声明的MyTestApplication类中,声明如下:

 public class PomeloTestApplication extends PomeloApplication { @Singleton @Component(modules = {AppModule.class}) public interface TestAppComponent extends AppComponent { } @Override protected AppComponent initDagger(Application application) { return DaggerPomeloTestApplication_TestAppComponent.builder() .appModule(new TestAppModule(application)) //notice we pass in our Test appModule here that we subclassed which has a ApplicationMode set to testing .build(); } } 

现在使用它只需将其注入生产代码中,如下所示:

 @Inject ApplicationMode appMode; 

所以当你运行espressotesting它将testing枚举,但在生产代码时,它将是正常的枚举。

ps没有必要,但如果你需要看看我的生产匕首如何build立这样的graphics,并在应用程序子类中声明:

  protected AppComponent initDagger(Application application) { return DaggerAppComponent.builder() .appModule(new AppModule(application)) .build(); }