Skip to content

Commit 969c4c7

Browse files
author
Sylvain MARIE
committed
fixture_union now supports unpack_into. Fixed #51
1 parent 1ce5e09 commit 969c4c7

File tree

4 files changed

+73
-9
lines changed

4 files changed

+73
-9
lines changed

docs/api_reference.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ Lists all desired cases for a given user query. This function may be convenient
245245

246246
### `@pytest_fixture_plus`
247247

248-
`pytest_fixture_plus(scope="function", autouse=False, name=None, **kwargs)`
248+
`pytest_fixture_plus(scope="function", autouse=False, name=None, unpack_into=None, **kwargs)`
249249

250250
Identical to `@pytest.fixture` decorator, except that
251251

@@ -255,6 +255,14 @@ Identical to `@pytest.fixture` decorator, except that
255255

256256
As a consequence it does not support the `params` and `ids` arguments anymore.
257257

258+
**Parameters:**
259+
260+
- **scope**: the scope for which this fixture is shared, one of "function" (default), "class", "module" or "session".
261+
- **autouse**: if True, the fixture func is activated for all tests that can see it. If False (the default) then an explicitreference is needed to activate the fixture.
262+
- **name**: the name of the fixture. This defaults to the name of the decorated function. Note: If a fixture is used in the same module in which it is defined, the function name of the fixture will be shadowed by the function arg that requests the fixture; one wayto resolve this is to name the decorated function ``fixture_<fixturename>`` and then use ``@pytest.fixture(name='<fixturename>')``.
263+
- **unpack_into**: an optional iterable of names, or string containing coma-separated names, for additional fixtures to create to represent parts of this fixture. See `unpack_fixture` for details.
264+
- **kwargs**: other keyword arguments for `@pytest.fixture`
265+
258266
### `unpack_fixture`
259267

260268
`unpack_fixture(argnames, fixture) -> Tuple[<Fixture>]`
@@ -273,7 +281,7 @@ The created fixtures are automatically registered into the callers' module, but
273281
### `fixture_union`
274282

275283
`fixture_union(name, fixtures, scope="function", idstyle='explicit',
276-
ids=fixture_alternative_to_str, autouse=False, **kwargs)
284+
ids=fixture_alternative_to_str, autouse=False, unpack_into=None, **kwargs)
277285
-> <Fixture>`
278286

279287
Creates a fixture that will take all values of the provided fixtures in order. That fixture is automatically registered into the callers' module, but you may wish to assign it to a variable for convenience. In that case make sure that you use the same name, e.g. `a = fixture_union('a', ['b', 'c'])`
@@ -290,6 +298,7 @@ The style of test ids corresponding to the union alternatives can be changed wit
290298
- `fixtures`: an array-like containing fixture names and/or fixture symbols
291299
- `scope`: the scope of the union. Since the union depends on the sub-fixtures, it should be smaller than the smallest scope of fixtures referenced.
292300
- `idstyle`: The style of test ids corresponding to the union alternatives. One of `'explicit'` (default), `'compact'`, or `None`.
301+
- `unpack_into`: an optional iterable of names, or string containing coma-separated names, for additional fixtures to create to represent parts of this fixture. See `unpack_fixture` for details.
293302
- `ids`: as in pytest. The default value returns the correct fixture
294303
- `autouse`: as in pytest
295304
- `kwargs`: other pytest fixture options. They might not be supported correctly.

