|
1 | 1 | from collections import defaultdict |
2 | | -from distutils.version import LooseVersion |
3 | | - |
4 | | -import pytest |
5 | | - |
6 | | -from pytest_cases import fixture, fixture_union |
7 | 2 |
|
| 3 | +from pytest_cases import fixture, fixture_union, parametrize |
8 | 4 |
|
9 | 5 | used = defaultdict(lambda: False) |
10 | 6 | torn_down = defaultdict(lambda: False) |
11 | 7 |
|
12 | 8 |
|
13 | 9 | @fixture(scope='session') |
14 | | -def a(): |
| 10 | +def s1(): |
| 11 | + name = 's1' |
| 12 | + global used, torn_down |
| 13 | + assert not used[name] |
| 14 | + used[name] = True |
| 15 | + yield name |
| 16 | + torn_down[name] += 1 |
| 17 | + |
| 18 | + |
| 19 | +@fixture(scope='session') |
| 20 | +def s2(): |
| 21 | + name = 's2' |
| 22 | + global used, torn_down |
| 23 | + assert not used[name] |
| 24 | + used[name] = True |
| 25 | + yield name |
| 26 | + torn_down[name] += 1 |
| 27 | + |
| 28 | + |
| 29 | +@fixture(scope='session') |
| 30 | +def s3(): |
| 31 | + name = 's3' |
| 32 | + global used, torn_down |
| 33 | + assert not used[name] |
| 34 | + used[name] = True |
| 35 | + yield name |
| 36 | + torn_down[name] += 1 |
| 37 | + |
| 38 | + |
| 39 | +@fixture(scope='module') |
| 40 | +def M1s1s2(s1, s2): |
| 41 | + name = 'M1s1s2' |
15 | 42 | global used, torn_down |
16 | | - assert not used['a'] |
17 | | - used['a'] = True |
18 | | - yield 'a' |
19 | | - torn_down['a'] = True |
| 43 | + assert not used[name] |
| 44 | + used[name] = True |
| 45 | + yield name |
| 46 | + torn_down[name] += 1 |
20 | 47 |
|
21 | 48 |
|
22 | 49 | @fixture(scope='module') |
23 | | -def b(a): |
| 50 | +def M2s1s3(s1, s3): |
| 51 | + name = 'M2s1s3' |
24 | 52 | global used, torn_down |
25 | | - assert not used['b'] |
26 | | - used['b'] = True |
27 | | - yield 'b' |
28 | | - torn_down['b'] = True |
| 53 | + assert not used[name] |
| 54 | + used[name] = True |
| 55 | + yield name |
| 56 | + torn_down[name] += 1 |
29 | 57 |
|
30 | 58 |
|
31 | 59 | @fixture(scope='function') |
32 | | -def c1(b): |
| 60 | +def F1M1s1s2(M1s1s2): |
| 61 | + name = 'F1M1s1s2' |
33 | 62 | global used, torn_down |
34 | | - used['c1'] += 1 |
35 | | - yield 'c1' |
36 | | - torn_down['c1'] += 1 |
| 63 | + assert not used[name] |
| 64 | + used[name] = True |
| 65 | + yield name |
| 66 | + torn_down[name] += 1 |
37 | 67 |
|
38 | 68 |
|
39 | 69 | @fixture(scope='function') |
40 | | -def c2(): |
| 70 | +@parametrize(i=[0, 1]) |
| 71 | +def F2(i): |
| 72 | + name = 'F2(%s)' % i |
41 | 73 | global used, torn_down |
42 | | - used['c2'] += 1 |
43 | | - yield 'c2' |
44 | | - torn_down['c2'] += 1 |
| 74 | + assert not used[name] |
| 75 | + used[name] = True |
| 76 | + yield name |
| 77 | + torn_down[name] += 1 |
45 | 78 |
|
46 | 79 |
|
47 | 80 | @fixture(scope='function') |
48 | | -def c3(a): |
| 81 | +def F3s2s3(s2, s3): |
| 82 | + name = 'F3s2s3' |
49 | 83 | global used, torn_down |
50 | | - used['c3'] += 1 |
51 | | - yield 'c3' |
52 | | - torn_down['c3'] += 1 |
| 84 | + assert not used[name] |
| 85 | + used[name] = True |
| 86 | + yield name |
| 87 | + torn_down[name] += 1 |
53 | 88 |
|
54 | 89 |
|
55 | 90 | @fixture(scope='function') |
56 | | -def c4(b): |
| 91 | +def F4M2s1s3(M2s1s3): |
| 92 | + name = 'F4M2s1s3' |
57 | 93 | global used, torn_down |
58 | | - used['c4'] += 1 |
59 | | - yield 'c4' |
60 | | - torn_down['c4'] += 1 |
| 94 | + assert not used[name] |
| 95 | + used[name] = True |
| 96 | + yield name |
| 97 | + torn_down[name] += 1 |
61 | 98 |
|
62 | 99 |
|
63 | | -d = fixture_union('d', (c1, c2, c3, c4)) |
| 100 | +d = fixture_union('d', (F1M1s1s2, F2, F3s2s3, F4M2s1s3)) |
64 | 101 |
|
65 | 102 |
|
66 | | -def test_foo(d, request): |
67 | | - super_closure = request._pyfuncitem._fixtureinfo.names_closure |
| 103 | +super_closure = None |
68 | 104 |
|
69 | | - # in old pytest sorting is different and cannot be done according to scope |
70 | | - if LooseVersion(pytest.__version__) >= LooseVersion('3.5.0'): |
71 | | - assert str(super_closure) == """SuperClosure with 4 alternative closures: |
72 | | - - ['d', 'a', 'b', 'c1', 'request'] (filters: d=d[0]=c1) |
73 | | - - ['d', 'c2', 'request'] (filters: d=d[1]=c2) |
74 | | - - ['d', 'a', 'c3', 'request'] (filters: d=d[2]=c3) |
75 | | - - ['d', 'a', 'b', 'c4', 'request'] (filters: d=d[3]=c4) |
76 | | -The 'super closure list' is ['a', 'b', 'd', 'c1', 'request', 'c2', 'c3', 'c4'] |
77 | 105 |
|
78 | | -The fixture tree is : |
79 | | -(d) split: d |
80 | | - - (c1,request,b,a) |
81 | | - - (c2,request) |
82 | | - - (c3,request,a) |
83 | | - - (c4,request,b,a) |
84 | | -""" |
| 106 | +def test_foo(d, request): |
| 107 | + # store closure for later analysis or test |
| 108 | + global super_closure |
| 109 | + super_closure = request._pyfuncitem._fixtureinfo.names_closure |
85 | 110 |
|
86 | 111 |
|
87 | 112 | def test_synthesis(module_results_dct): |
88 | 113 | assert all(torn_down.values()) |
89 | 114 | assert list(module_results_dct) == [ |
90 | | - 'test_foo[d_is_c1]', |
91 | | - 'test_foo[d_is_c4]', |
92 | | - 'test_foo[d_is_c3]', |
93 | | - 'test_foo[d_is_c2]', |
| 115 | + 'test_foo[d_is_F1M1s1s2]', |
| 116 | + 'test_foo[d_is_F2-i=0]', |
| 117 | + 'test_foo[d_is_F2-i=1]', |
| 118 | + 'test_foo[d_is_F3s2s3]', |
| 119 | + 'test_foo[d_is_F4M2s1s3]' |
94 | 120 | ] |
95 | 121 |
|
96 | | - for item in ('a', 'b', 'c1', 'c2', 'c3', 'c4'): |
97 | | - assert used[item] == 1 |
98 | | - assert torn_down[item] == 1 |
| 122 | + function_scoped = ('F1M1s1s2', 'F2(0)', 'F2(1)', 'F3s2s3', 'F4M2s1s3') |
| 123 | + module_scoped = ('M1s1s2', 'M2s1s3') |
| 124 | + session_scoped = ('s1', 's2', 's3') |
| 125 | + |
| 126 | + for item in function_scoped + module_scoped + session_scoped: |
| 127 | + assert used[item] == 1, "item %s was not used once" % item |
| 128 | + |
| 129 | + if item in function_scoped: |
| 130 | + assert torn_down[item] == 1, "item %s was not torn down once" % item |
| 131 | + # else we know that the last module/session fixture alive is not properly torn down, this is a pytest issue |
| 132 | + |
| 133 | + |
| 134 | +# def test_super_closure(): |
| 135 | +# global super_closure |
| 136 | +# print(super_closure) |
0 commit comments