Skip to content

Commit abc2afc

Browse files
author
Sylvain MARIE
committed
Added test and comments about #137
1 parent 3bdb1f4 commit abc2afc

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

pytest_cases/plugin.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ def _cleanup_calls_list(metafunc, fix_closure_tree, calls, nodes, pending):
890890
if nb_calls != len(nodes):
891891
raise ValueError("This should not happen !")
892892

893-
# function_scope_num = get_pytest_function_scopenum()
893+
function_scope_num = get_pytest_function_scopenum()
894894

895895
for i in range(nb_calls):
896896
c, n = calls[i], nodes[i]
@@ -921,17 +921,16 @@ def _cleanup_calls_list(metafunc, fix_closure_tree, calls, nodes, pending):
921921
#
922922
# For this we use a dirty hack: we add a parameter with they name in the callspec, it seems to be propagated
923923
# in the `request`. TODO is there a better way?
924-
f_scope = get_pytest_function_scopenum()
925924
for fixture_name in fix_closure_tree.get_not_always_used():
925+
# (a) retrieve fixture scope
926926
try:
927927
fixdef = metafunc._arg2fixturedefs[fixture_name] # noqa
928928
except KeyError:
929929
continue # dont raise any error here and let pytest say "not found"
930-
931930
this_scopenum = fixdef[-1].scopenum
932931

933-
# only do this for function-scoped fixtures, module or session scoped fixtures should remain active
934-
if this_scopenum == f_scope:
932+
# (b) only do this for function-scoped fixtures, module or session scoped fixtures should remain active
933+
if this_scopenum == function_scope_num:
935934
if fixture_name not in c.params and fixture_name not in c.funcargs:
936935
if not n.requires(fixture_name):
937936
# explicitly add it as discarded by creating a parameter value for it.
@@ -944,6 +943,18 @@ def _cleanup_calls_list(metafunc, fix_closure_tree, calls, nodes, pending):
944943
c.indices[fixture_name] = 0
945944
c._arg2scopenum[fixture_name] = this_scopenum # get_pytest_scopenum(fixdef[-1].scope) # noqa
946945

946+
# finally, if there are some session or module-scoped fixtures that
947+
# are used in *none* of the calls, they could be deactivated too
948+
# (see https://github.com/smarie/python-pytest-cases/issues/137)
949+
#
950+
# for fixture_name in fix_closure_tree.get_not_always_used():
951+
# # (a) retrieve fixture scope
952+
# ...
953+
# # (b) for non function-scoped fixtures
954+
# if this_scopenum != function_scope_num:
955+
# # to do check if there is at least one call that actually uses the fixture and is not skipped...
956+
# # this seems a bit "too much" !! > WONT FIX
957+
947958

948959
# def get_calls_for_partition(metafunc, super_closure, p_idx, pending):
949960
# """

pytest_cases/tests/pytest_extension/fixtures/fixture_unions/test_fixture_union_setup_teardown2.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
# + All contributors to <https://github.com/smarie/python-pytest-cases>
33
#
44
# License: 3-clause BSD, <https://github.com/smarie/python-pytest-cases/blob/master/LICENSE>
5+
#
6+
# This is a more complex version of test_fixture_union_setup_teardown3.py
7+
# but the idea is the same: find a configuration in which the "smart reordering" of pytest
8+
# can not group test nodes together, so that we have session- and module-scoped fixtures
9+
# used and not used, alternatively. The objective is to check that they are not called several times
10+
# in spite of them being used/not used alternatively in test nodes.
11+
#
512
from collections import defaultdict
613

714
from pytest_cases import fixture, fixture_union, parametrize
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Authors: Sylvain MARIE <[email protected]>
2+
# + All contributors to <https://github.com/smarie/python-pytest-cases>
3+
#
4+
# License: 3-clause BSD, <https://github.com/smarie/python-pytest-cases/blob/master/LICENSE>
5+
#
6+
# In this test we make sure that a session-scoped fixture is setup only once even if it is
7+
# not used in all test nodes because one parametrized test (TestFoo.test_b) requires a fixture union where
8+
# it is not always used.
9+
from pytest_cases import fixture, fixture_ref, parametrize
10+
11+
fa_used = False
12+
13+
14+
@fixture(scope='session')
15+
def fa(request):
16+
global fa_used
17+
assert not fa_used
18+
fa_used = True
19+
return
20+
21+
22+
@fixture(scope='session')
23+
def fb():
24+
return
25+
26+
27+
class TestFoo:
28+
def test_a(self, fa):
29+
pass
30+
31+
@parametrize("o", [fixture_ref(fa), fixture_ref(fb), fixture_ref(fa)])
32+
def test_b(self, o):
33+
pass
34+
35+
def test_c(self, fa):
36+
pass

0 commit comments

Comments
 (0)