python fixtures py.test

python - py.test: pasar un parámetro a una función de fijación



fixtures (3)

Estoy usando py.test para probar algunos códigos DLL incluidos en una clase Python MyTester. Para validar el propósito, necesito registrar algunos datos de prueba durante las pruebas y luego hacer más procesamiento. Como tengo muchos archivos de prueba ... quiero reutilizar la creación del objeto del comprobador (instancia de MyTester) para la mayoría de mis pruebas.

Como el objeto del comprobador es el que obtuvo las referencias a las variables y funciones de la DLL, necesito pasar una lista de las variables de la DLL al objeto probador para cada uno de los archivos de prueba (las variables que se registrarán son las mismas para una prueba). . archivo). El contenido de la lista se utilizará para registrar los datos especificados.

Mi idea es hacerlo de alguna manera así:

import pytest class MyTester(): def __init__(self, arg = ["var0", "var1"]): self.arg = arg # self.use_arg_to_init_logging_part() def dothis(self): print "this" def dothat(self): print "that" # located in conftest.py (because other test will reuse it) @pytest.fixture() def tester(request): """ create tester object """ # how to use the list below for arg? _tester = MyTester() return _tester # located in test_...py # @pytest.mark.usefixtures("tester") class TestIt(): # def __init__(self): # self.args_for_tester = ["var1", "var2"] # # how to pass this list to the tester fixture? def test_tc1(self, tester): tester.dothis() assert 0 # for demo purpose def test_tc2(self, tester): tester.dothat() assert 0 # for demo purpose

¿Es posible lograrlo así o incluso hay una manera más elegante?

Por lo general, podría hacerlo para cada método de prueba con algún tipo de función de configuración (xUnit-style). Pero quiero ganar algún tipo de reutilización. ¿Alguien sabe si esto es posible con los accesorios en absoluto?

Sé que puedo hacer algo como esto: (de los documentos)

@pytest.fixture(scope="module", params=["merlinux.eu", "mail.python.org"])

Pero necesito la parametrización directamente en el módulo de prueba. ¿Es posible acceder al atributo params del dispositivo desde el módulo de prueba?


Esto es realmente compatible de forma nativa en py.test a través de parametrización indirecta .

En tu caso, tendrías:

@pytest.fixture def tester(request): """Create tester object""" return MyTester(request.param) class TestIt: @pytest.mark.parametrize(''tester'', [[''var1'', ''var2'']], indirect=True) def test_tc1(self, tester): tester.dothis() assert 1



Tuve un problema similar: tengo un dispositivo llamado test_package , y luego quise poder pasar un argumento opcional a ese dispositivo cuando lo ejecutaba en pruebas específicas. Por ejemplo:

@pytest.fixture() def test_package(request, version=''1.0''): ... request.addfinalizer(fin) ... return package

(No importa para estos propósitos lo que hace el dispositivo o qué tipo de objeto es el package devuelto).

Entonces sería deseable utilizar de algún modo este dispositivo en una función de prueba de tal manera que también pueda especificar el argumento de version para ese dispositivo para usar con esa prueba. Esto actualmente no es posible, aunque podría ser una buena característica.

Mientras tanto, fue bastante fácil hacer que mi dispositivo simplemente devolviera una función que hace todo el trabajo que el accesorio hacía anteriormente, pero me permite especificar el argumento de la version :

@pytest.fixture() def test_package(request): def make_test_package(version=''1.0''): ... request.addfinalizer(fin) ... return test_package return make_test_package

Ahora puedo usar esto en mi función de prueba como:

def test_install_package(test_package): package = test_package(version=''1.1'') ... assert ...

y así.

La solución intentada por el OP se dirigió en la dirección correcta, y como lo sugiere la answer @ hpk42, el MyTester.__init__ podría simplemente almacenar una referencia a la solicitud como:

class MyTester(object): def __init__(self, request, arg=["var0", "var1"]): self.request = request self.arg = arg # self.use_arg_to_init_logging_part() def dothis(self): print "this" def dothat(self): print "that"

Luego, usa esto para implementar el accesorio como:

@pytest.fixture() def tester(request): """ create tester object """ # how to use the list below for arg? _tester = MyTester(request) return _tester

Si lo desea, la clase MyTester podría reestructurarse un poco para que su atributo .args pueda actualizarse después de que se haya creado, para modificar el comportamiento de las pruebas individuales.