From 090f7ff44907ab1b3317bf5c19b36fabb6a84b8b Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 1 Dec 2018 15:58:55 -0200 Subject: [PATCH 1/2] Remove request.cached_setup Fix #4489 --- changelog/4489.removal.rst | 3 + doc/en/deprecations.rst | 68 +++++++------- src/_pytest/deprecated.py | 5 - src/_pytest/fixtures.py | 37 -------- testing/deprecated_test.py | 21 ----- testing/python/fixture.py | 188 +------------------------------------ 6 files changed, 38 insertions(+), 284 deletions(-) create mode 100644 changelog/4489.removal.rst diff --git a/changelog/4489.removal.rst b/changelog/4489.removal.rst new file mode 100644 index 000000000..423620465 --- /dev/null +++ b/changelog/4489.removal.rst @@ -0,0 +1,3 @@ +Removed ``request.cached_setup``. This was the predecessor mechanism to modern fixtures. + +See our `docs `__ on information on how to update your code. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index 229bca171..b6ec4f245 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -49,41 +49,6 @@ Becomes: exec("assert(1, 2)") # exec is used to avoid a top-level warning - -``cached_setup`` -~~~~~~~~~~~~~~~~ - -.. deprecated:: 3.9 - -``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures. - -Example: - -.. code-block:: python - - @pytest.fixture - def db_session(): - return request.cached_setup( - setup=Session.create, teardown=lambda session: session.close(), scope="module" - ) - -This should be updated to make use of standard fixture mechanisms: - -.. code-block:: python - - @pytest.fixture(scope="module") - def db_session(): - session = Session.create() - yield session - session.close() - - -You can consult `funcarg comparison section in the docs `_ for -more information. - -This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings. - - Using ``Class`` in custom Collectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -309,6 +274,39 @@ Removed Features As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after an appropriate period of deprecation has passed. +``cached_setup`` +~~~~~~~~~~~~~~~~ + +*Removed in version 4.0.* + +``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures. + +Example: + +.. code-block:: python + + @pytest.fixture + def db_session(): + return request.cached_setup( + setup=Session.create, teardown=lambda session: session.close(), scope="module" + ) + +This should be updated to make use of standard fixture mechanisms: + +.. code-block:: python + + @pytest.fixture(scope="module") + def db_session(): + session = Session.create() + yield session + session.close() + + +You can consult `funcarg comparison section in the docs `_ for +more information. + +This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings. + ``yield`` tests ~~~~~~~~~~~~~~~ diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index ba7426a11..94ba6d037 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -24,11 +24,6 @@ MAIN_STR_ARGS = RemovedInPytest4Warning( YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored" -CACHED_SETUP = RemovedInPytest4Warning( - "cached_setup is deprecated and will be removed in a future release. " - "Use standard fixture functions instead." -) - FUNCARG_PREFIX = UnformattedWarning( RemovedInPytest4Warning, '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 924352afb..1519d2fbc 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -469,43 +469,6 @@ class FixtureRequest(FuncargnamesCompatAttr): if argname not in item.funcargs: item.funcargs[argname] = self.getfixturevalue(argname) - def cached_setup(self, setup, teardown=None, scope="module", extrakey=None): - """ (deprecated) Return a testing resource managed by ``setup`` & - ``teardown`` calls. ``scope`` and ``extrakey`` determine when the - ``teardown`` function will be called so that subsequent calls to - ``setup`` would recreate the resource. With pytest-2.3 you often - do not need ``cached_setup()`` as you can directly declare a scope - on a fixture function and register a finalizer through - ``request.addfinalizer()``. - - :arg teardown: function receiving a previously setup resource. - :arg setup: a no-argument function creating a resource. - :arg scope: a string value out of ``function``, ``class``, ``module`` - or ``session`` indicating the caching lifecycle of the resource. - :arg extrakey: added to internal caching key of (funcargname, scope). - """ - from _pytest.deprecated import CACHED_SETUP - - warnings.warn(CACHED_SETUP, stacklevel=2) - if not hasattr(self.config, "_setupcache"): - self.config._setupcache = {} # XXX weakref? - cachekey = (self.fixturename, self._getscopeitem(scope), extrakey) - cache = self.config._setupcache - try: - val = cache[cachekey] - except KeyError: - self._check_scope(self.fixturename, self.scope, scope) - val = setup() - cache[cachekey] = val - if teardown is not None: - - def finalizer(): - del cache[cachekey] - teardown(val) - - self._addfinalizer(finalizer, scope=scope) - return val - def getfixturevalue(self, argname): """ Dynamically run a named fixture function. diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index bc2e8378b..aa3c5e58b 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -10,27 +10,6 @@ from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG pytestmark = pytest.mark.pytester_example_path("deprecated") -def test_cached_setup_deprecation(testdir): - testdir.makepyfile( - """ - import pytest - @pytest.fixture - def fix(request): - return request.cached_setup(lambda: 1) - - def test_foo(fix): - assert fix == 1 - """ - ) - result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines( - [ - "*test_cached_setup_deprecation.py:4:*cached_setup is deprecated*", - "*1 passed, 1 warnings in*", - ] - ) - - def test_funcarg_prefix_deprecation(testdir): testdir.makepyfile( """ diff --git a/testing/python/fixture.py b/testing/python/fixture.py index f5813b5d8..2cc4122b4 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -953,181 +953,6 @@ class TestRequestMarking(object): reprec.assertoutcome(passed=2) -class TestRequestCachedSetup(object): - def test_request_cachedsetup_defaultmodule(self, testdir): - reprec = testdir.inline_runsource( - """ - mysetup = ["hello",].pop - - import pytest - - @pytest.fixture - def something(request): - return request.cached_setup(mysetup, scope="module") - - def test_func1(something): - assert something == "hello" - class TestClass(object): - def test_func1a(self, something): - assert something == "hello" - """, - SHOW_PYTEST_WARNINGS_ARG, - ) - reprec.assertoutcome(passed=2) - - def test_request_cachedsetup_class(self, testdir): - reprec = testdir.inline_runsource( - """ - mysetup = ["hello", "hello2", "hello3"].pop - - import pytest - @pytest.fixture - def something(request): - return request.cached_setup(mysetup, scope="class") - def test_func1(something): - assert something == "hello3" - def test_func2(something): - assert something == "hello2" - class TestClass(object): - def test_func1a(self, something): - assert something == "hello" - def test_func2b(self, something): - assert something == "hello" - """, - SHOW_PYTEST_WARNINGS_ARG, - ) - reprec.assertoutcome(passed=4) - - @pytest.mark.filterwarnings("ignore:cached_setup is deprecated") - def test_request_cachedsetup_extrakey(self, testdir): - item1 = testdir.getitem("def test_func(): pass") - req1 = fixtures.FixtureRequest(item1) - values = ["hello", "world"] - - def setup(): - return values.pop() - - ret1 = req1.cached_setup(setup, extrakey=1) - ret2 = req1.cached_setup(setup, extrakey=2) - assert ret2 == "hello" - assert ret1 == "world" - ret1b = req1.cached_setup(setup, extrakey=1) - ret2b = req1.cached_setup(setup, extrakey=2) - assert ret1 == ret1b - assert ret2 == ret2b - - @pytest.mark.filterwarnings("ignore:cached_setup is deprecated") - def test_request_cachedsetup_cache_deletion(self, testdir): - item1 = testdir.getitem("def test_func(): pass") - req1 = fixtures.FixtureRequest(item1) - values = [] - - def setup(): - values.append("setup") - - def teardown(val): - values.append("teardown") - - req1.cached_setup(setup, teardown, scope="function") - assert values == ["setup"] - # artificial call of finalizer - setupstate = req1._pyfuncitem.session._setupstate - setupstate._callfinalizers(item1) - assert values == ["setup", "teardown"] - req1.cached_setup(setup, teardown, scope="function") - assert values == ["setup", "teardown", "setup"] - setupstate._callfinalizers(item1) - assert values == ["setup", "teardown", "setup", "teardown"] - - def test_request_cached_setup_two_args(self, testdir): - testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def arg1(request): - return request.cached_setup(lambda: 42) - @pytest.fixture - def arg2(request): - return request.cached_setup(lambda: 17) - def test_two_different_setups(arg1, arg2): - assert arg1 != arg2 - """ - ) - result = testdir.runpytest("-v", SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines(["*1 passed*"]) - - def test_request_cached_setup_getfixturevalue(self, testdir): - testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def arg1(request): - arg1 = request.getfixturevalue("arg2") - return request.cached_setup(lambda: arg1 + 1) - @pytest.fixture - def arg2(request): - return request.cached_setup(lambda: 10) - def test_two_funcarg(arg1): - assert arg1 == 11 - """ - ) - result = testdir.runpytest("-v", SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines(["*1 passed*"]) - - def test_request_cached_setup_functional(self, testdir): - testdir.makepyfile( - test_0=""" - import pytest - values = [] - @pytest.fixture - def something(request): - val = request.cached_setup(fsetup, fteardown) - return val - def fsetup(mycache=[1]): - values.append(mycache.pop()) - return values - def fteardown(something): - values.remove(something[0]) - values.append(2) - def test_list_once(something): - assert something == [1] - def test_list_twice(something): - assert something == [1] - """ - ) - testdir.makepyfile( - test_1=""" - import test_0 # should have run already - def test_check_test0_has_teardown_correct(): - assert test_0.values == [2] - """ - ) - result = testdir.runpytest("-v", SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines(["*3 passed*"]) - - def test_issue117_sessionscopeteardown(self, testdir): - testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def app(request): - app = request.cached_setup( - scope='session', - setup=lambda: 0, - teardown=lambda x: 3/x) - return app - def test_func(app): - pass - """ - ) - result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG) - assert result.ret != 0 - result.stdout.fnmatch_lines(["*3/x*", "*ZeroDivisionError*"]) - - class TestFixtureUsages(object): def test_noargfixturedec(self, testdir): testdir.makepyfile( @@ -2297,15 +2122,7 @@ class TestFixtureMarker(object): reprec = testdir.inline_run() reprec.assertoutcome(passed=4) - @pytest.mark.parametrize( - "method", - [ - 'request.getfixturevalue("arg")', - 'request.cached_setup(lambda: None, scope="function")', - ], - ids=["getfixturevalue", "cached_setup"], - ) - def test_scope_mismatch_various(self, testdir, method): + def test_scope_mismatch_various(self, testdir): testdir.makeconftest( """ import pytest @@ -2321,11 +2138,10 @@ class TestFixtureMarker(object): import pytest @pytest.fixture(scope="session") def arg(request): - %s + request.getfixturevalue("arg") def test_1(arg): pass """ - % method ) result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG) assert result.ret != 0 From 40b85d7ee89388245e7bb45b044993251c71664c Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 1 Dec 2018 16:41:59 -0200 Subject: [PATCH 2/2] Remove Metafunc.addcall Fix #3083 --- changelog/3083.removal.rst | 3 + doc/en/deprecations.rst | 31 +++++-- src/_pytest/deprecated.py | 5 -- src/_pytest/fixtures.py | 3 +- src/_pytest/python.py | 42 ---------- testing/acceptance_test.py | 5 +- testing/deprecated_test.py | 17 ---- testing/python/metafunc.py | 164 ++----------------------------------- 8 files changed, 37 insertions(+), 233 deletions(-) create mode 100644 changelog/3083.removal.rst diff --git a/changelog/3083.removal.rst b/changelog/3083.removal.rst new file mode 100644 index 000000000..ce689b94a --- /dev/null +++ b/changelog/3083.removal.rst @@ -0,0 +1,3 @@ +Remove ``Metafunc.addcall``. This was the predecessor mechanism to ``@pytest.mark.parametrize``. + +See our `docs `__ on information on how to update your code. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index b6ec4f245..5f57b51d2 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -168,13 +168,6 @@ Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py files because they will activate referenced plugins *globally*, which is surprising because for all other pytest features ``conftest.py`` files are only *active* for tests at or below it. -Metafunc.addcall -~~~~~~~~~~~~~~~~ - -.. deprecated:: 3.3 - -:meth:`_pytest.python.Metafunc.addcall` was a precursor to the current parametrized mechanism. Users should use -:meth:`_pytest.python.Metafunc.parametrize` instead. marks in ``pytest.mark.parametrize`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -274,6 +267,30 @@ Removed Features As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after an appropriate period of deprecation has passed. +Metafunc.addcall +~~~~~~~~~~~~~~~~ + +*Removed in version 4.0.* + +:meth:`_pytest.python.Metafunc.addcall` was a precursor to the current parametrized mechanism. Users should use +:meth:`_pytest.python.Metafunc.parametrize` instead. + +Example: + +.. code-block:: python + + def pytest_generate_tests(metafunc): + metafunc.addcall({"i": 1}, id="1") + metafunc.addcall({"i": 2}, id="2") + +Becomes: + +.. code-block:: python + + def pytest_generate_tests(metafunc): + metafunc.parametrize("i", [1, 2], ids=["1", "2"]) + + ``cached_setup`` ~~~~~~~~~~~~~~~~ diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 94ba6d037..00e066ff0 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -91,11 +91,6 @@ COLLECTOR_MAKEITEM = RemovedInPytest4Warning( "pycollector makeitem was removed as it is an accidentially leaked internal api" ) -METAFUNC_ADD_CALL = RemovedInPytest4Warning( - "Metafunc.addcall is deprecated and scheduled to be removed in pytest 4.0.\n" - "Please use Metafunc.parametrize instead." -) - PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = RemovedInPytest4Warning( "Defining pytest_plugins in a non-top-level conftest is deprecated, " "because it affects the entire directory tree in a non-explicit way.\n" diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 1519d2fbc..3e5ad5f73 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -568,8 +568,7 @@ class FixtureRequest(FuncargnamesCompatAttr): ) fail(msg, pytrace=False) else: - # indices might not be set if old-style metafunc.addcall() was used - param_index = funcitem.callspec.indices.get(argname, 0) + param_index = funcitem.callspec.indices[argname] # if a parametrize invocation set a scope it will override # the static scope defined with the fixture function paramscopenum = funcitem.callspec._arg2scopenum.get(argname) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 7ddcc2762..3db36fb19 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1022,48 +1022,6 @@ class Metafunc(fixtures.FuncargnamesCompatAttr): pytrace=False, ) - def addcall(self, funcargs=None, id=NOTSET, param=NOTSET): - """ Add a new call to the underlying test function during the collection phase of a test run. - - .. deprecated:: 3.3 - - Use :meth:`parametrize` instead. - - Note that request.addcall() is called during the test collection phase prior and - independently to actual test execution. You should only use addcall() - if you need to specify multiple arguments of a test function. - - :arg funcargs: argument keyword dictionary used when invoking - the test function. - - :arg id: used for reporting and identification purposes. If you - don't supply an `id` an automatic unique id will be generated. - - :arg param: a parameter which will be exposed to a later fixture function - invocation through the ``request.param`` attribute. - """ - warnings.warn(deprecated.METAFUNC_ADD_CALL, stacklevel=2) - - assert funcargs is None or isinstance(funcargs, dict) - if funcargs is not None: - for name in funcargs: - if name not in self.fixturenames: - fail("funcarg %r not used in this function." % name) - else: - funcargs = {} - if id is None: - raise ValueError("id=None not allowed") - if id is NOTSET: - id = len(self._calls) - id = str(id) - if id in self._ids: - raise ValueError("duplicate id %r" % id) - self._ids.add(id) - - cs = CallSpec2(self) - cs.setall(funcargs, id, param) - self._calls.append(cs) - def _find_parametrized_scope(argnames, arg2fixturedefs, indirect): """Find the most appropriate scope for a parametrized call based on its arguments. diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index b23cd7ca8..0b7af5338 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -299,7 +299,7 @@ class TestGeneralUsage(object): """ import pytest def pytest_generate_tests(metafunc): - metafunc.addcall({'x': 3}, id='hello-123') + metafunc.parametrize('x', [3], ids=['hello-123']) def pytest_runtest_setup(item): print(item.keywords) if 'hello-123' in item.keywords: @@ -316,8 +316,7 @@ class TestGeneralUsage(object): p = testdir.makepyfile( """ def pytest_generate_tests(metafunc): - metafunc.addcall({'i': 1}, id="1") - metafunc.addcall({'i': 2}, id="2") + metafunc.parametrize('i', [1, 2], ids=["1", "2"]) def test_func(i): pass """ diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index aa3c5e58b..71ea60050 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -105,23 +105,6 @@ def test_resultlog_is_deprecated(testdir): ) -def test_metafunc_addcall_deprecated(testdir): - testdir.makepyfile( - """ - def pytest_generate_tests(metafunc): - metafunc.addcall({'i': 1}) - metafunc.addcall({'i': 2}) - def test_func(i): - pass - """ - ) - res = testdir.runpytest("-s", SHOW_PYTEST_WARNINGS_ARG) - assert res.ret == 0 - res.stdout.fnmatch_lines( - ["*Metafunc.addcall is deprecated*", "*2 passed, 2 warnings*"] - ) - - def test_terminal_reporter_writer_attr(pytestconfig): """Check that TerminalReporter._tw is also available as 'writer' (#2984) This attribute is planned to be deprecated in 3.4. diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 833eb5641..7f9cdb5cc 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -54,66 +54,6 @@ class TestMetafunc(object): assert metafunc.function is func assert metafunc.cls is None - def test_addcall_no_args(self): - def func(arg1): - pass - - metafunc = self.Metafunc(func) - metafunc.addcall() - assert len(metafunc._calls) == 1 - call = metafunc._calls[0] - assert call.id == "0" - assert not hasattr(call, "param") - - def test_addcall_id(self): - def func(arg1): - pass - - metafunc = self.Metafunc(func) - pytest.raises(ValueError, metafunc.addcall, id=None) - - metafunc.addcall(id=1) - pytest.raises(ValueError, metafunc.addcall, id=1) - pytest.raises(ValueError, metafunc.addcall, id="1") - metafunc.addcall(id=2) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].id == "1" - assert metafunc._calls[1].id == "2" - - def test_addcall_param(self): - def func(arg1): - pass - - metafunc = self.Metafunc(func) - - class obj(object): - pass - - metafunc.addcall(param=obj) - metafunc.addcall(param=obj) - metafunc.addcall(param=1) - assert len(metafunc._calls) == 3 - assert metafunc._calls[0].getparam("arg1") == obj - assert metafunc._calls[1].getparam("arg1") == obj - assert metafunc._calls[2].getparam("arg1") == 1 - - def test_addcall_funcargs(self): - def func(x): - pass - - metafunc = self.Metafunc(func) - - class obj(object): - pass - - metafunc.addcall(funcargs={"x": 2}) - metafunc.addcall(funcargs={"x": 3}) - pytest.raises(pytest.fail.Exception, metafunc.addcall, {"xyz": 0}) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == {"x": 2} - assert metafunc._calls[1].funcargs == {"x": 3} - assert not hasattr(metafunc._calls[1], "param") - def test_parametrize_error(self): def func(x, y): pass @@ -508,19 +448,6 @@ class TestMetafunc(object): ) assert result == ["a0", "a1", "b0", "c", "b1"] - def test_addcall_and_parametrize(self): - def func(x, y): - pass - - metafunc = self.Metafunc(func) - metafunc.addcall({"x": 1}) - metafunc.parametrize("y", [2, 3]) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == {"x": 1, "y": 2} - assert metafunc._calls[1].funcargs == {"x": 1, "y": 3} - assert metafunc._calls[0].id == "0-2" - assert metafunc._calls[1].id == "0-3" - @pytest.mark.issue714 def test_parametrize_indirect(self): def func(x, y): @@ -710,20 +637,6 @@ class TestMetafunc(object): ["*already takes an argument 'y' with a default value"] ) - def test_addcalls_and_parametrize_indirect(self): - def func(x, y): - pass - - metafunc = self.Metafunc(func) - metafunc.addcall(param="123") - metafunc.parametrize("x", [1], indirect=True) - metafunc.parametrize("y", [2, 3], indirect=True) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == {} - assert metafunc._calls[1].funcargs == {} - assert metafunc._calls[0].params == dict(x=1, y=2) - assert metafunc._calls[1].params == dict(x=1, y=3) - def test_parametrize_functional(self, testdir): testdir.makepyfile( """ @@ -871,7 +784,7 @@ class TestMetafuncFunctional(object): # assumes that generate/provide runs in the same process import sys, pytest, six def pytest_generate_tests(metafunc): - metafunc.addcall(param=metafunc) + metafunc.parametrize('metafunc', [metafunc]) @pytest.fixture def metafunc(request): @@ -896,43 +809,15 @@ class TestMetafuncFunctional(object): result = testdir.runpytest(p, "-v", SHOW_PYTEST_WARNINGS_ARG) result.assert_outcomes(passed=2) - def test_addcall_with_two_funcargs_generators(self, testdir): - testdir.makeconftest( - """ - def pytest_generate_tests(metafunc): - assert "arg1" in metafunc.fixturenames - metafunc.addcall(funcargs=dict(arg1=1, arg2=2)) - """ - ) - p = testdir.makepyfile( - """ - def pytest_generate_tests(metafunc): - metafunc.addcall(funcargs=dict(arg1=1, arg2=1)) - - class TestClass(object): - def test_myfunc(self, arg1, arg2): - assert arg1 == arg2 - """ - ) - result = testdir.runpytest("-v", p, SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines( - ["*test_myfunc*0*PASS*", "*test_myfunc*1*FAIL*", "*1 failed, 1 passed*"] - ) - def test_two_functions(self, testdir): p = testdir.makepyfile( """ def pytest_generate_tests(metafunc): - metafunc.addcall(param=10) - metafunc.addcall(param=20) - - import pytest - @pytest.fixture - def arg1(request): - return request.param + metafunc.parametrize('arg1', [10, 20], ids=['0', '1']) def test_func1(arg1): assert arg1 == 10 + def test_func2(arg1): assert arg1 in (10, 20) """ @@ -943,6 +828,7 @@ class TestMetafuncFunctional(object): "*test_func1*0*PASS*", "*test_func1*1*FAIL*", "*test_func2*PASS*", + "*test_func2*PASS*", "*1 failed, 3 passed*", ] ) @@ -961,47 +847,12 @@ class TestMetafuncFunctional(object): result = testdir.runpytest(p) result.assert_outcomes(passed=1) - def test_generate_plugin_and_module(self, testdir): - testdir.makeconftest( - """ - def pytest_generate_tests(metafunc): - assert "arg1" in metafunc.fixturenames - metafunc.addcall(id="world", param=(2,100)) - """ - ) - p = testdir.makepyfile( - """ - def pytest_generate_tests(metafunc): - metafunc.addcall(param=(1,1), id="hello") - - import pytest - @pytest.fixture - def arg1(request): - return request.param[0] - @pytest.fixture - def arg2(request): - return request.param[1] - - class TestClass(object): - def test_myfunc(self, arg1, arg2): - assert arg1 == arg2 - """ - ) - result = testdir.runpytest("-v", p, SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines( - [ - "*test_myfunc*hello*PASS*", - "*test_myfunc*world*FAIL*", - "*1 failed, 1 passed*", - ] - ) - def test_generate_tests_in_class(self, testdir): p = testdir.makepyfile( """ class TestClass(object): def pytest_generate_tests(self, metafunc): - metafunc.addcall(funcargs={'hello': 'world'}, id="hello") + metafunc.parametrize('hello', ['world'], ids=['hellow']) def test_myfunc(self, hello): assert hello == "world" @@ -1014,8 +865,7 @@ class TestMetafuncFunctional(object): p = testdir.makepyfile( """ def pytest_generate_tests(metafunc): - metafunc.addcall({'arg1': 10}) - metafunc.addcall({'arg1': 20}) + metafunc.parametrize('arg1', [10, 20], ids=["0", "1"]) class TestClass(object): def test_func(self, arg1): @@ -1032,7 +882,7 @@ class TestMetafuncFunctional(object): p = testdir.makepyfile( """ def pytest_generate_tests(metafunc): - metafunc.addcall({'arg1': 1}) + metafunc.parametrize('arg1', [1]) class TestClass(object): def test_method(self, arg1):