skip to Main Content

I am testing a bot in python-telegram-bot using pyrogram to simulate inputs. I have to set a cryptography key in my environment so the code being tested can access it. I tried to accomplish this using the setup-teardown concept inside pytest.fixtures.
For that, i created a file where all my fixtures are created, and one of them is set like @pytest.fixture(autouse=True, scope="session")

The fixture is being found, but not executed. Why?

File structure:

--root
   |-tests/
       |- conftest.py
       |- test_something1.py
       |- test_something2.py

I am executing pytest -s --fixtures from the root folder

Here is conftest.py

#  coding:utf-8
import os

import pytest
from pyrogram import Client
from telegram.ext import Application

from config import BOT_ID
from contrib.consts import CRYPT_KEY_EDK
from tests.config import TESTER_USERNAME, API_ID, API_HASH, CRYPT_KEY

@pytest.fixture
async def bot():
    async with Application.builder().token(BOT_ID).build() as bot:
        yield bot


@pytest.fixture
async def pyro_client():
    async with Client(name=TESTER_USERNAME, api_id=API_ID, api_hash=API_HASH) as pyro_client:
        yield pyro_client


@pytest.fixture(autouse=True, scope="session")
def set_crypt_key():
    print("Entered set_crypt_key fixture")
    os.environ[CRYPT_KEY_EDK] = CRYPT_KEY

And here is ‘test_can_access_netbox.py’:

# coding: utf-8
from unittest import mock

import pynetbox
import pytest
import requests
from pynetbox import RequestError
from telegram.ext import ContextTypes

from contrib.consts import NETBOX_CONFIG_CDK
from contrib.datawrappers.netboxconfig import NetboxConfig
from tests.config import NETBOX_TEST_TOKEN, NETBOX_TEST_URL

chat_data_mock = {
    NETBOX_CONFIG_CDK: NetboxConfig(token=NETBOX_TEST_TOKEN, url=NETBOX_TEST_URL)
}


@mock.patch("telegram.ext.ContextTypes.DEFAULT_TYPE", chat_data=chat_data_mock)
def test_can_access_netbox(context: ContextTypes.DEFAULT_TYPE):
    """TC002"""
    try:
        nb = pynetbox.api(**context.chat_data[NETBOX_CONFIG_CDK].to_dict())
        nb.status()
    except RequestError as e:
        pytest.fail("Error requesting connection to Netbox: {}".format(e))
    except requests.exceptions.ConnectionError as e:
        pytest.fail("Connection error: {}".format(e))

if __name__ == '__main__':
    test_can_access_netbox()

And when i run my tests with pytest -s --fixtures, i get this error:

------------------------------------------------------------- fixtures defined from tests.fixtures -------------------------------------------------------------
bot -- tests/fixtures.py:19
pyro_client -- tests/fixtures.py:29
set_crypt_key [session scope] -- tests/fixtures.py:39

============================================================================ ERRORS ============================================================================
_______________________________________________________ ERROR collecting tests/test_can_access_netbox.py _______________________________________________________
tests/test_can_access_netbox.py:16: in <module>
    NETBOX_CONFIG_CDK: NetboxConfig(token=NETBOX_TEST_TOKEN, url=NETBOX_TEST_URL)
contrib/datawrappers/netboxconfig.py:8: in __init__
    super().__init__()
contrib/classesbehaviors/cryptographs.py:13: in __init__
    self.crypt = Fernet(os.environ[CRYPT_KEY_EDK].encode())
/usr/lib/python3.8/os.py:675: in __getitem__
    raise KeyError(key) from None
E   KeyError: 'TELOPS_CRYPT_KEY'
=================================================================== short test summary info ====================================================================
ERROR tests/test_can_access_netbox.py - KeyError: 'TELOPS_CRYPT_KEY'
======================================================================= 1 error in 0.36s =======================================================================

Notice that my print() did not appear, despite of me using -s on command.

Libs i am using:
pytest==7.2.1
pytest-asyncio==0.20.3
Python is 3.8.10
Here are the first lines of the command output, i hope they help:

platform linux -- Python 3.8.10, pytest-7.2.1, pluggy-1.0.0
rootdir: /home/joao/Desktop/enterprise/project_name
plugins: asyncio-0.20.3, anyio-3.6.2
asyncio: mode=strict

2

Answers


  1. Chosen as BEST ANSWER

    Okay, i figured it out (thanks to willcode.io asking for the test file):

    In my test file i had some lines out of any function. The problem was: they were being executed when pytest was trying to fetch all the tests. But these lines needed to be executed after the fixtures.

    Solution: As these floating lines were doing some setup process, i just inserted them into a fixture and everything is working now.


  2. The error messages you pasted don’t quite match the snippets you included, so it is hard to see the precise reason for the failures.

    For example, if we look at the confest.py snippet you included, it will definitely fail, but with a different exception – NameError because it will not be able to resolve the names CRYPT_KEY_EDK or CRYPT_KEY values.

    Secondly the error message talks about a file test_can_access_netbox.py for which we cannot see here.

    This being said, here is a simple example to show how one can use a fixture to set an environment variable:

    constants.py

    CRYPT_KEY_EDK = "CRYPT-KEY-EDK-VALUE"
    CRYPT_KEY = "SOME-CRYPT-KEY-VALUE"
    

    test_fixture_executed.py

    import pytest
    import os
    import constants
    
    @pytest.mark.asyncio
    async def test_env_var_is_present():
        assert constants.CRYPT_KEY_EDK in os.environ
    

    conftest.py

    import pytest
    import os
    import constants
    
    @pytest.fixture(autouse=True, scope="session")
    def set_crypt_key():
        print("Entered set_crypt_key fixture")
        os.environ[CRYPT_KEY_EDK] = CRYPT_KEY
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search