¿Por qué para el nuevo proyecto tomé Robot Framework?

Recientemente cambié el proyecto: llegué a un nuevo desarrollo, donde antes no había pruebas, ni manuales ni automáticas. El cliente no impuso condiciones en el kit de herramientas (excepto que era Python), así que tomé mi propia decisión. En este artículo, explicaré por qué en tales condiciones elegí Robot Framework. Y al final habrá algunos ejemplos especialmente escritos para el artículo que ilustran de lo que estamos hablando.

imagen

Llevo más de 10 años realizando pruebas de automatización, y aproximadamente tres de ellas interactuaron con Robot Framework.

Como señalé anteriormente, no hace mucho tiempo llegué a un nuevo proyecto, donde comencé a probar la automatización desde cero. No puedo contarte sobre el proyecto - NDA. Solo noto que esta es una herramienta de automatización genial, que en el futuro debería ahorrar una gran cantidad de recursos humanos. Está construido a partir de microservicios. Hasta ahora, mi trabajo concierne a cuatro de ellos, pero en el futuro expandiré mis actividades a otros, todo se reduce al hecho de que solo tengo 8 horas de trabajo al día. Todo lleva tiempo.

La falta de pruebas en el caso de este proyecto fue idéntica a la falta de herramientas recomendadas. Como parte de la pila de Python, tenía libertad de elección. Y lo aproveché.

¿Por qué Robot Framework?


Creo que puedo atribuirme a los fanáticos de Robot Framework. Me parece que casi todo se puede hacer al respecto.

En otros proyectos, la compañía usa pytest. Sin embargo, en mi opinión, no tiene tales capacidades, ya que está limitado por las capacidades de Python. Simplemente escriba el código Python y tenga en cuenta que espera un cierto valor en dicha variable. Para mi gusto, es simple pero demasiado abstracto. Mucho se ha dejado a merced del desarrollador, que tendrá que agregar todas las características útiles a mano. Robot Framework lo hace él mismo. Aquí hay cuatro puntos que vale la pena tomar para su proyecto.

Flexibilidad


Robot Framework en sí está escrito en Python (es decir, todo lo que Python puede hacer), y para ello hay muchas bibliotecas creadas por la comunidad, lo que amplía enormemente el rango de problemas a resolver.

Bajo Robot Framework, puede escribir fácilmente sus propias bibliotecas, integrándolas con casi cualquier cosa, y todo funcionará de inmediato. No se requieren muletas o bicicletas.
Además, Robot Framework le permite escribir pruebas paramétricas (plantillas), lo que acelera enormemente el trabajo de la herramienta de automatización.

Idioma ruso en las pruebas


Uno de los puntos fundamentales es que la palabra clave (análogos de los métodos convencionales en Robot Framework, que por alguna razón se han denominado históricamente de esa manera) se puede escribir en ruso. Como resultado, los textos de prueba están, por supuesto, lejos del lenguaje literario, pero a primera vista queda claro lo que está sucediendo allí. En primer lugar, esto no es necesario para los desarrolladores finales, sino, por ejemplo, para las partes interesadas. Pueden abrir las pruebas de forma independiente y ver qué sucede exactamente allí: "Seleccionar un elemento aleatorio de ...", etc.

Etiquetado


Robot Framework funciona bien con etiquetas. No solo puede ejecutar pruebas con una etiqueta específica, sino también analizar informes con su ayuda. El archivo de registro contiene estadísticas sobre etiquetas, en función de las cuales puede tomar alguna medida si piensa en la disposición de las etiquetas por adelantado.

Convenientemente, no es necesario que escriba todas las etiquetas en un paño largo en cada prueba, pero puede insertar pruebas en una estructura de árbol. En mi caso, se ve así: el primer nivel es un microservicio, el segundo es el tipo de prueba, el tercero son las pruebas en sí mismas (es conveniente poner un archivo init que contenga etiquetas para lo que está incrustado dentro).

Creé una etiqueta para cada microservicio, cada enfoque de prueba (pruebas de humo, pruebas CRUD, integración, etc.). Puedo ejecutar pruebas de un tipo específico o solo para un servicio específico. También etiqueto el tipo de función: lista o detallada. Y si el producto responsable de la lista funciona "se rompe" en el producto, todas las pruebas con esta etiqueta se volverán rojas, independientemente de dónde se encuentren y con qué se relacionen.