docs/index.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,28 @@ def test_function(a, b):
251251
assert a[0] == b
252252
```
253253

254+
And it is also available in `fixture_union`:
255+
256+
```python
257+
import pytest
258+
from pytest_cases import pytest_fixture_plus, fixture_union
259+
260+
@pytest_fixture_plus
261+
@pytest.mark.parametrize("o", ['hello', 'world'])
262+
def c(o):
263+
return o, o[0]
264+
265+
@pytest_fixture_plus
266+
@pytest.mark.parametrize("o", ['yeepee', 'yay'])
267+
def d(o):
268+
return o, o[0]
269+
270+
fixture_union("c_or_d", [c, d], unpack_into="a, b")
271+
272+
def test_function(a, b):
273+
assert a[0] == b
274+
```
275+
254276
### `param_fixture[s]`
255277

256278
If you wish to share some parameters across several fixtures and tests, it might be convenient to have a fixture representing this parameter. This is relatively easy for single parameters, but a bit harder for parameter tuples.

pytest_cases/main_fixtures.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -762,8 +762,14 @@ def fixture_alternative_to_str(fixture_alternative, # type: UnionFixtureAlterna
762762
return fixture_alternative.fixture_name
763763

764764

765-
def fixture_union(name, fixtures, scope="function", idstyle='explicit',
766-
ids=fixture_alternative_to_str, autouse=False, **kwargs):
765+
def fixture_union(name,
766+
fixtures,
767+
scope="function",
768+
idstyle='explicit',
769+
ids=fixture_alternative_to_str,
770+
unpack_into=None,
771+
autouse=False,
772+
**kwargs):
767773
"""
768774
Creates a fixture that will take all values of the provided fixtures in order. That fixture is automatically
769775
registered into the callers' module, but you may wish to assign it to a variable for convenience. In that case
@@ -784,18 +790,20 @@ def fixture_union(name, fixtures, scope="function", idstyle='explicit',
784790
:param idstyle: The style of test ids corresponding to the union alternatives. One of `'explicit'` (default),
785791
`'compact'`, or `None`.
786792
:param ids: as in pytest. The default value returns the correct fixture
793+
:param unpack_into: an optional iterable of names, or string containing coma-separated names, for additional
794+
fixtures to create to represent parts of this fixture. See `unpack_fixture` for details.
787795
:param autouse: as in pytest
788796
:param kwargs: other pytest fixture options. They might not be supported correctly.
789797
:return: the new fixture. Note: you do not need to capture that output in a symbol, since the fixture is
790798
automatically registered in your module. However if you decide to do so make sure that you use the same name.
791799
"""
792800
caller_module = get_caller_module()
793801
return _fixture_union(caller_module, name, fixtures, scope=scope, idstyle=idstyle, ids=ids, autouse=autouse,
794-
**kwargs)
802+
unpack_into=unpack_into, **kwargs)
795803

796804

797805
def _fixture_union(caller_module, name, fixtures, idstyle, scope="function", ids=fixture_alternative_to_str,
798-
autouse=False, **kwargs):
806+
unpack_into=None, autouse=False, **kwargs):
799807
"""
800808
Internal implementation for fixture_union
801809
@@ -805,6 +813,7 @@ def _fixture_union(caller_module, name, fixtures, idstyle, scope="function", ids
805813
:param idstyle:
806814
:param scope:
807815
:param ids:
816+
:param unpack_into:
808817
:param autouse:
809818
:param kwargs:
810819
:return:
@@ -853,6 +862,10 @@ def _new_fixture(request, **all_fixtures):
853862
check_name_available(caller_module, name, if_name_exists=WARN, caller=param_fixture)
854863
setattr(caller_module, name, fix)
855864

865+
# if unpacking is requested, do it here
866+
if unpack_into is not None:
867+
_unpack_fixture(caller_module, unpack_into, name)
868+
856869
return fix
857870

858871

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
11
import pytest
2-
from pytest_cases import pytest_fixture_plus
2+
from pytest_cases import pytest_fixture_plus, fixture_union
33

44

55
@pytest_fixture_plus(unpack_into="a,b")
66
@pytest.mark.parametrize("o", ['hello', 'world'])
7-
def c(o):
7+
def root1(o):
88
return o, o[0]
99

1010

1111
def test_function(a, b):
1212
assert a[0] == b
13+
assert a in ('hello', 'world')
14+
15+
16+
@pytest_fixture_plus
17+
@pytest.mark.parametrize("o", ['yeepee', 'yay'])
18+
def root2(o):
19+
return o, o[0]
20+
21+
22+
fixture_union("root", [root1, root2], unpack_into="c,d")
23+
24+
25+
def test_function2(c, d):
26+
assert c[0] == d
27+
assert c in ('hello', 'world', 'yeepee', 'yay')
1328

1429

1530
def test_synthesis(module_results_dct):
1631
assert list(module_results_dct) == ['test_function[hello]',
17-
'test_function[world]']
32+
'test_function[world]',
33+
'test_function2[root_is_root1-hello]',
34+
'test_function2[root_is_root1-world]',
35+
'test_function2[root_is_root2-yeepee]',
36+
'test_function2[root_is_root2-yay]',
37+
]

0 commit comments

Comments
 (0)