Tengo un controlador lamba que usa una variable de entorno. ¿Cómo puedo establecer ese valor usando pytest? me sale el error
tests/test_kinesis.py:3: in <module> from runner import kinesis runner/kinesis.py:6: in <module> DATA_ENGINEERING_BUCKET = os.environ["BUCKET"] ../../../../../.pyenv/versions/3.8.8/lib/python3.8/os.py:675: in __getitem__ raise KeyError(key) from None E KeyError: 'BUCKET' 7:03Intenté configurar la prueba de esta manera
class TestHandler(unittest.TestCase): @mock_s3 @mock_lambda def test_handler(monkeypatch): monkeypatch.setenv("BUCKET", "test-bucket") actual = kinesis.handler(kinesis_stream_event, "") expected = {"statusCode": 200, "body": "OK"} assert actual == expected DATA_ENGINEERING_BUCKET = os.environ["BUCKET"] def handler(event, context): ...Obtendrá la falla antes de que su parche de mono pueda ejecutarse. La carga de la variable de entorno ocurrirá cuando el módulo del corredor se importe por primera vez.
Si este es un módulo de su propiedad, recomendaría modificar el código para usar un valor predeterminado si DATA_ENGINEERING_BUCKET no está configurado. Luego, puede modificar su valor a lo que desee en tiempo de ejecución llamando a module.DATA_ENGINEERING_BUCKET = "my_bucket" .
DATA_ENGINEERING_BUCKET = os.environ.get("BUCKET", default="default_bucket")Investigué la creación de un dispositivo global que corrige el entorno y carga el módulo una vez, antes de que se carguen las pruebas, y recibí un error de pytest sobre el uso de dispositivos de nivel de función dentro de un dispositivo de nivel de sesión. Lo cual tiene sentido. Monkeypatch realmente no pretende falsificar cosas a largo plazo. Puede colocar la carga del módulo en su prueba después del parche mono, pero eso generará una gran cantidad de repeticiones.
Lo que eventualmente funcionó creando un accesorio que proporcionará la clase en lugar de importarla. El accesorio; establece os.environ al valor deseado, carga el módulo, restablece os.environ a su valor original y luego genera el módulo. Cualquier prueba que necesite este módulo puede solicitar el accesorio para tener acceso a él dentro de su alcance. Una palabra de precaución, porque los archivos de prueba se importan antes de que se ejecuten los accesorios. Cualquier archivo de prueba que no use el accesorio e importe el módulo normalmente generará un KeyError y hará que pytest se bloquee antes de ejecutar cualquier prueba.
import os, pytest @pytest.fixture(scope='session') def kinesis(): old_environ = os.environ os.environ = {'BUCKET': 'test-bucket'} import kinesis os.environ = old_environ yield kinesis # Do NOT import kinesis in any test file. Rely on the fixture. class TestHandler(unittest.TestCase): @mock_s3 @mock_lambda def test_handler(kinesis): actual = kinesis.handler(kinesis_stream_event, "") expected = {"statusCode": 200, "body": "OK"} assert actual == expected os.environ es un diccionario de variables de entorno que se crea cuando os se carga por primera vez. Si desea un valor único para cada prueba, solo necesita agregar el valor que desea antes de cargar cualquier módulo de prueba. Si coloca os.environ['BUCKET'] = 'test-bucket' en la parte superior de conftest.py, configurará la variable de entorno para el resto de la sesión de prueba. Luego, siempre que la primera importación del módulo ocurra después, no tendrá un error clave. La gran desventaja de este enfoque es que, a menos que sepa buscar en conftest.py o grep el código, será difícil determinar dónde se establece la variable de entorno al solucionar problemas.