Todos los que han estado o participan en autotest de Android saben lo doloroso que es.
Te cansas del volumen de tareas y problemas para que las vacaciones no ayuden. La gente incluso deja de fumar debido a los autotest.
El dolor, el sufrimiento y el tormento conducen inevitablemente a la aparición de algo nuevo y hermoso. Intentamos reunir todos los rastrillos que tuvimos que pisar, unimos fuerzas con los muchachos de Avito y HH y creamos algo que haría que su relación con las pruebas automáticas fuera incomparablemente mejor y más fructífera.
Conoce:
Kaspresso : ¡el marco de autotest que estabas esperando!
Notaré de inmediato que hay dos videos de bastante alta calidad en la
red dedicados a
Kaspresso y
AdbServer (auxiliar para Kaspresso, pero al mismo tiempo, un proyecto sólido e independiente):
1.
Dmitry Movchan, Eugene Matsyuk - Cómo comenzar a escribir autotests y no volverse loco2.
Egor Kournikov: lo único que necesita para las pruebas de IUDescriben en detalle la historia de la creación de bibliotecas: cómo pasamos de resolver un problema a resolver otro y qué sucedió al final. Lo recomiendo mucho
Por lo tanto, en el artículo solo hablaré sobre los puntos principales y las fichas para que pueda comprender rápidamente de qué se trata este marco y qué tareas resuelve. Y se pueden encontrar agallas y detalles en el video y la documentación.
¿Por qué necesitamos nuestro propio marco?
Cada desarrollador que comienza a escribir autotests inevitablemente hace preguntas:
- ¿Cómo comenzar a escribir autotests?
- ¿Qué herramientas elegir?
- ¿Qué hacer si no hay una herramienta necesaria?
- ¿Cuáles son las mejores prácticas?
A todo esto agregue que cada equipo está tratando de resolver estos problemas de alguna manera a su manera. Como resultado, no hay una respuesta única para ellos, no hay ningún lugar para ver cómo hacerlo bien. Por lo tanto, escribir y respaldar autotests es costoso para las empresas, lo que pone en duda la viabilidad de la automatización como tal.
Mientras tanto, la automatización de pruebas persigue buenos objetivos. Le permite tener siempre un asistente verde y listo para lanzar. Y esto significa que puede implementar el lanzamiento rápidamente.
El único problema es encontrar respuestas a las preguntas anteriores. Pero son casi iguales para todos los equipos. Entonces, ¿por qué no automatizar su solución?
¿Qué queremos del marco?
Revelemos un poco nuestras expectativas del marco.
Buena legibilidad
Por defecto, solo la biblioteca Espresso está disponible para nosotros en Android. Existe, por supuesto, Appium + Cucumber, que en teoría le permite escribir pruebas en dos plataformas a la vez. Pero la comunidad se está moviendo con confianza hacia el primer instrumento. No describiré todos los pros y los contras de las bibliotecas anteriores: la red está llena de información sobre esto. Aquí, por ejemplo, está uno de los enlaces relativamente recientes:
Appium vs Espresso. ¿Qué elegir y cómo usar?Entonces, espresso. No es una mala herramienta, pero su API está un poco al revés. Eche un vistazo a un código simple:
@Test fun espressoTest() { onView(allOf(allOf(withId(R.id.espresso), isDescendantOfA(withId(R.id.coffee_variates))), isDescendantOfA(withId(R.id.content)))) .check(matches(withEffectiveVisibility(View.VISIBLE))) }
Tienes que pensar para resolverlo, ¿verdad?
Los dioses de Tailandia y Australia nos presentaron la biblioteca de
Kakao , con la que puede comprender de un vistazo lo que sucede en su prueba. Aquí está el mismo código, pero con Kakao:
@Test fun kakaoTest() { mainScreen { myView.isVisible() } }
Mucho mejor Pero ahora imagine que ha automatizado un caso de prueba completo. ¿Cómo sería el código?
@RunWith(AndroidJUnit4::class) class OpenHomeScreenTest: TestCase() { @Test fun test() { MainScreen() { homeButton.click() } HomeScreen() { title { isVisible() hasAnyText() } } } }
El problema principal es que, al observar esta prueba, es difícil correlacionarla con el caso de prueba que automatizó. Por supuesto, puede agregar registros o algo así. O ingrese dsl, que transforma inmediatamente el aspecto de sus pruebas:
@RunWith(AndroidJUnit4::class) class OpenHomeScreenTest: TestCase() { @Test fun test() { step(“1. Open Home screen”) { MainScreen() { homeButton.click() } } step(“2. Check Home title”) { HomeScreen() { title { isVisible() hasAnyText() } } } } }
De acuerdo, se ve completamente diferente.
Estabilidad
Cualquier biblioteca para ui-tests falla. La misma acción se puede realizar 50 veces con éxito, y en el descanso 51 sin razón aparente. Y en la carrera 52, todo vuelve a estar bien. Y tal "flacidez" puede estropear decentemente sus nervios.
Pensamos, ¿por qué no tratar de interceptar todas las acciones de Kakao-Espresso, y ya agregar allí un comportamiento adicional destinado a manejar tales errores aleatorios?
Así nació la
versión 2.1 de la biblioteca de Kakao , que le permite integrarse en todas las llamadas de Espresso.
Además, creamos nuestros propios interceptores, con los que puede cambiar el comportamiento en el dial-peer o, por ejemplo, simplemente iniciar sesión. Además, estos interceptores son personalizables, por lo que puede personalizarlos para satisfacer sus necesidades. Lea más en el
muelle .
Específicamente, como parte de la lucha contra las pruebas escamosas: si algunas de sus acciones arrojaron una excepción, Kaspresso intentará:
- Desplazarse Tal vez su vista simplemente no sea visible en la pantalla.
- Eliminar el diálogo del sistema que podría provenir de Dios sabe dónde.
- Repita una llamada interrumpida durante dos segundos.
¡Con estos pasos, resolvemos completamente el problema con pruebas escamosas!
Registro
Uno de los principales problemas que acompaña a las pruebas automáticas es la falta de registro inteligible, lo que es especialmente insuficiente cuando la prueba falla. Siéntate y pregúntate qué y cómo ha caído aquí.
Gracias a la interceptación antes mencionada, pudimos construir un sistema de registro bastante extenso.
Echemos un vistazo a un ejemplo:


