python unit-testing py.test

python - Cree e importe funciones de ayuda en las pruebas sin crear paquetes en el directorio de prueba usando py.test



unit-testing (6)

Pregunta

¿Cómo puedo importar funciones de ayuda en archivos de prueba sin crear paquetes en el directorio de test ?


Contexto

Me gustaría crear una función auxiliar de prueba que pueda importar en varias pruebas. Oye, algo como esto:

# In common_file.py def assert_a_general_property_between(x, y): # test a specific relationship between x and y assert ... # In test/my_test.py def test_something_with(x): some_value = some_function_of_(x) assert_a_general_property_between(x, some_value)

Usando Python 3.5, con py.test 2.8.2


Solución actual"

Actualmente estoy haciendo esto importando un módulo dentro del directorio de test mi proyecto (que ahora es un paquete), pero me gustaría hacerlo con algún otro mecanismo si es posible (para que mi directorio de test no tenga paquetes, sino solo pruebas, y las pruebas se pueden ejecutar en una versión instalada del paquete, como se recomienda aquí en la documentación de py.test sobre buenas prácticas ).


Como otra opción, esta estructura de directorio funcionó para mí:

mypkg/ ... test_helpers/ __init__.py utils.py ... tests/ my_test.py ...

Y luego, en my_test.py importe las utilidades usando: from test_helpers import utils


Cree un paquete de ayudantes en la carpeta de pruebas: tests/ helpers/ __init__.py utils.py ... # make sure no __init__.py in here! setup.cfg tests/ helpers/ __init__.py utils.py ... # make sure no __init__.py in here! setup.cfg

en setup.cfg: [pytest] norecursedirs=tests/helpers

Los ayudantes estarán disponibles con import helpers .


Mi opción es crear un directorio adicional en el directorio de tests y agregarlo a pythonpath en el conftest.

tests/ helpers/ utils.py ... conftest.py setup.cfg

en el conftest.py

import sys import os sys.path.append(os.path.join(os.path.dirname(__file__), ''helpers''))

en setup.cfg

[pytest] norecursedirs=tests/helpers

este módulo estará disponible con `import utils '', solo tenga cuidado de poner nombres.


Mientras buscaba una solución para este problema, encontré esta pregunta de SO y terminé adoptando el mismo enfoque. Creando un paquete de ayudantes, munging sys.path para hacerlo importable y luego importándolo ...

Este no parecía el mejor enfoque, así que creé pytest-helpers-namespace . Este complemento le permite registrar funciones de ayuda en su conftest.py :

import pytest pytest_plugins = [''helpers_namespace''] @pytest.helpers.register def my_custom_assert_helper(blah): assert blah # One can even specify a custom name for the helper @pytest.helpers.register(name=''assertme'') def my_custom_assert_helper_2(blah): assert blah # And even namespace helpers @pytest.helpers.asserts.register(name=''me'') def my_custom_assert_helper_3(blah): assert blah

Y luego, dentro de un cuerpo de función de caso de prueba, utilícelo como

def test_this(): assert pytest.helpers.my_custom_assert_helper(blah) def test_this_2(): assert pytest.helpers.assertme(blah) def test_this_3(): assert pytest.helpers.asserts.me(blah)

Es bastante simple y la documentación bastante pequeña. Echa un vistazo y dime si aborda tu problema también.


Para acceder a un método desde diferentes módulos sin crear paquetes, y hacer que esa función funcione como una función auxiliar, encontré útil lo siguiente:

conftest.py:

@pytest.fixture def compare_test_vs_actual(): def a_function(test, actual): print(test, actual) return a_function

test_file.py:

def test_service_command_add(compare_test_vs_actual): compare_test_vs_actual("hello", "world")


Podría definir una clase auxiliar en conftest.py, luego crear un elemento que devuelva esa clase (o una instancia de ella, dependiendo de lo que necesite).

import pytest class Helpers: @staticmethod def help_me(): return "no" @pytest.fixture def helpers(): return Helpers

Luego, en tus pruebas, puedes usar el accesorio:

def test_with_help(helpers): helpers.help_me()