Configure pytest fixtures using a combination of"parametrize" and markers
Project description
Configure pytest fixtures using combination of parametrize and markers
What is this thing?
The problem
Pytest fixture names must be unique within the whole dependency graph (#3966).
This means that when you want to parametrize fixtures, each parameter name must be unique:
import pytest
@pytest.fixture
def foo(foo_option):
return {'option': foo_option}
@pytest.fixture
def bar(bar_option):
return {'option': bar_option}
@pytest.mark.parametrize(
'foo_option, bar_option',
[
(42, 24),
]
)
def test_options(foo, bar):
assert foo['option'] == 42
assert bar['option'] == 24
Also, if you want to provide default vaules for options, they need to be fixtures as well:
@pytest.fixture
def foo_option():
return 'default_foo_option'
@pytest.fixture
def bar_option():
return 'default_bar_option'
@pytest.fixture
def foo(foo_option):
return {'option': foo_option}
@pytest.fixture
def bar(bar_option):
return {'option': bar_option}
def test_options(foo, bar):
assert foo['option'] == 'default_foo_option'
assert bar['option'] == 'default_bar_option'
This is inconvenient when number of options and fixtures increases, and you end up with lots of boilerplate code like this:
@pytest.fixture()
def app_elements():
{}
@pytest.fixture()
def app_sequence():
return None
@pytest.fixture()
def app_uuid(uuid=None):
return uuid or uuid4()
@pytest.fixture
def app_app_key():
return ApplicationKey(bytes.fromhex('63964771734fbd76e3b40519d1d94a48'))
@pytest.fixture
def app_net_key():
return NetworkKey(bytes.fromhex('7dd7364cd842ad18c17c2b820c84c3d6'))
@pytest.fixture
def app_dev_key():
return DeviceKey(bytes.fromhex('9d6dd0e96eb25dc19a40ed9914f8f03f'))
@pytest.fixture
def app_addr():
return 0x5f2
@pytest.fixture
def app_iv_index():
return 0
@pytest.fixture()
def application(app_uuid, app_elements, app_dev_key, app_app_key, app_net_ket,
app_addr, app_iv_index, app_sequence):
...
The solution
This plugin provides a cleaner way to pass such options to selected fixutres, by implementing a magic fixture called paramark, which returns a different value for each of the fixtures that depend on it:
@pytest.fixture
def foo(paramark):
return paramark
@pytest.fixture
def bar(paramark):
return paramark
@pytest.mark.foo(option=42)
@pytest.mark.bar(option=24)
def test_options(foo, bar):
assert foo['option'] == 42
assert bar['option'] == 24
As can be seen in the example, paramark returns a dictionary with keys and values pulled from a custom mark with the same name as the dependant fixture. Note that these marks still need to be registered.
This also works with parametrize, by extending the argument name syntax to include a dot:
@pytest.mark.parametrize(
'foo.option, bar.option',
[
(43, 24),
]
)
@pytest.mark.bar(option=24)
def test_options(foo, bar):
assert foo['option'] == 42
assert bar['option'] == 24
or, if you want to parametrize the whole dictionary:
@pytest.mark.parametrize(
'foo.*, bar.option',
[
({'option': 42, 'another: 17}, 24),
]
)
@pytest.mark.bar(option=24)
def test_options(foo, bar):
assert foo['option'] == 42
assert foo['another'] == 17
assert bar['option'] == 24
Having this, defining default values no longer requires separate fixture for each option:
@pytest.fixture
def foo(paramark):
default = {'option': 'default_foo_option'}
return {**default, **paramark)
@pytest.fixture
def bar(paramark):
default = {'option': 'default_bar_option'}
return {**default, **paramark)
@pytest.mark.foo(option='custom_foo_option')
def test_options(foo, bar):
assert foo['option'] == 'custom_foo_option'
assert bar['option'] == 'default_bar_option'
or, if you want to be safer and fancier:
import typing
@pytest.fixture
def foo(paramark):
class Foo(typing.NamedTuple):
option: str = 'default_foo_option'
return Foo(**paramark)
def test_options(foo):
assert foo.option == 'default_foo_option'
Installation
You can install “pytest-paramark” via pip from PyPI:
$ pip install pytest-paramark
Contributing
Contributions are very welcome. Tests can be run with tox, please ensure the coverage at least stays the same before you submit a pull request.
License
Distributed under the terms of the MIT license, “pytest-paramark” is free and open source software
Issues
If you encounter any problems, please file an issue along with a detailed description.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for pytest-paramark-0.1.1.linux-x86_64.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | c36daf9de6b79147258115a491256674cab4b5a342912fa2e77f585df45a3f82 |
|
MD5 | 9fb2e908ea11f7aba9e3bdeaed372471 |
|
BLAKE2b-256 | bec84b960c136b385b39ed3e87d87c8fba2dedfd428b900d64063780f465a65e |
Hashes for pytest_paramark-0.1.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 42f5002bd13fb0652e916a11dc292557eaa5c328eb3ece095d05406fe8257fdc |
|
MD5 | 870eaa619334a64400bb256b401e6478 |
|
BLAKE2b-256 | 0a0ec7b04e63cdfc845691592cb54301eab824b60f52c15a859917e0ef115cb3 |