Por defecto, Kaspresso registra todas sus acciones, selecciona cada paso de la prueba, muestra el tiempo de ejecución, etc.
Adb completo en pruebas de espresso
Inicialmente, adb no está disponible en las pruebas de Espresso. Sí, hay
adb shell , pero hay muchas menos funciones que en
adb completo. Pero hay tantas cosas que pueden ser útiles en las pruebas.
¡Hemos creado una biblioteca
AdbServer separada que devolverá
adb completo a sus pruebas! El video anterior detalla cómo peleamos y por lo que pasamos (
uno y
dos ).
Trabajar con sistema operativo Android
Los detalles de las pruebas en Kaspersky Lab son tales que tenemos que trabajar mucho con el sistema operativo Android: configurar algunas configuraciones, subir archivos al sistema, etc. Todo esto nos llevó a estandarizar todo nuestro trabajo con el sistema, creando un conjunto de interfaces claras, accesible a través de un único punto de entrada -
Dispositivo de clase.
¿Qué son estas interfaces y qué están haciendo? Permíteme darte un par de diapositivas de la presentación de Yegor como ilustración:




La documentación está
aquí .
Debajo del capó, AdbServer y UiAutomator se utilizan principalmente.
Pero! Si de repente no está satisfecho con la implementación de una interfaz, puede configurarla a través del Configurador.
Captura de pantalla para DocLoc (Documentación y localización)
En todos los proyectos donde hay localización, a menudo es necesario tomar capturas de pantalla en diferentes idiomas para dárselas al traductor como ilustraciones. Después de todo, es muy difícil hacer una traducción correcta sin ver dónde y cómo se usa una línea en particular. Por lo tanto, quiero poder tomar capturas de pantalla de forma rápida e inmediata en todos los idiomas. Incluyendo capturas de pantalla de los cuadros de diálogo del sistema. También puede necesitar capturas de pantalla en pantallas heredadas y sin refactorización global.
Todo esto le permite hacer Kaspresso fuera de la caja. Lea más en la
documentación .
Arquitectura y mejores prácticas.
Una de las tareas clave de Kaspresso era crear un dsl que lo llevara a la arquitectura de prueba correcta y su escritura correcta.
Se rompieron muchas copias sobre este tema, porque, desafortunadamente, no encontrará tales reglas en ningún lado. Lo máximo que puede encontrar son artículos sobre
Objeto de página .
Por lo tanto, no escatimamos esfuerzos y destacamos estos problemas en la
documentación y en el
video una vez y el
video dos .
Además, Sasha Blinov escribió un excelente
artículo sobre el DSL Kotlin y las pruebas elegantes . La dsl descrita en el artículo es proporcionada por Kaspresso.
De vuelta en Mobius, propusimos una opción sobre cómo acelerar el impacto de las pruebas automáticas e integrarlas rápidamente en PullRequest, evitando problemas inevitables de infraestructura. Hablamos de esto con más detalle
aquí .
Cómo conectar y configurar Kaspresso si ya tiene muchas pruebas
El principal encanto es que si ya tiene muchas pruebas escritas en Kakao y desea implementar Kaspresso, ¡entonces no necesita reescribir nada! Simplemente herede sus clases de prueba de la clase especial TestCase. ¡Y eso es todo!
Fue:
@RunWith(AndroidJUnit4::class) class OpenHomeScreenTest { private val mainScreen = MainScreen() private val homeScreen = HomeScreen() @get:Rule val activityTestRule = ActivityTestRule(MainActivity::class.java, true, false) @Test fun test() { ... } }
Se convirtió en:
@RunWith(AndroidJUnit4::class) class OpenHomeScreenTest : TestCase() { private val mainScreen = MainScreen() private val homeScreen = HomeScreen() @get:Rule val activityTestRule = ActivityTestRule(MainActivity::class.java, true, false) @Test fun test() { ... } }
Y si no le gusta la herencia, use una clase
TestRule similar.
Como ya mencionamos, Kaspresso es un marco muy flexible y personalizable. Todos los ajustes están disponibles a través de la clase
Kaspresso del mismo nombre.
La configuración predeterminada es predeterminada. Si desea personalizar algo, se verá así:
@RunWith(AndroidJUnit4::class) class OpenHomeScreenTest : TestCase( Kaspresso.Builder.default().apply { viewBehaviorInterceptors.add(MyInterceptor()) flakySafetyParams.timeoutMs = 1_000 } ) { private val mainScreen = MainScreen() private val homeScreen = HomeScreen() @get:Rule val activityTestRule = ActivityTestRule(MainActivity::class.java, true, false) @Test fun test() { ... } }
Es decir,
Kaspresso.Builder está disponible a través del
constructor TestCase , donde establece todas las configuraciones que necesita. Los detalles sobre el configurador están escritos en la
documentación .
Planes inmediatos
En un futuro muy cercano, planeamos agregar lo siguiente:
Mostrar pasos de prueba en Allure (hola a los chicos de HeadHunter)
A través de un interceptor especial, preparamos datos para
Marathon . Esto nos permite ver informes de Allure de la siguiente naturaleza:

