Define pytest fixtures using lambda functions
Project description
pytest-lambda
Define pytest fixtures with lambda functions.
Quickstart
pip install pytest-lambda
# test_the_namerator.py
import pytest
first = pytest.static_fixture('John')
middle = pytest.static_fixture('Jacob')
last = pytest.static_fixture('Jingleheimer-Schmidt')
full_name = pytest.lambda_fixture(lambda first, middle, last: f'{first} {middle} {last}')
def test_the_namerator(full_name):
assert full_name == 'John Jacob Jingleheimer-Schmidt'
Cheatsheet
import pytest
# Basic usage
fixture_name = pytest.lambda_fixture(lambda other_fixture: 'expression', scope='session', autouse=True)
# Request fixtures by name
fixture_name = pytest.lambda_fixture('other_fixture')
fixture_name = pytest.lambda_fixture('other_fixture', 'another_fixture', 'cant_believe_its_not_fixture')
# Reference `self` inside a class
class TestContext:
fixture_name = pytest.lambda_fixture(lambda self: self.__class__.__name__, bind=True)
# Parametrize
fixture_name = pytest.lambda_fixture(lambda request: request.param, params=['a', 'b'], ids=['A!', 'B!'])
fixture_name = pytest.lambda_fixture(lambda request: request.param,
params=[pytest.param('a', id='A!'),
pytest.param('b', id='B!')])
# Use literal value (not lazily evaluated)
fixture_name = pytest.static_fixture(42)
fixture_name = pytest.static_fixture('just six sevens', autouse=True, scope='module')
# Raise an exception if fixture is requested
fixture_name = pytest.error_fixture(lambda: ValueError('my life has no intrinsic value'))
# Or maybe don't raise the exception
fixture_name = pytest.error_fixture(lambda other_fixture: TypeError('nope') if other_fixture else None)
# Create an abstract fixture (to be overridden by the user)
fixture_name = pytest.not_implemented_fixture()
fixture_name = pytest.not_implemented_fixture(autouse=True, scope='session')
# Disable usage of a fixture (fail early to save future head scratching)
fixture_name = pytest.disabled_fixture()
What else is possible?
Of course, you can use lambda fixtures inside test classes:
# test_staying_classy.py
import pytest
class TestClassiness:
classiness = pytest.lambda_fixture(lambda: 9000 + 1)
def test_how_classy_we_is(self, classiness):
assert classiness == 9001
Aliasing other fixtures
You can also pass the name of another fixture, instead of a lambda:
# test_the_bourne_identity.py
import pytest
agent = pytest.static_fixture('Bourne')
who_i_am = pytest.lambda_fixture('agent')
def test_my_identity(who_i_am):
assert who_i_am == 'Bourne'
Even multiple fixture names can be used:
# test_the_bourne_identity.py
import pytest
agent_first = pytest.static_fixture('Jason')
agent_last = pytest.static_fixture('Bourne')
who_i_am = pytest.lambda_fixture('agent_first', 'agent_last')
def test_my_identity(who_i_am):
assert who_i_am == ('Jason', 'Bourne')
Annotating aliased fixtures
You can force the loading of fixtures without trying to remember the name of pytest.mark.usefixtures
# test_garage.py
import pytest
car = pytest.static_fixture({
'type': 'Sweet-ass Cadillac',
'is_started': False,
})
turn_the_key = pytest.lambda_fixture(lambda car: car.update(is_started=True))
preconditions = pytest.lambda_fixture('turn_the_key', autouse=True)
def test_my_caddy(car):
assert car['is_started']
Declaring abstract things
not_implemented_fixture
is perfect for labeling abstract parameter fixtures of test mixins
# test_mixinalot.py
import pytest
class Dials1900MixinALot:
butt_shape = pytest.not_implemented_fixture()
desires = pytest.not_implemented_fixture()
def it_kicks_them_nasty_thoughts(self, butt_shape, desires):
assert butt_shape == 'round' and 'triple X throw down' in desires
@pytest.mark.xfail
class DescribeMissThing(Dials1900MixinALot):
butt_shape = pytest.static_fixture('flat')
desires = pytest.static_fixture(['playin workout tapes by Fonda'])
class DescribeSistaICantResista(Dials1900MixinALot):
butt_shape = pytest.static_fixture('round')
desires = pytest.static_fixture(['gettin in yo Benz',
'triple X throw down'])
Use disabled_fixture
to mark a fixture as disabled. Go figure.
# test_ada.py
import pytest
wheelchair = pytest.disabled_fixture()
@pytest.mark.xfail(strict=True)
def test_stairs(wheelchair):
assert wheelchair + 'floats'
Raising exceptions
You can also raise an arbitrary exception when a fixture is requested, using error_fixture
# test_bikeshed.py
import pytest
bicycle = pytest.static_fixture('a sledgehammer')
def it_does_sweet_jumps(bicycle):
assert bicycle + 'jump' >= '3 feet'
class ContextOcean:
depth = pytest.not_implemented_fixture()
bicycle = pytest.error_fixture(lambda bicycle, depth: (
RuntimeError(f'Now is not the time to use that! ({bicycle})') if depth > '1 league' else None))
class ContextDeep:
depth = pytest.static_fixture('20,000 leagues')
@pytest.mark.xfail(strict=True, raises=RuntimeError)
def it_doesnt_flip_and_shit(self, bicycle):
assert bicycle + 'floats'
class ContextBeach:
depth = pytest.static_fixture('1 inch')
def it_gets_you_all_wet_but_otherwise_rides_like_a_champ(self, bicycle):
assert 'im wet'
Development
How can I build and test the thing locally?
- Create a virtualenv, however you prefer. Or don't, if you prefer.
pip install -r dev-requirements.txt
flit install -s
to install setuptools entrypoint, so pytest automatically loads the plugin (otherwise, you'll have to runpy.test -p pytest_lambda.plugin
)- Run
py.test
. The tests will be collected from the README.md (thanks to pytest-markdown).
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_lambda-0.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 74fb5b1afd3769f2abd51009ee8ec27ff15a1521e6721e15767ffd4a2930608c |
|
MD5 | 2366881afbd0f72327feb913f957903e |
|
BLAKE2b-256 | 9e86dc0850fb1db78beeef8a8a5901544dabe859d79feb57326855584ecfad4a |