Por etiquetas ato autotests a Jira. Cuando el error del rastreador se cierra y la prueba del rojo se vuelve verde, todavía tenemos un historial de lo que ha cambiado exactamente. Muchos meses después, si la prueba se vuelve roja nuevamente, podemos ver qué pasos se tomaron para solucionar el problema la última vez, e incluso asumir que condujo a la repetición del error.

Otra etiqueta especial que he agregado para errores no críticos. GitLab no nos permite hacer nada con el ensamblaje si al menos una prueba falla. Esto es lógico: hasta que se solucionen todos los errores, no podemos lanzar un producto o incluso un sprint semanal. Pero tenemos errores de baja prioridad e insignificantes. Para ellos, seleccioné una etiqueta que permite que Robot Framework no deje caer todo el ensamblaje, a menos que específicamente estas pruebas (pruebas con esta etiqueta) fallen.

Gran registro


El análisis de registros es una parte integral de las pruebas. Pase lo que pase en el momento en que se ejecutan las pruebas, Robot Framework escribe absolutamente todo. Hasta el punto en que tuve que escribir un contenedor especial que oculta el inicio de sesión y la contraseña del registro para conectarse a la base de datos.

Tales detalles ayudan a comprender mucho más rápido cuál es la razón del fallo de la prueba: ¿el sistema bajo prueba funciona incorrectamente o hay algo que no se tiene en cuenta en la prueba y debe repararse? La respuesta a esta pregunta no siempre es obvia. Los errores de desarrolladores y probadores se distribuyen 50/50.
En otras herramientas, en el mismo pytest, puede crear el mismo registro detallado. Pero allí la tarea de generarlo recae en el desarrollador que escribe las pruebas. Necesita pensar qué tipo de entradas de registro son realmente necesarias.

¿Qué hay en el proyecto en este momento?


Desde el momento en que comencé a usar Robot Framework, han pasado varios meses. Por el momento, Robot Framework ha implementado más de 200 pruebas y, como se mencionó anteriormente, hay una integración con GitLab, que ayuda a verificar los cambios realizados en el producto desarrollado (los casos de prueba con identificadores que le permiten vincular las pruebas automáticas se almacenan en testrail).

Para calcular la cobertura, escribí una utilidad que toma una lista de API de back-end de Swagger y la compara con lo que se probó. Por lo tanto, tenemos una comprensión clara de la cobertura actual. Por ejemplo, sabemos que hoy este microservicio está cubierto en su totalidad, mientras que el otro está cubierto en un 98%. Y después de agregar una nueva funcionalidad que aún no se refleja en las pruebas, la cobertura cae. En consecuencia, puedes planificar el próximo sprint que implementaré yo.

Naturalmente, el proyecto se está desarrollando aún más. Por ejemplo, ahora estamos implementando un servidor simulado ( mi colega ya escribió en Habré sobre qué es y por qué es necesario).

Ahora a practicar


Los ejemplos anteriores están diseñados específicamente para que el artículo ilustre las ideas anteriores. Si desea experimentar con estos ejemplos usted mismo, todos están publicados en nuestro repositorio .

El ejemplo de prueba más simple.


Comencemos con la prueba más simple en Robot Framework.

En el ejemplo a continuación, primero se crea una sesión en un determinado recurso obviamente accesible (en nuestro caso, en.wikipedia.org/wiki ). Al llamar a Get root (/), verificamos el código de estado 200.

*** Settings *** Documentation  smoke-. Library RequestsLibrary *** Variables *** ${base_url} https://en.wikipedia.org/wiki ${url} / *** Test Cases ***   Wiki Create session conn ${base_url} disable_warnings=1 ${response} Get request conn ${url} Delete all sessions Should be equal ${response.status_code} ${200} 

Pruebas de plantilla (paramétricas)