Detalles en
PR # 4PS PR ya está en la versión 1.0.1, ahora estamos preparando el PR correspondiente en
Marathon .
Pss. Existe la idea de adjuntar una parte específica del registro a cada paso y agregar una captura de pantalla al paso "caído".
Prueba de scripts de actualización
A menudo es necesario verificar la corrección de las actualizaciones de la aplicación. Sí, algunos de los controles se pueden transferir a pruebas unitarias. Pero nos gustaría estar tranquilos para toda la aplicación en su conjunto.
Desafortunadamente, en un Espresso puro es imposible hacer esto, porque si reinstalamos el apk probado, la prueba fallará. De alguna manera puedes intentar engañar al corredor, pero me resulta difícil imaginar cómo se verán esas mejoras y qué tan estables serán.
Por lo tanto, en Kaspresso, estamos preparando una solución a este problema, basada en UiAutomator. Sin embargo, en la parte superior, tendrá el mismo dsl familiar, muy similar a Kakao y con el mismo soporte para la intersección.
Enlaces utiles
KaspressoAdbServerChat , en el que siempre estaremos encantados de responder todas sus preguntas
Agradecimientos
Un agradecimiento especial a todos los que participaron en el desarrollo del proyecto.
¡Fue muy difícil, pero genial!


En lugar de una conclusión
Creemos que Kaspresso y AdbServer mejorarán su vida.
Agradecemos sus comentarios, recomendaciones, Yishuyam y PulRequest!
¡Y no olvides poner un asterisco, por favor!
PD Y al final una pequeña encuesta =)