英文:
Fixture found but not called
问题
我正在使用pyrogram来模拟输入,测试python-telegram-bot中的一个机器人。我必须在环境中设置一个加密密钥,以便被测试的代码可以访问它。我尝试使用pytest.fixtures中的setup-teardown概念来实现这一点。
为此,我创建了一个文件,其中包含我创建的所有fixtures,其中一个fixture被设置为@ pytest.fixture(autouse=True, scope="session")。
这个fixture已被找到,但没有执行。为什么?
文件结构:
--root
|-tests/
|- conftest.py
|- test_something1.py
|- test_something2.py
我从根文件夹执行pytest -s --fixtures
命令。
以下是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
以下是'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()
当我运行pytest -s --fixtures
测试时,我收到以下错误信息:
------------------------------------------------------------- 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 =======================================================================
请注意,尽管我在命令中使用了-s
参数,但我的print()
未出现。
我正在使用的库:
pytest==7.2.1
pytest-asyncio==0.20.3
Python版本为3.8.10
以下是命令输出的前几行,希望它们对你有所帮助:
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
英文:
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
答案1
得分: 1
错误消息中包含的部分与您提供的代码片段不完全匹配,因此很难确定失败的确切原因。
例如,如果我们看一下您提供的confest.py
片段,它肯定会失败,但会引发不同的异常 - NameError
,因为它无法解析名称CRYPT_KEY_EDK
或CRYPT_KEY
的值。
其次,错误消息提到了一个文件test_can_access_netbox.py
,但我们在这里看不到这个文件。
话虽如此,这里是一个简单的示例,展示如何使用 fixture 来设置环境变量:
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[constants.CRYPT_KEY_EDK] = constants.CRYPT_KEY
请注意,上述代码中已将constants.CRYPT_KEY_EDK
和constants.CRYPT_KEY
引用为常量,以避免NameError
异常。
英文:
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
答案2
得分: 0
好的,我明白了(感谢 willcode.io 要求测试文件):
在我的测试文件中,有一些不在任何函数内的代码行。问题是:它们在 pytest 尝试获取所有测试时被执行。但这些行在夹具之后需要被执行。
解决方案:由于这些悬浮行在进行一些设置过程,我只是将它们插入到一个夹具中,现在一切都正常工作。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论