使用会话范围的夹具作为变量
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 ================================================================================================
之后我们可以确认 commit
和 delete
方法都被调用了:
$ ls
commit_was_called
delete_was_called
test_user.py
user.py
我在 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 ================================================================================================
之后我们可以确认 commit
和 delete
方法都被调用了:
$ ls
commit_was_called
delete_was_called
test_user.py
user.py