找到了但未调用的测试装置。

huangapple go评论66阅读模式
英文:

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=&quot;session&quot;)
def set_crypt_key():
    print(&quot;Entered set_crypt_key fixture&quot;)
    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(&quot;telegram.ext.ContextTypes.DEFAULT_TYPE&quot;, chat_data=chat_data_mock)
def test_can_access_netbox(context: ContextTypes.DEFAULT_TYPE):
    &quot;&quot;&quot;TC002&quot;&quot;&quot;
    try:
        nb = pynetbox.api(**context.chat_data[NETBOX_CONFIG_CDK].to_dict())
        nb.status()
    except RequestError as e:
        pytest.fail(&quot;Error requesting connection to Netbox: {}&quot;.format(e))
    except requests.exceptions.ConnectionError as e:
        pytest.fail(&quot;Connection error: {}&quot;.format(e))

if __name__ == &#39;__main__&#39;:
    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 &lt;module&gt;
    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: &#39;TELOPS_CRYPT_KEY&#39;
=================================================================== short test summary info ====================================================================
ERROR tests/test_can_access_netbox.py - KeyError: &#39;TELOPS_CRYPT_KEY&#39;
======================================================================= 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_EDKCRYPT_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_EDKconstants.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 = &quot;CRYPT-KEY-EDK-VALUE&quot;
CRYPT_KEY = &quot;SOME-CRYPT-KEY-VALUE&quot;

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=&quot;session&quot;)
def set_crypt_key():
    print(&quot;Entered set_crypt_key fixture&quot;)
    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.

huangapple
  • 本文由 发表于 2023年2月16日 02:37:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定