Robot Framework le permite crear patrones de prueba. Si transferimos la prueba del ejemplo anterior a la vista de plantilla, podemos escalarla fácilmente agregando llamadas con los argumentos necesarios. Por ejemplo, verifiquemos la respuesta 200 para páginas con biografías de científicos.

 *** Settings *** Documentation  smoke-.    . ...    . Library RequestsLibrary Test Setup   Test Teardown    Test Template Smoke- *** Variables *** ${base_url} https://en.wikipedia.org/wiki *** Test Cases ***      /Isaac_Newton      /Albert_Einstein      /Stephen_Hawking *** Keywords ***   Create session conn ${base_url} disable_warnings=1    Delete all sessions Smoke- [Arguments] ${url} ${response} Get request conn ${url} Should be equal ${response.status_code} ${200} 

Etiquetado y lectura de registros


Continuamos mejorando la prueba más simple.

Al tener una plantilla como punto de entrada único, podemos agregar fácilmente la verificación del año de nacimiento del científico. De esta manera, confirmamos que la página cargada muestra los datos correctos.

Además, en el ejemplo a continuación, incluí la palabra clave existente en nombres rusos, para mi gusto, por lo que la prueba se lee más orgánicamente. Como probador, siempre me molestaban los métodos llamados "como en inglés", pero completamente analfabetos. Siempre es mejor escribir en el idioma que conoces.

 *** Settings *** Documentation  smoke-.    . ...    . ...      . ...  . Library RequestsLibrary Test Setup   Test Teardown    Test Template Smoke- *** Variables *** ${base_url} https://en.wikipedia.org/wiki *** Test Cases ***      [Tags] Newton /Isaac_Newton 1642      [Tags] Einstein /Albert_Einstein 1879      [Tags] Hawking /Stephen_Hawking 1942     (  ) [Tags] Numbers /123456789 1899 *** Keywords ***   Create session conn ${base_url} disable_warnings=1    Delete all sessions Smoke- [Arguments] ${url} ${expected_word} ${response} Get request conn ${url} Should be equal ${response.status_code} ${200} ... msg=  GET ${url}    ,   200 .      ${response.text} ${expected_word}      [Arguments] ${text} ${expected_word} Should contain ${text} ${expected_word} msg=    ${expected_word}! 

Presta atención a [Tags] . Puede agregar etiquetas aquí, lo que, como escribí anteriormente, ayudará a evaluar los problemas a nivel de informe. Del mismo modo, Force Tags en el archivo __init __. Robot (consulte el ejemplo en nuestro repositorio ) le permite establecer etiquetas para todas las pruebas en el directorio, incluidas las anidadas. Si el etiquetado se realiza correctamente, sin siquiera leer los nombres de las pruebas en sí y sin arrastrarse a su lógica, podemos suponer con bastante precisión que no funciona en el proyecto de prueba.

Mire el informe sobre el lanzamiento de estas pruebas. Para mayor claridad, agregué una prueba que encontrará un error.

Las estadísticas de informes son su parte más importante.

imagen

En nuestro ejemplo, las pruebas con la etiqueta de numbers no pasaron por completo (tenemos 1 de 1, pero en la vida real habrá, por ejemplo, 17 de 20). Se puede suponer que el problema está en esta página.

Las etiquetas ayudan a ejecutar pruebas de forma selectiva. Para ejecutar todas las pruebas con una etiqueta específica en la línea de lanzamiento, debe especificar:

 --include <tag> 

Incluso las operaciones lógicas con etiquetas son compatibles:

 -- include <tag>AND<tag> 

Por ejemplo, si desea ejecutar solo la prueba de humo para pruebas con la etiqueta de números, debe agregar:

 --include smokeANDnumbers 

Pruebas no criticas


Pasemos a trucos que simplifican enormemente el trabajo.

Después de etiquetar la prueba con etiquetas, puede definir una o más de ellas como "no críticas". Una prueba con dicha etiqueta aún mostrará errores (si los hay), pero al final, estos errores no se interpretarán como "inválidos". Uso esta opción cuando se tomaron en cuenta algunos errores menores, se ingresaron en el rastreador de errores, pero aún no se han solucionado. Sin él, las pruebas automáticas incluidas en CI, al detectar dichos problemas conocidos, no le permitirán armar el proyecto, y esto no siempre es conveniente.

