keep developer android android-testing android-wake-lock android-espresso

developer - Android Espresso, despertador antes del test. ¿Cómo utilizar un manifiesto personalizado para la prueba?



powermanager android (8)

Ahora que KeyguardLock está en desuso, simplemente puede usar:

if (BuildConfig.DEBUG) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); }

He estado escribiendo pruebas con el nuevo marco de espresso de androides y descubrí que funciona bien. Una cosa molesta (que no está especialmente relacionada con el espresso) es que tengo que asegurarme de que la pantalla esté activada y desbloqueada para que se ejecuten las pruebas. Encontré una solución alternativa (a través de varias fuentes), pero no estoy seguro de cuál es la mejor manera de integrarla.

Así que esto es lo que hice, en mi actividad "Inicio" tengo el siguiente código:

Clase de

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /************ Put this in a conditional for a test version ***********/ KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("TAG"); keyguardLock.disableKeyguard(); getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); }

También es necesario agregar los siguientes permisos:

<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> <uses-permission android:name="android.permission.WAKE_LOCK"/>

Así que, después de hacer esto, mis pruebas ahora activan mi teléfono para que funcione, por lo que no tengo que hacer guardia y asegurarme de que la pantalla no se apague justo antes de que comiencen las pruebas.

Preferiría no incluir esos permisos en mi aplicación, obviamente. Sé que con Gradle es posible hacer diferentes "sabores" que tienen su propio manifiesto de Android que se fusionará en el manifiesto principal. Estaba pensando en usar eso, pero preferiría no agregar un sabor solo por esa razón, dado que esto ya está usando el tipo de compilación de prueba para ejecutar. Parece que a partir de la documentación de Android Gradle no se puede crear un AndroidManifest para el directorio instrumentTest ya que se generará automáticamente.

Sin embargo, me preguntaba si hay otra forma de hacerlo sin crear una variante y luego especificar que las pruebas deberían ejecutar esa variante. Además, no estoy seguro de la sintaxis exacta de todo eso y pensé que sería bueno tener esta información en el sitio para otros, ya que parece estar dispersa.

Por último, si alguien sabe de una mejor manera de resolver el problema de despertar el teléfono para las pruebas, me encantaría escucharlo, ya que no soy un gran fanático de esta manera.


Aunque ya ha aceptado la respuesta de Matt Wolve, creo que no es una buena idea contaminar su código con una plantilla de prueba (soy consciente de que al usar Espresso hay algunas situaciones en las que tiene que hacerlo, como agregar indicadores de inactividad para los IdlingResources personalizados). Me gustaría añadir otro enfoque:

@ClassRule public static ActivityTestRule<HomeActivity> mActivityRuleSetUp = new ActivityTestRule<>( HomeActivity.class); private static void wakeUpDevice(){ if (BuildConfig.DEBUG){ HomeActivity homeActivity = mActivityRuleSetUp.getActivity(); KeyguardManager myKM = (KeyguardManager) homeActivity.getSystemService(HomeActivity.KEYGUARD_SERVICE); boolean isPhoneLocked = myKM.inKeyguardRestrictedInputMode(); if (isPhoneLocked){ homeActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); } } } @BeforeClass public static void setUp(){ wakeUpDevice(); }

Espero eso ayude.


El método más sencillo es usar el comando adb como se muestra a continuación si está ejecutando las pruebas desde el entorno de CI, por ejemplo:

adb -s $DEVICE_ID shell input keyevent 82

Esto desbloqueará la pantalla de su dispositivo.


En realidad, descubrí una manera muy fácil de manejar esto. Elimine los permisos de bloqueo de teclas y wakelock del manifiesto principal y colóquelos en src / debug / AndroidManifest.xml de esta forma:

src / debug / AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" > <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> </manifest>

Cuando la aplicación esté diseñada para la depuración, los permisos anteriores se fusionarán en el manifiesto principal. Por defecto, el sistema de compilación usa la compilación de depuración para las pruebas de instrumentos, por lo que esto funciona bien.

Luego en mi onCreate puse el código mencionado en la pregunta:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (BuildConfig.DEBUG) { KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("TAG"); keyguardLock.disableKeyguard(); getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); } ... }

Ahora mi teléfono puede ejecutar pruebas sin que yo las despierte primero a mano y no tuve que agregar los permisos anteriores a la versión de lanzamiento de mi aplicación.


He creado el archivo src / debug / AndroidManifest.xml como Matt sugirió y agregó al siguiente código para el testCase:

@Override public void setUp() throws Exception { super.setUp(); // Espresso will not launch our activity for us, we must launch it via getActivity(). Activity activity = getActivity(); KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE); KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("TAG"); keyguardLock.disableKeyguard(); activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); }


Lo he hecho de esta manera: primero establece dos reglas, una para la actividad y otra para el hilo de la interfaz de usuario:

@Rule public ActivityTestRule<Your Activity> mActivityRule = new ActivityTestRule<>(Your Activity.class, true, true); @Rule public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();

Y luego en mi primer método de prueba hice esto:

@Test @LargeTest public void CreateAndSaveTaskEntity() throws Throwable { uiThreadTestRule.runOnUiThread(new Runnable() { @Override public void run() { Your Activity activity = mActivityRule.getActivity(); activity.getWindow() .addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); } }); //begin test cases ... }

Por supuesto que tiene que agregar en AndroidManifest.xml los permisos:

<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/> <uses-permission android:name="android.permission.WAKE_LOCK"/>


Otra mejor manera de despertar el dispositivo antes de la prueba. Simplemente agregue ActivityLifecycleCallback en su método de setUp .

public class Moduletest extends ActivityInstrumentationTestCase2<Your Activity>{ protected void setUp(){ super.setUp(); ActivityLifecycleMonitorRegistry.getInstance().addLifecycleCallback(new ActivityLifecycleCallback() { @Override public void onActivityLifecycleChanged(Activity activity, Stage stage) { if (stage == Stage.PRE_ON_CREATE) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } }); } }


Para probar el dispositivo, establezca el patrón de bloqueo en NINGUNO en Configuración-> Seguridad. Luego use la instancia de UiDevice y llame a su método wakeUp()

Este método simula presionar el botón de encendido si la pantalla está apagada, de lo contrario no hace nada si la pantalla ya está encendida. Si la pantalla estaba apagada y se acaba de encender, este método insertará un retraso de 500 ms para permitir que el dispositivo se active y acepte la entrada.