Probar formularios web largos en varios navegadores y en resoluciones no solo es extremadamente necesario, sino también por tercera o cuarta vez, un proceso extremadamente aburrido y de concentración intensiva. Por lo tanto, esta es exactamente el área que pide automatización. Esto es lo que hicimos.
En este artículo sobre Habr, hablaremos sobre nuestra experiencia en la prueba de pantallas grandes con las herramientas de cuadrícula Protractor, Zalenium y Selenium. Cómo introdujimos gradualmente estas herramientas para las pruebas automáticas de interfaz de usuario y qué dificultades tuvimos que atravesar.

Creamos y mantenemos un sistema en el que 7 mil usuarios activos. La mayoría de las veces usan estos navegadores:

Y las siguientes resoluciones de pantalla:

Cada vez después del lanzamiento de una nueva versión, debe verificar el rendimiento en estos navegadores y permisos.
Para comprender mejor cómo funcionan las pruebas de IU en nuestro caso, considere un caso simple: probar la funcionalidad de una aplicación de recuperación de contraseña. En consecuencia, hay dos páginas. En uno, debe especificar un nombre de usuario o correo en el que vendrá una carta con un enlace a un cambio de contraseña. Después de enviar la aplicación, el usuario va a la página con la confirmación de que todo salió bien.
Formulario de recuperación de contraseña
La página a la que se produce la redirección después del envío exitoso de la aplicaciónLa prueba de este mecanismo de forma simplificada se ve así:

El mismo script que el código:
it(' ', async function(): Promise<boolean | void> { await browser.get(browser.baseUrl); await element(by.name('EmailOrLogin')).sendKeys(userLogin); await element(by.buttonText('')).click(); const screenshot = await browser.takeScreenshot(); const canonicalScreenshotPath = < >; await compareScreenshot(screenshot, canonicalScreenshotPath); });
Como puede ver, el código de prueba parece bastante simple, literalmente repite lo que se muestra en el diagrama de bloques.
Ahora mostramos qué herramientas fueron útiles para implementar este esquema en diferentes resoluciones de pantalla, y qué dificultades encontramos.
Caja de herramientas seleccionada
Comenzó con cromo
Para la automatización de pruebas, elegimos Protractor, un marco e2e para probar aplicaciones angulares. Nuestra aplicación es solo en Angular. Con Protractor, realizamos dos tipos de pruebas:
- Sobre la funcionalidad general: se abre un formulario de envío de solicitud, se completa con datos y se envía una solicitud, después de lo cual verificamos que se haya producido una redirección al registro de todas las aplicaciones.
- Pruebas de captura de pantalla: Protractor le permite tomar una captura de pantalla en cualquier momento. Usando una biblioteca separada de cosecha azul, comparamos dos capturas de pantalla: una referencia y una real. Si no coinciden, se crea inmediatamente una captura de pantalla en la que todas las diferencias son visibles, al igual que en Git.
Por ejemplo, si continúa analizando el ejemplo descrito anteriormente.
Captura de pantalla con mensaje de enlace no válido
Las diferencias (texto y diseño del botón) en la referencia y las capturas de pantalla actuales se resaltan en lilaSi la página contiene datos que cambian dinámicamente (por ejemplo, la fecha o el número de pedido), debe enmascararlos; dicha funcionalidad se encuentra en la biblioteca de cosecha azul. De lo contrario, la comparación de capturas de pantalla arrojará un resultado negativo.
Agregar FF y diferentes permisos
Con el tiempo, nuestros requisitos para el sistema de prueba de IU existente han aumentado:
- ejecutar pruebas no solo en Chrome, sino también en FF,
- realizar pruebas de captura de pantalla no en una resolución, sino en las más populares,
- ejecutar pruebas en paralelo.
Entonces, hagamos que nuestras pruebas se ejecuten en paralelo tanto en Chrome como en FF.
Para hacer esto, en la configuración de capacidades de Protractor'a, reemplácelo con esto:
multiCapabilities: [ { shardTestFiles: true, maxInstances: 2, browserName: 'chrome' }, { shardTestFiles: true, maxInstances: 2, browserName: 'firefox' } ]
Aquí todo es obvio, de lo cual cada entorno es responsable. Solo merece atención
shardTestFiles: true
/** * If this is set to be true, specs will be shared by file (ie all files to be run by this set of capabilities will run in parallel). * Default is false. */
Con este indicador, proporcionamos el lanzamiento paralelo de todas las especificaciones en todos los navegadores que se especifican en multiCapabilities.
El parámetro specs está oculto debajo de las especificaciones de la palabra, que determina por qué plantilla buscar archivos con pruebas.
exports.config = { ... specs: ['./e2e/**/*.spec.ts'], ... }
La teoría de dividir todas las pruebas en varios archivos de especificaciones parece bastante lógica. la simultaneidad funciona en ellos (por ejemplo, crea un archivo de especificaciones para cada característica de la aplicación).
Además, en Protractor'e existe la posibilidad de resaltar suites.
exports.config = { ... suites: { suite01: './e2e/**/suite01.*.spec.ts', suite02: './e2e/**/suite02.spec.ts', suite03: './e2e/**/suite03.spec.ts' }, ... }
Como puede ver en esta parte de la configuración, cuando se inicia una suite, las pruebas se ejecutan desde un solo archivo de especificaciones. Esto probablemente sea útil si desea ejecutar pruebas para solo una parte de la aplicación.
En cuanto a probar la aplicación con diferentes resoluciones, seguimos el siguiente camino. Algunos de los más populares fueron seleccionados como permisos experimentales: 1920x1080, 1366x768, 1440x10900, 768x1024. Cuando ejecuta cada prueba, todas las acciones necesarias se realizaron inicialmente y luego se realizan una serie de comprobaciones de capturas de pantalla.

