Se preparó una traducción del artículo específicamente para los estudiantes del curso de Ingeniero de Python QA .
Estamos viviendo en una era en la que el software se está moviendo muy rápidamente al mercado. Debido a esto, el proceso de desarrollo se vuelve muy estresante. Las altas tasas de implementación de software y la entrega rápida parecen una buena parte del modelo de negocio, pero aquí surge la pregunta acerca de cómo entregar software de la calidad adecuada.
¿Por qué necesitamos pruebas automatizadas?
Las pruebas automatizadas tienen muchas ventajas, aquí hay tres principales:
Reutilización: no es necesario escribir nuevos scripts cada vez, incluso cuando se lanza una nueva versión del sistema operativo, a menos que haya una necesidad urgente de ello.
Confiabilidad: las personas tienden a cometer errores, y los autos los hacen menos propensos. Y funcionan más rápido al realizar pasos / pruebas repetidas que deben realizarse continuamente.
Trabajo las 24 horas, los 7 días de la semana: puede comenzar a realizar pruebas en cualquier momento del día, incluso de forma remota. Si comienza a realizar pruebas por la noche, se ejecutará incluso mientras duerme.
Desarrolló una herramienta de prueba pytest con todas las funciones en Python
Actualmente, hay muchos marcos y herramientas para realizar pruebas. Existen diferentes tipos de marcos, por ejemplo, basados en datos, basados en palabras clave, híbridos, BDD, etc. Puede elegir el que mejor se adapte a sus necesidades.
Debo decir que Python y
pytest
ocupan un gran nicho en este asunto. Python y sus herramientas relacionadas son ampliamente utilizadas, probablemente porque son más accesibles para personas con poca experiencia en programación en comparación con otros lenguajes.
El marco
pytest
facilita la escritura de pequeñas pruebas, pero también se escala para admitir pruebas funcionales sofisticadas de aplicaciones y bibliotecas.
Algunas características clave de
pytest
:
- Detección automática de módulos de prueba y funciones;
- CLI eficaz para mejorar el control sobre lo que desea ejecutar u omitir;
- Gran ecosistema de complementos de terceros;
- Accesorios: diferentes tipos, diferentes aplicaciones;
- Trabaje con el marco de prueba de unidad tradicional.
Detección de prueba automática y configurable.
Por defecto,
pytest
espera encontrar pruebas en esos módulos de Python cuyos nombres comienzan con
test_
o terminan con
_test.py
. Además, de forma predeterminada, espera que los nombres de las funciones de prueba comiencen con el prefijo
test_
. Sin embargo, este protocolo de detección de prueba se puede cambiar agregando su propia configuración a uno de los
pytest
configuración de
pytest
.
Veamos una función de prueba muy simple:
class CheckClass(object): def one_check(self): x = "this" assert 'h' in x def two_check(self): x = "hello" assert hasattr(x, 'check')
¿Has notado algo? No hay
assertEqual
o
assertDictEqual
, solo una
assertDictEqual
accesible y comprensible. No es necesario importar estas funciones para simplemente comparar dos objetos. Afirmar es lo que Python ya tiene y no hay necesidad de reinventar la rueda.
Código de plantilla? ¡No te preocupes, los accesorios corren al rescate!
Mire las funciones de prueba que prueban las operaciones básicas en el programa Wallet:
// test_wallet.py from wallet import Wallet def test_default_initial_amount(): wallet = Wallet() assert wallet.balance == 0 wallet.close() def test_setting_initial_amount(): wallet = Wallet(initial_amount=100) assert wallet.balance == 100 wallet.close() def test_wallet_add_cash(): wallet = Wallet(initial_amount=10) wallet.add_cash(amount=90) assert wallet.balance == 100 wallet.close() def test_wallet_spend_cash(): wallet = Wallet(initial_amount=20) wallet.spend_cash(amount=10) assert wallet.balance == 10 wallet.close()
Ejem, interesante! ¿Te has dado cuenta? Hay mucho código repetitivo. Otra cosa que vale la pena señalar es que esta prueba hace algo más además de probar la parte funcional, por ejemplo, crear una billetera y cerrarla con
wallet.close()
.
Ahora echemos un vistazo a cómo puede deshacerse del código repetitivo utilizando los
pytest
pytest.
import pytest from _pytest.fixtures import SubRequest from wallet import Wallet
Bien, ¿no es así? Las funciones de prueba ahora son compactas y hacen exactamente lo que deberían hacer. La billetera se configura, instala y cierra usando el
wallet
. Los accesorios no solo ayudan a escribir código reutilizable, sino que también agregan el concepto de intercambio de datos. Si observa detenidamente, la cantidad en la
wallet
es parte de los datos de prueba proporcionados externamente por la lógica de prueba, y no rígidamente fijados dentro de la función.
@pytest.mark.parametrize('wallet', [(10,)], indirect=True)
En un entorno más controlado, puede tener un archivo con datos de prueba, por ejemplo
test-data.ini
en su repositorio o shell que puede leerlo, mientras que su función de prueba puede llamar a varios shells para leer datos de prueba.
Sin embargo, se recomienda colocar todos los dispositivos en un archivo especial
conftest.py
. Este es un archivo especial en pytest que permite que la prueba detecte dispositivos globales.
¡Pero tengo casos de prueba que quiero ejecutar en diferentes conjuntos de datos!
No se preocupe,
pytest
tiene una característica genial para parametrizar su dispositivo. Veamos un ejemplo.
Supongamos que su producto tiene una CLI que se administra localmente. Además, su producto tiene muchos parámetros predeterminados que se establecen en el inicio, y desea verificar todos los valores de estos parámetros.
Puede pensar en escribir un caso de prueba separado para cada uno de estos parámetros, ¡pero con
pytest
todo es mucho más simple!
@pytest.mark.parametrize(“setting_name, setting_value”, [('qdb_mem_usage', 'low'), ('report_crashes', 'yes'), ('stop_download_on_hang', 'no'), ('stop_download_on_disconnect', 'no'), ('reduce_connections_on_congestion', 'no'), ('global.max_web_users', '1024'), ('global.max_downloads', '5'), ('use_kernel_congestion_detection', 'no'), ('log_type', 'normal'), ('no_signature_check', 'no'), ('disable_xmlrpc', 'no'), ('disable_ntp', 'yes'), ('ssl_mode', 'tls_1_2'),])def test_settings_defaults(self, setting_name, setting_value): assert product_shell.run_command(setting_name) == \ self.”The current value for \'{0}\' is \'{1}\'.”.format(setting_name, setting_value), \ 'The {} default should be {}'.format(preference_name, preference_value)
Genial, ¿no es así? Acaba de escribir 13 casos de prueba (cada uno establece un
setting_value
diferente), y en el futuro, si agrega un nuevo parámetro a su producto, todo lo que necesita hacer es agregar otra tupla.
¿Cómo se integra pytest con las pruebas de interfaz de usuario con las pruebas Selenium y API?
Bueno, su producto puede tener varias interfaces. CLI - como dijimos anteriormente. Similar a la GUI y API. Antes de implementar su producto de software, es importante probarlos todos. En el software empresarial, donde varios componentes están interconectados y dependen unos de otros, un cambio en una parte puede afectar a todas las demás.
Recuerde que
pytest
es solo un marco para pruebas fáciles, no un tipo específico de prueba. Es decir, puede crear pruebas para la GUI utilizando Selenium o, por ejemplo, pruebas para la API con la biblioteca de
requests
de Python y ejecutarlas con
pytest
.
Por ejemplo, en un nivel alto, esto puede ser una verificación de la estructura del repositorio.

Como puede ver en la imagen de arriba, ofrece una buena oportunidad para separar los componentes:
apiobjects : un buen lugar para crear contenedores para llamar a puntos finales API. Puede tener un
BaseAPIObject
y una clase derivada que cumpla con sus requisitos.
ayudantes : puede agregar sus métodos de ayuda aquí.
lib : archivos de biblioteca que pueden ser utilizados por varios componentes, por ejemplo, sus elementos
conftest
en un
conftest
,
pageobjects
, etc.
pageobjects : el
PageObjects
arquitectura
PageObjects se puede usar para crear clases para varias páginas GUI. Usamos
Webium , que es una biblioteca de implementaciones de plantillas de objetos de página para Python.
suites : puede escribir sus propios conjuntos de comprobaciones de pylint para el código, lo ayudarán a ganar más confianza en la calidad de su código.
pruebas : puede catalogar las pruebas según sus preferencias. Esto facilitará la administración y revisión de sus pruebas.
Lo traje solo como referencia, la estructura del repositorio y las dependencias se pueden organizar de acuerdo con sus necesidades personales.
Tengo muchos casos de prueba y quiero que se ejecuten en paralelo
Puede tener muchos casos de prueba en su conjunto, y sucede que necesita ejecutarlos en paralelo y reducir el tiempo total de ejecución de la prueba.
Pytest ofrece un impresionante complemento de ejecución de prueba paralela llamado
pytest-xdist
, que agrega varios modos de ejecución únicos al pytest base. Instala este complemento usando
pip
.
pip install pytest-xdist
Veamos cómo funciona con un ejemplo.
Tengo un repositorio de pruebas automatizadas de CloudApp para mis pruebas de GUI de Selenium. Además, está en constante crecimiento y actualización con nuevas pruebas y ahora tiene cientos de pruebas. Lo que quiero hacer es ejecutarlos en paralelo y reducir el tiempo total de ejecución de la prueba.
En la terminal, simplemente escriba
pytest
en la carpeta raíz del proyecto / carpeta de prueba. Esto le permitirá ejecutar todas las pruebas.
pytest -s -v -n=2

pytest-xdist
ejecutará todas las pruebas en paralelo!
De esta manera, también puede ejecutar múltiples navegadores en paralelo.
Informes
Pytest viene con soporte incorporado para crear archivos de resultados de prueba que se pueden abrir con Jenkins, Bamboo u otros servidores de integración continua. Use lo siguiente:
pytest test/file/path — junitxml=path
Esto ayudará a generar un gran archivo XML que se puede abrir con muchos analizadores.
Conclusión
La popularidad de Pytest está creciendo cada año. Además, tiene un poderoso soporte comunitario, que le permite acceder a muchas extensiones, como
pytest-django , que lo ayudará a escribir pruebas para aplicaciones web en Django. Recuerde que pytest admite casos de prueba unittest, por lo que si usa
unittest
, pytest debe considerarse con más detalle.
Fuentes
Eso es todo. ¡Nos vemos en el
curso !