sql >> Base de Datos >  >> RDS >> Database

Pruebas automatizadas de la aplicación de escritorio:descripción general de la conveniencia y los marcos

Introducción

Seguro que has oído hablar de las pruebas de regresión y aceptación. Pero, ¿sabe cuánto se gasta realmente en pruebas de aceptación en un proyecto?
Podemos obtener rápidamente una respuesta con la ayuda de un sistema de seguimiento de tiempo como TMetric.
En nuestro proyecto, pruebas de aceptación una aplicación de escritorio de alrededor de 100 ensamblajes tomó más de 2 semanas-persona. Los nuevos especialistas en control de calidad que no conocían bien la aplicación estaban teniendo las mayores dificultades. En comparación con los especialistas en control de calidad más experimentados, dedicaron mucho más tiempo a cada caso de prueba.
Sin embargo, en mi opinión, la parte más desagradable fue esta:si se encuentran errores críticos antes del lanzamiento, se deben realizar pruebas de aceptación nuevamente. después de corregir estos errores.
Las pruebas unitarias escritas ayudaron un poco, pero aun así redujeron en su mayoría el tiempo dedicado a las pruebas de regresión. Con esto, cuando la cantidad de pruebas manuales alcanzó un nivel crítico, comenzamos a avanzar hacia la automatización.

Retorno de la inversión

