使用会话范围的夹具作为变量

Use Session Scoped Fixture as Variable

我在 pytest 中编写测试并使用固定装置作为变量。
最初,这是固定装置的样子:

@pytest.fixture(scope="class")
def user(request):
    u = "Matt"
    request.cls.u = u
    return u

然后,当我完成它时,还有另一个装置可以从数据库中删除用户。 在测试中,我像这样使用了两个固定装置 @pytest.mark.usefixtures("user", "teardown fixture")
拆解装置是 class scoped,直到我决定将其更改为 session scoped,因为我只想在 运行 完成所有测试后删除用户。
问题是拆解装置突然无法访问用户,因为用户是 class scoped
我将用户更改为会话范围,但是,我现在不确定如何访问或导出它。

@pytest.fixture(scope="session")
def user(request):
    u = "Matt"
    # request.cls.user = u -> WHAT GOES HERE INSTEAD OF THIS?
    return u

用户在测试功能中不再被识别。
测试位于 class 内。当前函数是这样的:

Class TestUser(OtherClassWhichInheritsFromBaseCase):
 def test_user1(self, user1):
        self.open("www.google.com")
        print(user1)

当我尝试 运行 pycharm 中的代码时,出现以下错误:

def _callTestMethod(self, method):
>       method()
E       TypeError: TestUser.test_user1() missing 1 required positional argument: 'user1'

有什么建议吗?

我认为您是从错误的方向来处理这个问题的。如果你需要清理一个夹具,你不需要写第二个夹具;你写你的fixture as a context manager.

例如,您可以这样写:

@pytest.fixture(scope="session")
def user():
    u = User(name="Matt")
    yield u
    # cleanup goes here

在你的测试代码中:

def test_something(user):
  assert user.name == "Matt"

这是一个完整的例子。我们从这个虚拟 user.py 开始,它只是创建文件来演示调用了哪些方法:

from dataclasses import dataclass


@dataclass
class User:
    name: str

    def commit(self):
        open("commit_was_called", "w")

    def delete(self):
        open("delete_was_called", "w")

那么这是我们的测试:


import pytest

import user


@pytest.fixture(scope="session")
def a_user():
    u = user.User(name="testuser")
    u.commit()
    yield u
    u.delete()


class TestUserStuff:
    def test_user(self, a_user):
        assert a_user.name == "testuser"

我们运行是这样的:

$ pytest
=============================================================================================== test session starts ===============================================================================================
platform linux -- Python 3.10.1, pytest-6.2.4, py-1.11.0, pluggy-0.13.1
rootdir: /home/lars/tmp/python
plugins: testinfra-6.5.0
collected 1 item

test_user.py .                                                                                                                                                                                              [100%]

================================================================================================ 1 passed in 0.00s ================================================================================================

之后我们可以确认 commitdelete 方法都被调用了:

$ ls
commit_was_called
delete_was_called
test_user.py
user.py