def test_cart_product_pytest(): # simple names_lst, values = cart_product_pytest(('a', 'b'), ([True], [1, 2])) assert names_lst == ['a', 'b'] assert values == [(True, 1), (True, 2)] # multi names_lst, values = cart_product_pytest(('a,b', 'c'), ([(True, 1)], [1, 2])) assert names_lst == ['a', 'b', 'c'] assert values == [(True, 1, 1), (True, 1, 2)] # marks names_lst, values = cart_product_pytest(('a,b', 'c'), ([(True, 1)], [skip(1), 2])) assert names_lst == ['a', 'b', 'c'] assert get_marked_parameter_values(values[0]) == (True, 1, 1) assert values[1] == (True, 1, 2) # lazy values def get_tuple(): return 3, 4 names_lst, values = cart_product_pytest( ('a', 'b,c'), ([True], [lazy_value(get_tuple, marks=skip), (1, 2)])) assert names_lst == ['a', 'b', 'c'] assert values[0][0] is True assert is_lazy(values[0][1]) assert is_lazy(values[0][2]) assert values[0][1].get_id() == 'get_tuple[0]' assert values[0][2].get_id() == 'get_tuple[1]' assert values[1] == (True, 1, 2)
def test_value_ref(): """ Tests that our hack for lazy_value works: for old versions of pytest, we make it a subclass of int so that pytest id generator (`_idval`) calls "str" on it. For pytest >= 5.3.0 we do not need this hack as overriding __name__ is enough. :return: """ def foo(): pass a = lazy_value(foo) assert mini_idval(a, 'a', 1) == 'foo' assert 'lazy_value' in repr(a)
def test_lv_tuple_clone(): """ Test that the internal API allows other plugins such as pytest-harvest to easily clone a lazy value without inheriting from the hack int base (this test is for tuple """ def foo(): return 1, 2 lvt = lazy_value(foo, id="hi", marks=pytest.mark.skip).as_lazy_tuple(2) for i, lv in enumerate(lvt): assert str(lv) == "hi[%s]" % i assert repr(lv).startswith("LazyTupleItem(item=%s, tuple=LazyValue(valuegetter=<function" % i) if pytest53: assert not isinstance(lv, int) lv2 = lv.clone() assert lv == lv2 assert not isinstance(lv2, int) else: assert isinstance(lv, int) lv2 = lv.clone(remove_int_base=True) assert lv == lv2 assert not isinstance(lv2, int)
def test_lv_clone(): """ Test that the internal API allows other plugins such as pytest-harvest to easily clone a lazy value without inheriting from the hack int base""" def foo(): return 1 lv = lazy_value(foo, id="hi", marks=pytest.mark.skip) assert str(lv) == "hi" assert repr(lv).startswith("LazyValue(valuegetter=<function") assert ">, _id='hi'," in repr(lv) assert "'skip'" in repr(lv) if pytest53: assert not isinstance(lv, int) lv2 = lv.clone() assert lv == lv2 assert not isinstance(lv2, int) else: assert isinstance(lv, int) lv2 = lv.clone(remove_int_base=True) assert lv == lv2 assert not isinstance(lv2, int)
pytest2 = LooseVersion(pytest.__version__) < LooseVersion("3.0.0") @fixture def b(): return 1, "hello" def foo(): return ["r", 1] @parametrize( "a", [ lazy_value(foo), # fixture_ref(b) ]) def test_foo(a): """a single lazy value""" assert a in (["r", 1], (1, "hello")) @parametrize( "i,j", [ lazy_value(foo), # fixture_ref(b) ]) def test_foo2(i, j): """a lazy value used as a tuple containing several args"""
return 1, 2 @pytest.mark.skipif(not has_pytest_param, reason="well") def val_skipped_on_old_pytest(): return "what" def val(): return 1 if not has_pytest_param: @parametrize("a", [ lazy_value(val), lazy_value(val_skipped_on_old_pytest), lazy_value(val, id='A') ]) def test_foo_single(a): """here the fixture is used for both parameters at the same time""" assert a == 1 @parametrize("a,b", [lazy_value(valtuple), (1, lazy_value(val))]) def test_foo_multi(a, b): """here the fixture is used for both parameters at the same time""" assert (a, b) == (1, 2) or (a, b) == (1, 1) def test_synthesis(module_results_dct): assert list(module_results_dct) == [ 'test_foo_single[val]',
from pytest_cases import parametrize_with_cases, lazy_value, parametrize from pytest_cases.common_pytest_marks import has_pytest_param def case_dumb(): return 1, 2 @parametrize("a,b", [(1, object()), lazy_value(case_dumb)]) def test_foo(a, b): pass @parametrize_with_cases('a,b', cases='.') def test_tuples_no_id(a, b): assert True # --------- now we do the same with an id generator @parametrize("a,b", [(1, object()), lazy_value(case_dumb)], ids=["hello", "world"]) def test_foo2(a, b): pass def generate_id(o): return "hello"
# License: 3-clause BSD, <https://github.com/smarie/python-pytest-cases/blob/master/LICENSE> import pytest from pytest_cases import parametrize_plus, lazy_value, fixture_plus, fixture_ref def valtuple(): return 1, 2 def val(): return 1 @fixture_plus @parametrize_plus("i", [lazy_value(val), 11]) def tfix(i): return i, i+2 @fixture_plus @parametrize_plus("i", [5, lazy_value(val)]) def vfix(i): return -i flag = False def valtuple_toskip(): return 15, 2
from pytest_cases import parametrize_plus, lazy_value, fixture_plus, fixture_ref @fixture_plus @parametrize_plus("i", [5, 7]) def bfix(i): return -i def val(): return 1 has_pytest_param = hasattr(pytest, 'param') if not has_pytest_param: @parametrize_plus("a", [lazy_value(val), fixture_ref(bfix), lazy_value(val, id='A')]) def test_foo_single(a): """here the fixture is used for both parameters at the same time""" assert a in (1, -5, -7) def test_synthesis2(module_results_dct): assert list(module_results_dct) == ['test_foo_single[a_is_val]', 'test_foo_single[a_is_bfix-5]', 'test_foo_single[a_is_bfix-7]', 'test_foo_single[a_is_A]', ]
# + All contributors to <https://github.com/smarie/python-pytest-cases> # # License: 3-clause BSD, <https://github.com/smarie/python-pytest-cases/blob/master/LICENSE> from pytest_cases import fixture, get_current_cases, parametrize, lazy_value, fixture_ref, parametrize_with_cases def foo(): return 1, 2 @fixture def foo_fix(): return 3, 4 @parametrize("a", [1, lazy_value(foo)]) @parametrize("a1,a2", [(1, 2), lazy_value(foo)]) @parametrize( "b1,b2", [(1, 2), lazy_value(foo), foo_fix, (foo_fix, foo_fix), (3, 4)], idstyle="explicit") def test_foo(a, a1, a2, b1, b2, current_cases, request): assert current_cases == {} assert get_current_cases(request) == {} # ----------- fix for issue 213 @parametrize(name=("bar", )) def case_foo2(name):
from distutils.version import LooseVersion import pytest from pytest_cases import parametrize, lazy_value, fixture, is_lazy def x(): return [] @parametrize("y", [0, 1]) @parametrize("x", [lazy_value(x)]) @pytest.mark.skipif( LooseVersion(pytest.__version__) < LooseVersion('3.0.0'), reason="request.getfixturevalue is not available in pytest 2") def test_foo(x, y, my_cache_verifier): print(x, y) # make sure the cache works correctly: different requests trigger different calls assert x == ['added_by_fixture'] x.append("added_by_test") @fixture def my_cache_verifier(request): x = request.getfixturevalue('x') assert is_lazy(x) x = x.get(request) x.append('added_by_fixture') yield x = request.getfixturevalue('x')
def test_value_ref(): """ Tests that our hack for lazy_value works: for old versions of pytest, we make it a subclass of int so that pytest id generator (`_idval`) calls "str" on it. For pytest >= 5.3.0 we do not need this hack as overriding __name__ is enough. :return: """ global _called def foo(): global _called _called += 1 return 1, 2 a = lazy_value(foo) # test that ids will be correctly generated even on old pytest assert mini_idval(a, 'a', 1) == 'foo' assert 'LazyValue' in repr(a) # test that that calls work and the cache works even across copies class FakeRequest: class FakeNode: pass def __init__(self): self.node = FakeRequest.FakeNode() fake_request = FakeRequest() assert a.get(fake_request) == (1, 2) assert a.get(fake_request) == (1, 2) assert _called == 1 assert LazyValue.copy_from(a).get(fake_request) == (1, 2) assert _called == 1 fake_request2 = FakeRequest() assert a.get(fake_request2) == (1, 2) assert _called == 2 assert LazyValue.copy_from(a).get(fake_request2) == (1, 2) assert _called == 2 # reset cache context and counter for next steps a.get(fake_request) _called = 1 # now do the same test for lazy values used as a tuple of parameters new_lv = lazy_value(foo) assert not new_lv.has_cached_value() assert a.has_cached_value() for src in new_lv, a: # set the counter according to the state of the cache _called = 0 if not src.has_cached_value() else 1 at = src.as_lazy_tuple(2) # test when the tuple is unpacked into several parameters if not at.has_cached_value(): for i, a in enumerate(at): # test that ids will be correctly generated even on old pytest assert mini_idval(a, 'a', 1) == 'foo[%s]' % i assert ('LazyTupleItem(item=%s' % i) in repr(a) else: # this does not happen in real usage but in case a plugin messes with this assert tuple(at) == (1, 2) # test when the tuple is not unpacked - # note: this is not supposed to happen when @parametrize decorates a test function, # it only happens when @parametrize decorates a fixture - indeed in that case we generate the whole id ourselves assert str(at) == 'foo' # assert that calls work and the cache works even across copies assert at.get(fake_request) == (1, 2) assert at.get(fake_request) == (1, 2) assert _called == 1 assert LazyTuple.copy_from(at).get(fake_request) == (1, 2) assert _called == 1 assert at.get(fake_request2) == (1, 2) assert LazyTuple.copy_from(at).get(fake_request2) == (1, 2) assert _called == 2 # test that retrieving the tuple does not loose the id assert str(at) == 'foo' assert at.has_cached_value()
from random import random import pytest from pytest_cases import lazy_value database = [random() for i in range(10)] def get_param(i): return database[i] def make_param_getter(i, use_partial=True): if use_partial: return partial(get_param, i) else: def _get_param(): return database[i] return _get_param many_parameters = (make_param_getter(i) for i in range(10)) @pytest.mark.parametrize('a', [lazy_value(f) for f in many_parameters]) def test_foo(a): print(a)
@fixture @parametrize("i", [5, 7]) def bfix(i): return -i def val(): return 1 has_pytest_param = hasattr(pytest, 'param') if not has_pytest_param: @parametrize("a", [lazy_value(val), fixture_ref(bfix), lazy_value(val, id='A')]) def test_foo_single(a): """here the fixture is used for both parameters at the same time""" assert a in (1, -5, -7) def test_synthesis2(module_results_dct): assert list(module_results_dct) == [ 'test_foo_single[val]', 'test_foo_single[bfix-5]', 'test_foo_single[bfix-7]', 'test_foo_single[A]', ] else:
# # License: 3-clause BSD, <https://github.com/smarie/python-pytest-cases/blob/master/LICENSE> import pytest from pytest_cases import parametrize_plus, fixture_plus, fixture_ref, lazy_value @pytest.fixture def world_str(): return 'world' def whatfun(): return 'what' @fixture_plus @parametrize_plus('who', [fixture_ref(world_str), 'you']) def greetings(who): return 'hello ' + who @parametrize_plus('main_msg', [ 'nothing', fixture_ref(world_str), lazy_value(whatfun), fixture_ref(greetings) ]) @pytest.mark.parametrize('ending', ['?', '!']) def test_prints(main_msg, ending): print(main_msg + ending)
return 15, 2 def valtuple_only_right_when_lazy(): global flag if flag: return 0, -1 else: raise ValueError("not yet ready ! you should call me later ") has_pytest_param = hasattr(pytest, 'param') if not has_pytest_param: @parametrize("a,b", [ lazy_value(valtuple), lazy_value(valtuple, id='A'), fixture_ref(tfix), (fixture_ref(vfix), lazy_value(val)), (lazy_value(val, id='B'), fixture_ref(vfix)), (fixture_ref(vfix), fixture_ref(vfix)), ], debug=True) def test_foo_multi(a, b): """here the fixture is used for both parameters at the same time""" global flag flag = True assert (a, b) in ((1, 2), (1, 1), (13, 15), (11, 13), (-5, 1), (-7, 1), (1, -5), (1, -7), (-5, -5), (-7, -7)) def test_synthesis2(module_results_dct):
@fixture def fixtuple(): return 1, 2 def foo(): return 2 def footuple(): return 3, 4 @test_steps("step1", "step2") @parametrize("b,c", [fixtuple, lazy_value(footuple)]) @parametrize(a=[fix, lazy_value(foo)]) def test_steps_and_cases(a, b, c): print("step 1") assert a in (1, 2) assert (b, c) in ((1, 2), (3, 4)) yield print("step 2") assert a in (1, 2) assert (b, c) in ((1, 2), (3, 4)) yield @test_steps("step1", "step2")