Antes de escribir pruebas de IU automatizadas, necesitábamos evaluar qué tan rentables son nuestras inversiones. Hicimos esto con la ayuda de ROI (Retorno de la inversión https://en.wikipedia.org/wiki/Return_on_investment)
Calcular el ROI de las pruebas de interfaz de usuario también se convirtió en una tarea interesante con múltiples variables desconocidas:

ROI =Beneficio / Gastos
o
ROI =(Beneficio – Gastos) / Gastos

En esta etapa, necesitábamos un pequeño prototipo que nos ayudara a estimar todos los gastos necesarios. Mostró resultados muy peculiares:realizar pruebas de aceptación lleva aproximadamente la misma cantidad de tiempo que automatizar este proceso. Al principio, esta información parecía cuestionable, pero cuando investigamos más a fondo, las razones quedaron claras:

  • Los nuevos especialistas en control de calidad podrían tener una comprensión limitada de los pasos descritos en los casos de prueba. Cuando esto suceda, algunas personas participarán en las pruebas de aceptación para ayudar a comprender mejor la situación. Aquí, también debemos tener en cuenta la cuestión de cuán relevante es la información que tenemos sobre la configuración y los requisitos del entorno.
  • A veces, las personas involucradas en las pruebas de aceptación dedican tiempo a aprender la documentación técnica.
  • La propia aplicación interactúa con un conjunto específico de servicios. Si uno de ellos no está disponible, los especialistas en control de calidad con menos experiencia dedicarán tiempo a describir errores que los desarrolladores, a su vez, investigarán. Como resultado, se pierde tiempo porque el servicio necesario simplemente no se ejecutó correctamente después de un apagón/actualización de hardware/reinicio de la computadora.
  • Las computadoras de los evaluadores de control de calidad no son muy poderosas. Si no hay SSD, ya lo notará durante la instalación. Además, si la aplicación funciona con mucha carga, es posible que se utilice un archivo de paginación lento.
  • Para ser honesto, nos dejamos llevar y olvidamos que estamos trabajando con automatización. Por cierto, ¿has cerrado la pestaña de Youtube en tu navegador?

Ahora, volvamos al ROI. Para simplificar las cosas, los cálculos se realizaron por tiempo. Calculemos las ganancias como ahorros en pruebas manuales, y el período de tiempo que veremos es un año:

Beneficio =(X – Y) * N =(60 – 1) * 8 =472 días

X:tiempo dedicado a las pruebas manuales (60 días)
Y:tiempo dedicado a la realización de pruebas automatizadas (1 día)
N:la cantidad de tiempo que se realizó la aceptación

A continuación, veremos los gastos:

Gastos =A + B + C + D + E + F =0 + 10 + 5 + 50 + 7 + 8 =80

A – El costo de la licencia de la herramienta de automatización. En nuestro caso, se utilizó una herramienta gratuita.
B – Formación de un especialista en control de calidad (10 días)
C – Preparación de la infraestructura (5 días)
D – Desarrollo de pruebas (50 días)
E – Ejecución de pruebas y descripción de errores descubiertos en el proceso (7 días)
F – Prueba de mantenimiento (8 días)

Total:

ROI =Beneficio / Gastos =472 / 80 =5,9

Por supuesto, algunos de los aspectos aquí son estimados. Para evaluar nuestros propios cálculos, dedicamos un tiempo a investigar las capacidades que ofrecen las soluciones pagas y varias calculadoras de ROI. Con esto, calculamos el valor de ROI promedio de 2 o 3, lo cual es un gran resultado.

Marcos existentes

Habiendo examinado las cuestiones organizativas, centrémonos en cuestiones de tipo técnico. El más importante de ellos fue elegir un marco para automatizar las pruebas de nuestra aplicación de escritorio. Teníamos los siguientes requisitos basados ​​en las características de nuestro proyecto:

  • Las pruebas se desarrollarán y ejecutarán en máquinas con Windows
  • El marco debe adaptarse para probar aplicaciones de escritorio
  • Las pruebas de interfaz de usuario se pueden integrar en el proceso de IC. Ya estábamos usando Jenkins, por lo que era preferible aquí
  • La capacidad de escribir pruebas en un IDE fácil de usar:debe tener resaltado de sintaxis, navegación de scripts de prueba y finalización de código al estilo de IntelliSense
  • Gastos mínimos en capacitación de control de calidad. Por ciertas razones, nuestros especialistas en control de calidad no querían escribir pruebas en Brainfuck
  • Es preferible una comunidad en Stack Overflow, MSDN, etc.

Prueba completa

Esta plataforma inicialmente nos atrajo por su madurez, lo que dio esperanzas en cuanto a los aspectos técnicos.
Lo primero que encontramos fue un IDE inestable y bastante obsoleto. El entorno manejó el resaltado de sintaxis de manera más o menos decente, pero hubo problemas importantes con la navegación (Ir a la definición), la búsqueda y el autocompletado de código:esta funcionalidad no funcionó en absoluto aproximadamente el 60 % del tiempo. La grabadora incorporada y un análogo Inspect funcionaron bien. Al final, el IDE nos dio una sorpresa desagradable cuando comenzó a pasar argumentos a la aplicación. Esto, como era de esperar, provocó errores en el rendimiento de la aplicación:

--no-sandbox
program files (x86)\smartbear\testcomplete12\x64\bin\Extensions\tcCrExtension\tcCEFHost.dll;application/x-testcomplete12-0-chrome-browser-agent

En esta etapa, involucramos al soporte de TestComplete en la situación para intentar ahorrar tiempo y evaluar la calidad del soporte técnico antes de comprar una licencia potencial. Después de enviar algunas cartas al soporte técnico, recibimos una respuesta:debemos ignorar los argumentos pasados ​​​​a la aplicación. Extraño, ¿no? Investigando más, descubrimos que estos argumentos son necesarios para probar aplicaciones que usan CEF. En nuestra siguiente carta, dijimos que usamos CEF, y los especialistas de soporte nos dijeron que no ignoraran los argumentos. Cuando preguntamos cómo usarlos exactamente, la respuesta volvió a cambiar a "Ignorar los argumentos".
Después de nuestra conversación con el soporte técnico, recurrimos a la documentación del IDE (sin muchas esperanzas). Tenía más información, pero no encontramos nada relacionado con el caso en cuestión. Además, de acuerdo con esta misma documentación, el IDE debería haberse comportado de manera diferente desde el principio.
Se supone que las pruebas en TestComplete se escribirán usando VBScript.

Si lo miras lo suficiente, puedes escuchar esto. Microsoft sugiere convertir esta "maravilla" en scripts de PowerShell. Como alternativa, se pueden usar JavaScript y Python, lo que ayuda en la situación.

Como herramienta gratuita, TestComplete sería soportable, pero su sitio tiene una página de precios y los precios son por usuario. Como resultado, esto es lo que obtendremos después de comprar la herramienta:

  • IDE que desea cerrar
  • Compatibilidad con scripts de 1996
  • Una grabadora para que no escribamos todo manualmente
  • Otra inspección, pero con campanas y silbatos
  • 2 tipos de respuestas de soporte técnico
  • Documentación que no representa la realidad

El peor acuerdo comercial de la historia, sigamos adelante.

IU codificada

Retirada táctica, reagrupamiento y flanqueamos la cuestión. Por un lado, aprendimos a usar Visual Studio como IDE. Por otro lado, nuestro enfoque se basó en los componentes de la interfaz de usuario de DevExpress que estamos usando. Como resultado, encontramos información interesante sobre el marco de IU codificada que se usa oficialmente en DevExpress para automatizar las pruebas de IU. Este marco está tan integrado en el proceso de prueba interno que incluso hay una extensión de Visual Studio para él.
Había una comunidad extensa, Microsoft promocionó la herramienta en su sitio web y este producto también ha sido mencionado en el “Microsoft Canal de Visual Studio”. Para resumir, todo parecía prometedor y comenzamos a preparar el marco.
El primer requisito que encontramos fue Visual Studio Enterprise. Además, esta versión de Visual Studio no solo era necesaria para escribir pruebas, sino también para ejecutarlas. Esto significa que mstest a través del cual se realizará el lanzamiento en caso de CI también debe ser parte de la edición Enterprise.
Todas las herramientas de IU codificadas necesarias se pueden instalar al habilitar las casillas de verificación correspondientes cuando se instala o modifica VS.

El enfoque para escribir pruebas fue bastante agradable:los comandos integrados en el shell permitieron iniciar rápidamente una grabadora que genera una prueba unitaria y una clase de "mapa" que describe la interfaz de usuario. Las herramientas adicionales integradas en VS brindaron la capacidad de crear clases de prueba separadas sin llamar al código.
La única peculiaridad que notamos fue una clase parcial que tenía la descripción del control y estaba dividida en dos partes. Junto con muchas otras cosas, se describe en la documentación. Esta documentación es suficiente para un proceso de trabajo cómodo:los ejemplos de código y las capturas de pantalla hacen que toda la información técnica sea fácilmente accesible y fácil de entender. En pocas palabras, cuando la grabadora describe la interfaz de usuario, se genera un archivo "Designer.cs". Este archivo se encarga de reutilizar el código que describe la interfaz de usuario. Todo lo que la grabadora no pudo manejar debe escribirse manualmente y guardarse en algún lugar fuera de la parte autogenerada de la clase. Esto es muy similar a las clases parciales escritas por los diseñadores de VS al crear controles. La prioridad de las operaciones realizadas en los controles y de sus verificaciones de estado se describe en un método al que la grabadora agrega útilmente un atributo TestMethod estándar.
Las nubes comenzaron a acumularse sobre el marco cuando comenzamos a investigar las cosas que generaba la grabadora . En primer lugar, oscureció algunos de los problemas de la aplicación:no se especificó la propiedad Nombre de algunos controles, y la grabadora consideró aceptable esta ridícula instancia de violación de la regla y buscó controles a través del texto. Además, manejó controles complejos de manera muy ineficiente. Por ejemplo, los nodos de TreeView se buscaron por índice de nodo, lo que hizo que la clase de "mapa" creada quedara inutilizable en el caso de la expansión de la interfaz. Y el valor de la grabadora se redujo significativamente a nuestros ojos:¿cuál es el punto de generar automáticamente el código si necesita verificarlo después?
Podríamos hacer las paces con todas estas cosas y encontrar una solución encomiable, pero de repente, un trueno golpeó:Microsoft declaró que esta tecnología ahora está obsoleta. Con esto, VS 2019 se convirtió en la última versión de Visual Studio que admite la interfaz de usuario codificada. La posibilidad de depender de VS 2019 ahora y con un par de años de anticipación realmente no parecía tan aterradora, pero nuestro proyecto es bastante grande, por lo que las dificultades podrían comenzar en algún momento (2025, por ejemplo).
Vamos a resumir. Con la interfaz de usuario codificada, tendremos:

  • Un potente IDE de pago
  • Toda la infraestructura ya creada para pruebas:tanto del lado del IDE como de nuestro CI
  • La capacidad de pedir ayuda a cualquier desarrollador de nuestro proyecto porque estamos escribiendo pruebas en C# en el mismo IDE
  • Una gran cantidad de documentación de buena calidad
  • Algunos tristes especialistas en control de calidad que colocaron su código en la parte autogenerada de la clase y luego lo perdieron durante el proceso de autogeneración
  • Mucho código generado que funciona y que debe someterse a una revisión estricta
  • Un enfoque escandalosamente transparente de CI:puede escribir código para iniciar pruebas a través de mstest con los ojos cerrados
  • Un gigante rojo de automatización que muere lentamente y crece constantemente a partir de nuevas pruebas y está peligrosamente cerca de convertirse en una enana blanca que se desvanece representada por una máquina absolutamente aislada con software irreversiblemente obsoleto o en una explosión de supernova cuando el proyecto implosiona bajo el presión de nuevas actualizaciones.

Todo sonaba bien excepto el último punto. Es por eso que necesitábamos continuar nuestra búsqueda.

TestStack.Blanco

Estábamos trabajando en pruebas de creación de prototipos con la ayuda de White en paralelo a la investigación de la funcionalidad de Coded UI.
White en sí mismo es una envoltura alrededor de las bibliotecas 'Microsoft.Automation' que parecían muy prometedoras, y White también es similar a Coded interfaz de usuario Sin embargo, en un examen más detallado, encontramos que era mucho más austero y se podía notar en todas partes, desde el hecho de que no había grabadora hasta la estructura de prueba real. Por ejemplo, ejecutar la aplicación, buscar una ventana y presionar el botón "Ejecutar" se ve así:

var appPath = @"C:\Program files\UiAutomatedTestApplication\TestApplication.exe";
var app = TestStack.White.Application.Launch(appPath);

var windowSearchCriteria = SearchCriteria.ByAutomationId("MainForm");
var window = app.GetWindow(windowSearchCriteria, InitializeOption.NoCache);

var execute = window.GetElement(SearchCriteria.ByText("Execute"));
var invokePattern = (InvokePattern)execute.GetCurrentPattern(InvokePattern.Pattern);
invokePattern.Invoke();

app.WaitWhileBusy();

Incluso si no hay quejas a la hora de ejecutar la aplicación, la necesidad de trabajar con la clase InvokePattern es muy cuestionable. La clase InitializeOption también se ve extraña porque tiene acceso al miembro estático WithCache, pero se supone que debe usarse estrictamente internamente:

public class InitializeOption {
//
// Summary:
//     This option should not be used as this is only for internal white purposes
public static InitializeOption WithCache { get; }
public static InitializeOption NoCache { get; }
public virtual bool Cached { get; }
public virtual string Identifier { get; }
public virtual bool NoIdentification { get; }

//
// Summary:
//     Specify the unique identification for your window. White remembers the location
//     of UIItems inside a window as you find them. Next time when items inside the
//     same window is found they are located first based on position which is faster.
//
// Parameters:
//   identifier:
public virtual InitializeOption AndIdentifiedBy(string identifier);
public virtual void NonCached();
public override string ToString();
}

Las decisiones extrañas como esta están en todas partes, y el marco resulta ser demasiado abstracto para el control de calidad.

La documentación es de buena calidad y ha dejado una buena impresión general. El código fuente del proyecto estaba alojado en github, pero la última confirmación databa del 8 de enero de 2016.
Resumiendo la información sobre White, tendríamos:

  • Documentación decente
  • Acceso al código fuente
  • Una pequeña comunidad
  • La necesidad de explicar a todos los especialistas de QA que el comportamiento del control se implementa a través de la clase Pattern
  • Un antiguo repositorio del que definitivamente tendríamos que bifurcarnos

La parte más desagradable fue la necesidad de desarrollar nuestro propio marco, que nos gustaría evitar. Así que tuvimos que seguir adelante.

Apio

Hemos encontrado Appium en nuestra búsqueda antes, pero solo comenzamos a considerarlo seriamente después de que Microsoft dejó de usar la interfaz de usuario codificada.
A primera vista, probar con la ayuda de Appium parece una máquina tragamonedas con tres carretes. El primero muestra el idioma para el que existe una API que permite la interacción con el controlador. Esto proporciona la capacidad de escribir pruebas en cualquier lenguaje familiar:Python, C#, Java, etc. El segundo carrete muestra la aplicación del controlador que sirve como capa intermedia entre las pruebas y el producto que estamos probando. Como se describe en la documentación, la interacción con las pruebas se realiza mediante el protocolo JSON Wire:esto es lo que realmente nos da la capacidad de escribir pruebas en cualquier idioma. Y el tercer carrete muestra el objeto que estamos probando. Realmente no importa si se trata de un sitio web, una aplicación móvil o una aplicación de escritorio, siempre que se esté ejecutando el controlador correspondiente. Como puede ver, los componentes son elegantemente intercambiables.
La estimación de la relevancia del paquete fue satisfactoria:en la página de Github, pudimos ver que el repositorio tenía confirmaciones nuevas. Mientras examinamos el repositorio de WinAppDriver, descubrimos que incluso había una grabadora en él.
Empezamos a notar algunos problemas mientras escribíamos un prototipo. Por ejemplo, debido a que el marco es demasiado polivalente, el WindowsElement responsable del control del escritorio tiene un método FindElementByCssSelector que genera la siguiente excepción en la ejecución:“Error inesperado. Comando no implementado:la estrategia del localizador del selector css no es compatible”. En el próximo artículo, hablaremos con más detalle sobre los problemas que encontramos al trabajar con este marco, pero por ahora me gustaría decir que logramos manejarlos todos.

Como resumen, esto es lo que tendremos mientras usamos Appium:

  • La capacidad de probar la funcionalidad de la aplicación que requiere la interacción con un navegador (abrir la página de comentarios, activación en línea, verificar la entrega de correo electrónico) en el ámbito de una infraestructura y una prueba
  • La capacidad de trabajar con cualquier edición de Visual Studio
  • La capacidad de probar una aplicación de escritorio que usa un navegador para representar la interfaz de usuario. Un buen ejemplo de esto sería Azure Data Studio
  • Todas las ventajas que obtenemos con la interfaz de usuario codificada
  • Un marco gratuito que Microsoft recomienda usar
  • Infraestructura familiar para los especialistas de control de calidad que trabajaron con Selenium
  • Un repositorio actualizado con nuevas confirmaciones
  • Una comunidad decentemente grande que, sin embargo, no es tan grande como la comunidad de Coded UI
  • Una grabadora con funcionalidad limitada
  • La necesidad de ejecutar una aplicación de controlador para realizar pruebas. No es muy conveniente, pero tiene su propia funcionalidad de registro
  • Muchas oportunidades para pegarse un tiro en el pie debido a la desafortunada herencia de WindowsElement de AppiumWebElement

Revisando todos los puntos con los requisitos para los marcos y comparando todos los problemas encontrados en cada uno de esos marcos, finalmente elegimos Appium.

Conclusión

Fue interesante trabajar con todos estos marcos porque cada uno de ellos se basaba en una filosofía única de abordar las pruebas automatizadas. Una parte de ellos recién comenzó su camino mientras que otros llegaban a su eclipse o ya se desvanecieron. Puede evitar perderse en las muchas soluciones disponibles creando una lista de requisitos específicos para la herramienta y teniendo un equipo responsable con una interacción bien establecida entre sus miembros. Y no olvide que las pruebas futuras son tanto un proyecto como lo es el código habitual, con una acumulación, tableros, CI, refactorización y todo lo demás.