Conectamos IE y capturas de pantalla de tamaño completo
Las pruebas de captura de pantalla que obtuvimos, desafortunadamente, solo funcionaron en función de la parte inicialmente visible de la página. Y si el desplazamiento estaba presente en la página, entonces todo lo que sigue debajo no se había explorado para el diseño que fue.
Además de esto, también debemos admitir IE, para lo cual nuestras pruebas aún no han sido diseñadas. Comenzamos a buscar una oportunidad adecuada para ejecutar pruebas en IE y tomar capturas de pantalla de tamaño completo.

Nos decidimos por dos soluciones:
Zalenium y
Selenium-Grid . Omitimos la descripción de cuál de ellos se jacta de qué, y hablamos de lo que encontraron / no encontraron en ninguna de las soluciones.
Zalenium : esta solución se ejecuta en un contenedor Docker y otros N contenedores se elevan después del contenedor principal, para lanzar navegadores. Le permite especificar screenWidth, screenHeight durante la
docker run
ventana
docker run
y obtener el tamaño de la pantalla, por ejemplo, 1920x6000. No hay soporte para IE.
Dos navegadores con un tamaño de pantalla de 1920x6000Selenium-grid: las pruebas en IE comenzaron muy fácilmente.
De los inconvenientes: no hay forma de establecer el tamaño de la ventana del navegador de ningún tamaño.
Total: Zalenium + Selenium-gridNos decidimos por un montón de Zalenium + Selenium-grid: a través de Zalenium se decidió ejecutar pruebas en Chrome y FF, y a través de Selenium-grid para verificar el rendimiento mínimo de la aplicación en IE.
Lo que fue interesante cumplir en el proceso
1. Usando formControlName como un localizador de elementosMediante la búsqueda en formControlName, puede buscar fácilmente los campos obligatorios en el formulario y completarlos con datos de prueba. El localizador de formControlName no está integrado, pero es fácil de agregar:
exports.config = { ... onPrepare() { require('ts-node').register({ project: 'e2e/tsconfig.e2e.json' }); jasmine.getEnv().addReporter(new specReporter({ spec: { displayStacktrace: true } })); addFormControlNameLocator(protractor); } ... } function addFormControlNameLocator(protractor) { protractor.by.addLocator('formControlName', function(value, optParentElement) { var using = optParentElement || document; return using.querySelectorAll('[formControlName="' + value + '"]'); }); }
2. La diferencia en el trabajo del administrador de controladores web instalado global y localmente en ProtractorAl instalar Protractor en el sistema (la documentación oficial aconseja instalar Protractor a nivel mundial), además del marco de prueba en sí, obtenemos el controlador webdriver instalado, que proporciona controladores para que los navegadores ejecuten pruebas, con lo cual se detectó uno de los problemas.
Después de ir a la carpeta del proyecto y ejecutar la actualización webdriver-manager, se descargan los controladores para Chrome, FF, IE. Después de eso, al comenzar las pruebas, detectaron el error:
No update-config.json found. Run 'webdriver-manager update' to download binaries.
Nos dimos cuenta de que el error desaparece si empaquetamos la actualización de webdriver-manager en un script npm:
{ ... scripts:{ “webdriver-update”: “webdriver-manager update” } ... }
y ejecutar a través de
npm run webdriver-update
, tanto las fuentes del controlador como el update-config.json mencionado anteriormente entran en la carpeta del proyecto.
3. Ejecutar Zalenium a través de docker-composeLa documentación de Zalenium viene acompañada de ejemplos del comando
docker run
y el archivo docker-compose. Todo despega casi como por arte de magia. El único problema que encontramos ocurrió al iniciar el archivo docker-compose
/var/run/docker.sock is not a valid windows path
. La solución está
aquí .
4. Visibilidad de elementos por transportadorEn el curso de nuestros experimentos, en un momento nos enfrentamos con la tarea de perforar algún menú en la página, es decir. ve a cada página del menú y toma una captura de pantalla.

