Función simulada en Python

Migel Hewage Nimesha 15 febrero 2024
  1. Configurar e instalar Pytest Mock en Python
  2. Simular una función en Python
  3. Conclusión
Función simulada en Python

La función unittest.mock o Mock es una biblioteca para pruebas en Python que le permite reemplazar componentes de su sistema bajo prueba con objetos mock y hacer afirmaciones sobre cómo se han utilizado las partes.

El unittest.mock brinda una clase central Mock, eliminando la necesidad de crear una gran cantidad de stubs en todo su conjunto de pruebas.

Después de ejecutar un proceso, puede afirmar qué métodos o atributos se usaron y los argumentos con los que se llamaron. También puede especificar los valores de retorno y establecer los atributos necesarios de la forma habitual.

Además, Mock proporciona un decorador patch() que puede manejar el módulo de aplicación de parches y los atributos de nivel de clase dentro del alcance de la prueba, junto con un asistente centinela, para crear objetos únicos.

Mock se creó para usar con unittest y se basa en el patrón acción a afirmación en lugar de grabación a reproducción, que se usa en la mayoría de los marcos de simulación. Hay un backport de unittest.mock para versiones anteriores de Python.

Configurar e instalar Pytest Mock en Python

A diferencia de unittest, pytest no es un paquete integrado de Python y necesita instalación. Esto se puede instalar ingresando el siguiente comando en la terminal.

pip install pytest

Como nota, las mejores prácticas para unittest también se aplican a pytest, de modo que:

  1. Se requiere un directorio tests/ para contener todas las pruebas unitarias.
  2. Los nombres de los archivos siempre deben comenzar con tests_.
  3. Los nombres de las funciones siempre deben comenzar con la prueba.

Se deben observar los estándares de nomenclatura para que el verificador pueda encontrar las pruebas unitarias realizadas.

Es necesario instalar pytest-mock antes de poder usarlo. A continuación se muestra cómo instalarlo usando pip:

pip install pytest-mock

Este es un complemento para Pytest. Por lo tanto, si aún no lo ha hecho, instalará Pytest.

Simular una función en Python

Para comenzar, crea una función simple get_os() para decirnos si estamos usando Windows o Linux como sistema operativo.

Cree un archivo llamado app.py de la siguiente manera:

from time import sleep


def isWindows():
    # This sleep can be some complex operation
    sleep(5)
    return True


def get_os():
    return "Windows is the current OS" if isWindows() else "Linux is the current OS"

Esta función utiliza la función isWindows para determinar si el sistema operativo actual es Windows o no. Suponiendo que esta función isWindows es bastante compleja y tarda varios segundos en ejecutarse, aquí podemos simular esta función lenta poniendo el programa en suspensión durante 5 segundos cada vez que se llama.

Lo siguiente sería un pytest para la función get_os():

Cree un archivo llamado test_app.py a pytest:

from app import get_os


def test_get_os():
    assert get_os() == "Windows is the current OS"

Dado que get_os() llama a una función más lenta isWindows, la prueba continúa siendo lenta. Esto se puede ver en el siguiente resultado de la ejecución de pytest.

Tardó 5,02 segundos y puede variar según la instancia actual.

función simulada python - salida 1

Las pruebas unitarias deben ser rápidas y deberíamos poder realizar cientos de pruebas en cuestión de segundos. El conjunto de pruebas se ralentiza con una sola prueba que tarda 5 segundos, por lo que aplicar burlas nos facilita la vida.

Si parcheamos la función lenta, podemos verificar el comportamiento de la función get_os() sin esperar 5 segundos.

Simulamos esta función con pytest-mock.

Pytest-mock proporciona un accesorio llamado mocker y una excelente interfaz además de las construcciones de simulación integradas de Python. Puede emplear un simulador invocando las funciones de simulación y parche y enviándolos como argumentos a su función de prueba.

En caso de que desee que la función isWindows devuelva True sin esperar esos preciados 5 segundos, podemos parchearlo de la siguiente manera:

mocker.patch("app.isWindows", return_value=True)

Aquí, debe referirse a isWindows como app.isWindows, dado que es la función en el módulo app. Si solo parcheamos isWindows, intentará parchear una función llamada isWindows en el archivo test_app, que no existe.

El formato siempre es <nombre_módulo>.<nombre_función>, y saber cómo simular correctamente es fundamental.

A continuación se describe la función de prueba modificada después del parche:

from app import get_os

# using'mocker' fixture provided by pytest-mock


def test_get_os(mocker):
    # mocking the slow-going function and returning True always
    mocker.patch("app.isWindows", return_value=True)
    assert get_os() == "Windows is the current OS"

Ahora, esta prueba terminará mucho más rápido cuando la ejecutes.

función simulada python - salida 2

Como puede ver, la prueba tomó solo 0,02 segundos, por lo que hemos parcheado con éxito la función lenta y acelerado el conjunto de pruebas.

Otra ventaja de la simulación es que puede hacer que la función de simulación devuelva cualquier cosa e incluso puede generar errores para probar cómo se procesa su código en esos escenarios.

Aquí, si desea probar el caso en el que isWindows devuelve False, escriba la siguiente prueba:

from app import get_os


def test_os_isLinux(mocker):
    mocker.patch(
        "app.isWindows", return_value=False
    )  # set the return value to be False
    assert get_os() == "Linux is the current OS"

Los simulacros y parches que vienen con el simulador tienen un ámbito de función, lo que significa que solo se pueden usar con esa función en particular. Como resultado, no habrá conflictos entre parches para la misma función en diferentes pruebas.

Conclusión

La simulación es la práctica de reemplazar el componente de la aplicación que está probando con un simulacro, que es una implementación ficticia de ese componente. A través de la simulación, podemos obtener beneficios como una mayor velocidad, donde las pruebas que se ejecutan más rápido son muy beneficiosas, evitando efectos secundarios no deseados durante las pruebas, etc.

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.

Artículo relacionado - Python Mock