Agregar una nueva prueba:

     (   ) [Tags] Letters Known /abcdefghi 1799 

Al inicio, la etiqueta agregada se define como "no crítica" utilizando la clave:

 --noncritical Known 

Palabra clave en python


Con el siguiente ejemplo, ilustraré cómo agregar mi biblioteca.

Cree una nueva palabra clave "Generar una matriz de números". Su propósito es obvio (para esto me encantan los nombres rusos).

 from random import randint from typing import List from robot.api.deco import keyword class ArrayGeneratorLibrary: ROBOT_LIBRARY_SCOPE = 'GLOBAL' @keyword("  ") def generate_array(self, length: int, minimal: int, maximal: int) -> List[int]: result = [] for i in range(int(length)): result.append(randint(int(minimal), int(maximal))) return result 

Conectamos la biblioteca en la prueba:

 Library libraries.ArrayGeneratorLibrary 

y úsalo:

   ,   python. ${array}    ${5} ${2} ${8} Log to console ${array} 

No olvide que si tiene una estructura anidada, debe separarla con puntos, como en el ejemplo.
Otro truco: ¡los números pasados ​​en ${} se tratan como int, no como cadenas!

Argumentos en línea


Otra cosa agradable son los argumentos integrados, que no se pasan al final de la llamada, como de costumbre, sino directamente en su cuerpo.

Para ilustrar, escribiremos un contenedor para el generador de matriz creado anteriormente, que permite utilizar los argumentos integrados:

  ${n} ,  ${from}  ${to} ${result}    ${n} ${from} ${to} [Return] ${result} 

Ahora puedes escribir así:

       . ${array}  5 ,  2  8 Log to console ${array} 

Sustitución de parte del nombre del método, inserción de python y bucles


El siguiente truco que realmente me gusta de Robot Framework es la sustitución de parte del nombre. Supongamos que tenemos dos métodos: uno selecciona números pares, el otro impar.

      [Arguments] ${list} ${evens} Evaluate [i for i in $list if i % 2 == 0] [Return] ${evens}      [Arguments] ${list} ${odds} Evaluate [i for i in $list if i % 2 != 0] [Return] ${odds} 

La palabra clave Evaluate utilizada anteriormente le permite ejecutar una línea de código de Python "aquí mismo". Tenga en cuenta que si no desea reemplazar un trozo de la cadena con el contenido de la variable, es decir, pasarle un enlace, debe indicar el nombre de la variable inmediatamente después del signo $ sin llaves.

Y así, puede llamar a ambos métodos, reemplazando la parte diferente de su nombre:

     ,   . . ${types} Create list   ${array}  5 ,  12  28 FOR ${type} IN @{types} ${numbers} Run keyword  ${type}    ${array} log to console ${numbers} END 

Método decoradores


Sí, Robot Framework le permite escribir un decorador para otras palabras clave.

Para ilustrar esta característica, escribimos un decorador que selecciona números negativos en la respuesta de cualquier método que devuelva una lista.

     ,  [Arguments] ${keyword} @{args} &{kwargs} ${list} Run keyword ${keyword} @{args} &{kwargs} ${negs} Evaluate [i for i in $list if i < 0] [Return] ${negs} 

Por favor tenga en cuenta:
@{args} son todos argumentos sin nombre;
&{kwargs} son todos argumentos con nombre.
Con este grupo, puedes redirigirlos, creando un decorador.
Trabajar con el decorador se verá así:

    ${negs}     ,     10 -5 5 log to console ${negs} 

En lugar de una conclusión


En los ejemplos anteriores, mostré las características principales de Robot Framework, que hacen la vida mucho más fácil. Pero sus fichas no se limitan a esta lista.

Si tiene alguna pregunta, escriba los comentarios. Seleccionaremos la dirección principal de interés de lectura y contestaremos las preguntas con una continuación del texto.

El autor del artículo: Vladimir Vasyaev.

PD: publicamos nuestros artículos en varios sitios de Runet. Suscríbase a nuestras páginas en VK , FB o Telegram-channel para conocer todas nuestras publicaciones y otras noticias de Maxilect.

Source: https://habr.com/ru/post/470924/


All Articles