Después de procesar el primer elemento de la lista, las pruebas comenzaron a caer, arrojando un error de que no había nada que hacer clic en algunas coordenadas. Al final resultó que, independientemente del hecho de que todos los elementos de la lista se seleccionaron inicialmente, después de que se volvieron realmente invisibles para nuestros ojos, desaparecieron a los ojos del transportador.
Resolvimos el problema estableciendo un ancho de pantalla suficiente para que el menú vuelva a aparecer antes de hacer clic en su siguiente elemento.
5. Cambio de resolución en IE (Selenium-grid)Como recordará, en Chrome y FF ajustamos el cambio en la resolución de la pantalla. Cuando se trataba de esto en IE, simplemente detectamos el error:
Failed: java.io.IOException: Server returned HTTP response code: 405 for URL: http://localhost:21800/session/8d14426d-6483-4bbf-90b3-2a3ed46ebe9b/window/size
.
Después de una larga depuración, fue posible descubrir que el error vuela exactamente en el momento en que el código intenta ejecutarse:
browser.driver.manage().window().setSize(x, y)
. Si intenta ejecutar
browser.driver.manage().window().setPosition(x, y)
, luego
browser.driver.manage().window().setPosition(x, y)
el mismo error, solo el tamaño cambiará a la posición. Esto nos lleva al hecho de que es imposible controlar la resolución de la pantalla cuando las pruebas se ejecutan en IE. La solución al problema son las muletas con las que debe superponer su código para no cambiar la resolución \ posición cuando IE se está ejecutando.
6. Zalenium y WebSocketHabiendo recogido todos los baches localmente, se decidió llevar a Zalenium a la infraestructura corporativa. El contenedor está abierto, el DNS está registrado, ahora todos pueden ejecutar pruebas en Zalenium, simplemente especificando la ruta en su configuración de Transportador. Belleza, ¿eh? Pero ahí estaba.
En este caso, todo ya estaba implementado en la máquina Linux, Nginx se utilizó como servidor. El contenedor con Zalenium subió sin problemas, seguido de otros N contenedores para lanzar navegadores, pero ... no pudo establecer conexiones con ellos. Fue fácil descubrir que el contenedor principal intentaba comunicarse con los contenedores de los navegadores a través del protocolo WebSocket, y Nginx no pudo hacerlo de manera predeterminada. El tratamiento es muy simple.
location / { proxy_pass some_url; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; }
9. Lanzamiento de Selenium-GridPara ejecutar Selenium-Grid necesitamos:
- servidor de selenio ,
- Controlador de IE, que es fácil de obtener a través de la actualización de webdriver-manager --ie32.
lanzamiento del servidor:
java -jar selenium-server-standalone.jar -role hub -hubConfig selenium-server-config.json
selenium-server-config.json { "host": "127.0.0.1", "maxSessions": 5, "port": 4445, "cleanupCycle": 5000, "timeout": 300000, "newSessionWaitTimeout": -1, "servlets": [], "prioritizer": null, "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", "throwOnCapabilityNotPresent": true, "nodePolling": 180000, "platform": "WINDOWS" }
lanzamiento del controlador IE:
java -Dwebdriver.ie.driver=< > -jar selenium-server-standalone.jar -role node -nodeConfig .\\ie-driver-config.json
ie-driver-config.json { "capabilities": [ { "browserName": "internet explorer", "maxInstances": 1, "platform": "WINDOWS", "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe" } ], "cleanUpCycle": 2000, "timeout": 30000, "port": -1, "role": "node", "hub": "http://127.0.0.1:4445/grid/register/", "register": true, "maxSessions": 5 }
Preste atención al uso de los mismos puertos al iniciar el servidor y en la URL del concentrador del controlador. Como seleniumAddress en la configuración del transportador, usamos
http://127.0.0.1:4445/wd/hub
.
Conclusiones
Así que resolvimos nuestra tarea y cada vez que se lanza una nueva versión, podemos verificar el rendimiento en estos navegadores y resoluciones.
Cómo integrar pruebas en un flujo de trabajo
Es importante comprender que no basta con elevar toda la infraestructura para ejecutar pruebas y escribirlas. Debe pensar cómo los usará en su vida diaria.
No implementamos pruebas de IU en CI, porque se ejecutan el tiempo suficiente para permitirse esperar su ejecución para cada compilación.
Para probar la versión local de la aplicación o instalarla en uno de los entornos de prueba (internos o del cliente), simplemente cambie baseUrl en la configuración de Protractor. Por lo tanto, el desarrollador y el probador pueden ejecutar las pruebas.
Desarrollador: cuando es necesario ejecutar pruebas, por ejemplo, para la versión local de la aplicación durante el desarrollo de una nueva característica. Especialista en control de calidad: por ejemplo, como prueba de humo después de una implementación en el producto, o como un control en la parte superior después de un montón de refactorización.
En conclusión, queremos enfatizar:- Recuerde que las pruebas de IU no lo salvarán de la necesidad de realizar pruebas manuales detalladas. La automatización solo ayuda a cubrir áreas.
- Use la automatización con prudencia, principalmente para las pruebas de humo. Cubrir todo y todo no tiene sentido: es costoso y difícil mantenerse actualizado
- Escribe simplemente. Si sus pruebas de IU parecen complicadas, entonces está haciendo algo mal. Batir simple y usar como se indica (ver punto 2)
Creemos que automatizar las pruebas de IU es bueno cuando se hace fácilmente. Así que comparta con nosotros sus observaciones y herramientas exitosas en los comentarios.
Enlaces útiles de nosotros: