使用间接参数化时,`fixture` 中的 `scope` 和 `parametrize` 中的 `scope` 之间的区别
Difference between `scope` in `fixture` and `scope` in `parametrize` when using indirect parametrization
我想使用间接参数化,如 this answer and in pytest documentation 所示。
我希望能够设置范围,以便能够配置夹具是针对每个函数 运行 还是针对其中的许多函数一次。
但是我看到我可以在 fixture
装饰器上设置范围:
import pytest
@pytest.fixture(scope="function")
def fixt(request):
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True)
def test_indirect(fixt):
assert len(fixt) == 3
或在 parametrize
装饰器上:
import pytest
@pytest.fixture
def fixt(request):
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope="function")
def test_indirect(fixt):
assert len(fixt) == 3
或者两者同时进行:
import pytest
@pytest.fixture(scope="function")
def fixt(request):
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope="function")
def test_indirect(fixt):
assert len(fixt) == 3
有什么区别,我应该在什么时候设置它们?
更新:
我测试了每一个,看看它们有何不同。
我用来测试的代码:
import pytest
scope_fixture="function"
scope_parametrize="module"
with open('scope_log.txt', 'a') as file:
file.write(f'--------\n')
file.write(f'{scope_fixture=}\n')
file.write(f'{scope_parametrize=}\n')
@pytest.fixture(scope=scope_fixture)
def fixt(request):
with open('scope_log.txt', 'a') as file:
file.write(f'fixture ' + str(request.param)+'\n')
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope=scope_parametrize)
def test_indirect1(fixt):
with open('scope_log.txt', 'a') as file:
file.write(f'1 ' + str(fixt)+'\n')
assert len(fixt) == 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope=scope_parametrize)
def test_indirect2(fixt):
with open('scope_log.txt', 'a') as file:
file.write(f'2 ' + str(fixt)+'\n')
assert len(fixt) == 3
结果:
scope_fixture=None
scope_parametrize=None
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture='function'
scope_parametrize=None
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture='module'
scope_parametrize=None
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture=None
scope_parametrize='function'
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture=None
scope_parametrize='module'
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture='function'
scope_parametrize='module'
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture='module'
scope_parametrize='module'
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture='module'
scope_parametrize='function'
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture='function'
scope_parametrize='function'
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
正如@Tzane 在评论中指出的那样,为 parametrize
设置范围会覆盖 fixtures 中设置的任何范围。
scope (Optional[_ScopeName]) – If specified it denotes the scope of
the parameters. The scope is used for grouping tests by parameter
instances. It will also override any fixture-function defined scope,
allowing to set a dynamic scope using test context or configuration.
我想使用间接参数化,如 this answer and in pytest documentation 所示。
我希望能够设置范围,以便能够配置夹具是针对每个函数 运行 还是针对其中的许多函数一次。
但是我看到我可以在 fixture
装饰器上设置范围:
import pytest
@pytest.fixture(scope="function")
def fixt(request):
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True)
def test_indirect(fixt):
assert len(fixt) == 3
或在 parametrize
装饰器上:
import pytest
@pytest.fixture
def fixt(request):
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope="function")
def test_indirect(fixt):
assert len(fixt) == 3
或者两者同时进行:
import pytest
@pytest.fixture(scope="function")
def fixt(request):
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope="function")
def test_indirect(fixt):
assert len(fixt) == 3
有什么区别,我应该在什么时候设置它们?
更新:
我测试了每一个,看看它们有何不同。
我用来测试的代码:
import pytest
scope_fixture="function"
scope_parametrize="module"
with open('scope_log.txt', 'a') as file:
file.write(f'--------\n')
file.write(f'{scope_fixture=}\n')
file.write(f'{scope_parametrize=}\n')
@pytest.fixture(scope=scope_fixture)
def fixt(request):
with open('scope_log.txt', 'a') as file:
file.write(f'fixture ' + str(request.param)+'\n')
return request.param * 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope=scope_parametrize)
def test_indirect1(fixt):
with open('scope_log.txt', 'a') as file:
file.write(f'1 ' + str(fixt)+'\n')
assert len(fixt) == 3
@pytest.mark.parametrize("fixt", ["a", "b"], indirect=True, scope=scope_parametrize)
def test_indirect2(fixt):
with open('scope_log.txt', 'a') as file:
file.write(f'2 ' + str(fixt)+'\n')
assert len(fixt) == 3
结果:
scope_fixture=None
scope_parametrize=None
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture='function'
scope_parametrize=None
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture='module'
scope_parametrize=None
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture=None
scope_parametrize='function'
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture=None
scope_parametrize='module'
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture='function'
scope_parametrize='module'
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture='module'
scope_parametrize='module'
fixture a
1 aaa
2 aaa
fixture b
1 bbb
2 bbb
--------
scope_fixture='module'
scope_parametrize='function'
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
--------
scope_fixture='function'
scope_parametrize='function'
fixture a
1 aaa
fixture b
1 bbb
fixture a
2 aaa
fixture b
2 bbb
正如@Tzane 在评论中指出的那样,为 parametrize
设置范围会覆盖 fixtures 中设置的任何范围。
scope (Optional[_ScopeName]) – If specified it denotes the scope of the parameters. The scope is used for grouping tests by parameter instances. It will also override any fixture-function defined scope, allowing to set a dynamic scope using test context or configuration.