访问autouse fixture而不必将其添加到method参数中

tri*_*iji 8 pytest python-3.x

我在conftest.py中有一个会话范围的夹具

@pytest.fixture(scope="session",autouse=True)
def log(request):
    testlog = LogUtil(testconf.LOG_NAME).get()
    return testlog
Run Code Online (Sandbox Code Playgroud)

当mytest.py中定义了测试方法时,这将加载并按预期工作,如下所示:

def test_hello_world(self, log):
        log.info("hello world test")
Run Code Online (Sandbox Code Playgroud)

有没有办法使用夹具(因为它启用了autouse),而无需在测试方法中添加额外的"log"参数?

def test_hello_world(self):
        log.info("hello world test") #log is not found

@pytest.mark.usefixtures("log")
def test_hello_world2(self):
        log.info("hello world test") #log is not found

def test_hello_world3(self,log):
        log.info("hello world test") #log object is accessible here
Run Code Online (Sandbox Code Playgroud)

错误 - NameError:未定义名称"log"

The*_*ler 8

当您只想将自动夹具用于设置/拆卸时,您通常会使用它们。

如果您需要访问夹具返回的对象,则需要像在第一个示例中一样将其指定为参数。

  • 我想象这个工作的唯一方法是通过 pytest 将全局变量注入到模块中并在每次测试之间更改它们......这听起来很痛苦,并且可能会因并行测试(`pytest-xdist`)而中断,而且很可能其他一些场景。 (3认同)
  • 感谢您的回复。当测试数量开始增长时,为每个测试添加参数就变得很麻烦。现在的选项似乎是:1)创建一个全局变量并使用conftest.py中定义的固定装置更新它2)使用静态变量创建一个基类(不需要固定装置) (2认同)
  • **我完全同意 [tj23](/sf/users/87994581/)。** 无法实际访问通过`autouse` 或`usefixtures` 隐式声明的fixture 使得这些fixture 对大多数人来说毫无用处目的 - 就我而言,_所有_目的。通常的替代方法是 **(A)** 定义一个需要多个真实装置的抽象装置,然后 **(B)** 有测试需要前者而不是后者。然而,就我而言,夹具作用域约束禁止这样做。_啊!_ (2认同)
  • 我不同意 - 就我个人而言,我也经常使用固定装置来简单地进行一些设置/拆卸(例如修补),并且实际上不需要访问它。您能详细说明为什么您需要*多个*真实的固定装置和一个抽象的固定装置吗?您的用例是什么?也许我们应该将其带到[pytest跟踪器](https://github.com/pytest-dev/pytest/issues)。 (2认同)

Joh*_*Mee 8

您的日志功能不是固定装置。像任何其他库例程一样对待它。例如:将其添加到公共模块并根据需要导入。

common.py

import logging
import os

logger = logging.getLogger()
project_id = os.getenv('PROJECT_ID', 'maris-baccus')
Run Code Online (Sandbox Code Playgroud)

test_stuff.py

from common import logger, project_id

def test_this():
    logger.info(f'This is the {project_id}')
Run Code Online (Sandbox Code Playgroud)