如何让两个发布的固定装置相互依赖?
How to have two issued fixtures depend on each other?
在 test_something()
中,app
实例应与 login
实例使用的实例相同。
@pytest.fixture
def app():
# ...
return app
@pytest.fixture
def login(app):
# ...
return login
def test_something(self, app, login):
pass
我尝试的是从第二个固定装置返回两个对象,但我不认为这是惯用的。
@pytest.fixture
def app_and_login(app):
# ...
return app, login
def test_something(self, app_and_login):
app, login = login_and_login
有更好的方法吗?
我没想到会这样,但这似乎是默认行为。不过,我找不到任何关于此的文档。感谢提示。
你可以return它作为对象,并使用第三个夹具:
import pytest
from collections import namedtuple
Auth = namedtuple('Auth', 'app, login')
@pytest.fixture
def app():
return 'APP'
@pytest.fixture
def login(app):
return 'Login at %s' % app
@pytest.fixture
def auth(app, login):
return Auth(app, login)
def test_something(auth):
assert auth.app in auth.login
如您所述,默认情况下,夹具已经 共享用于测试运行时。
这在任何地方都没有明确记录(或者至少我还没有找到它),但它有点隐含:Sharing a fixture across tests in a module 描述了 scope
参数,默认范围是 function
.
其他范围例如是 module
(share/cache 同一模块中所有测试的夹具)或 session
(为整个测试会话缓存夹具)。
我知道这个问题很老,但我没有看到你描述的行为,我真的被这个问答分心了,直到我想,“它不能以这种方式工作......”并为自己进行了测试。我试过这个:
platform darwin -- Python 3.7.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 -- .../bin/python3
我做了这个测试,它通过了:
import collections
import pytest
AppObject = collections.namedtuple("App", ["name", "login"])
@pytest.fixture
def app():
app = AppObject("appname", "applogin")
return app
@pytest.fixture
def login(app):
return app.login
def test_something(app, login):
assert isinstance(app, AppObject) and app.name == "appname"
assert isinstance(login, str) and login == "applogin"
OP 似乎担心 login
fixture 接收的 app
对象与 app fixture 返回的 app
不同。我不认为会发生这种情况。例如,如果您添加一些有用的 print
语句,如下所示:
import collections
import pytest
AppObject = collections.namedtuple("App", ["name", "login"])
@pytest.fixture
def app():
app = AppObject("appname", "applogin")
print("Object id in app fixture: %d" % id(app))
return app
@pytest.fixture
def login(app):
print("Object id in login fixture: %d" % id(app))
return app.login
def test_something(app, login):
print("Object id in test: %d" % id(app))
assert isinstance(app, AppObject) and app.name == "appname"
assert isinstance(login, str) and login == "applogin"
我看到这个输出:
Object id in app fixture: 4451368624
Object id in login fixture: 4451368624
Object id in test: 4451368624
...所以这三个地方绝对是同一个对象。像这样的嵌套固定装置对我来说“只是工作”,所以我要么错过了你问的问题的要点,要么行为发生了变化,或者......其他。但我想把这个留给那些一起来寻找 nested/dependent 像这样的固定装置的人。
在 test_something()
中,app
实例应与 login
实例使用的实例相同。
@pytest.fixture
def app():
# ...
return app
@pytest.fixture
def login(app):
# ...
return login
def test_something(self, app, login):
pass
我尝试的是从第二个固定装置返回两个对象,但我不认为这是惯用的。
@pytest.fixture
def app_and_login(app):
# ...
return app, login
def test_something(self, app_and_login):
app, login = login_and_login
有更好的方法吗?
我没想到会这样,但这似乎是默认行为。不过,我找不到任何关于此的文档。感谢提示。
你可以return它作为对象,并使用第三个夹具:
import pytest
from collections import namedtuple
Auth = namedtuple('Auth', 'app, login')
@pytest.fixture
def app():
return 'APP'
@pytest.fixture
def login(app):
return 'Login at %s' % app
@pytest.fixture
def auth(app, login):
return Auth(app, login)
def test_something(auth):
assert auth.app in auth.login
如您所述,默认情况下,夹具已经 共享用于测试运行时。
这在任何地方都没有明确记录(或者至少我还没有找到它),但它有点隐含:Sharing a fixture across tests in a module 描述了 scope
参数,默认范围是 function
.
其他范围例如是 module
(share/cache 同一模块中所有测试的夹具)或 session
(为整个测试会话缓存夹具)。
我知道这个问题很老,但我没有看到你描述的行为,我真的被这个问答分心了,直到我想,“它不能以这种方式工作......”并为自己进行了测试。我试过这个:
platform darwin -- Python 3.7.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 -- .../bin/python3
我做了这个测试,它通过了:
import collections
import pytest
AppObject = collections.namedtuple("App", ["name", "login"])
@pytest.fixture
def app():
app = AppObject("appname", "applogin")
return app
@pytest.fixture
def login(app):
return app.login
def test_something(app, login):
assert isinstance(app, AppObject) and app.name == "appname"
assert isinstance(login, str) and login == "applogin"
OP 似乎担心 login
fixture 接收的 app
对象与 app fixture 返回的 app
不同。我不认为会发生这种情况。例如,如果您添加一些有用的 print
语句,如下所示:
import collections
import pytest
AppObject = collections.namedtuple("App", ["name", "login"])
@pytest.fixture
def app():
app = AppObject("appname", "applogin")
print("Object id in app fixture: %d" % id(app))
return app
@pytest.fixture
def login(app):
print("Object id in login fixture: %d" % id(app))
return app.login
def test_something(app, login):
print("Object id in test: %d" % id(app))
assert isinstance(app, AppObject) and app.name == "appname"
assert isinstance(login, str) and login == "applogin"
我看到这个输出:
Object id in app fixture: 4451368624
Object id in login fixture: 4451368624
Object id in test: 4451368624
...所以这三个地方绝对是同一个对象。像这样的嵌套固定装置对我来说“只是工作”,所以我要么错过了你问的问题的要点,要么行为发生了变化,或者......其他。但我想把这个留给那些一起来寻找 nested/dependent 像这样的固定装置的人。