diff --git a/doc/en/example/costlysetup/conftest.py b/doc/en/example/costlysetup/conftest.py index 0b83d42e8..4f456fae3 100644 --- a/doc/en/example/costlysetup/conftest.py +++ b/doc/en/example/costlysetup/conftest.py @@ -1,10 +1,11 @@ -def pytest_funcarg__setup(request): - return request.cached_setup( - setup=lambda: CostlySetup(), - teardown=lambda costlysetup: costlysetup.finalize(), - scope="session", - ) +import pytest + +@pytest.factory("session") +def setup(testcontext): + setup = CostlySetup() + testcontext.addfinalizer(setup.finalize) + return setup class CostlySetup: def __init__(self): diff --git a/doc/en/example/multipython.py b/doc/en/example/multipython.py index c0d58aec5..af5377668 100644 --- a/doc/en/example/multipython.py +++ b/doc/en/example/multipython.py @@ -5,29 +5,14 @@ serialization via the pickle module. import py, pytest pythonlist = ['python2.4', 'python2.5', 'python2.6', 'python2.7', 'python2.8'] - -def pytest_generate_tests(metafunc): - # we parametrize all "python1" and "python2" arguments to iterate - # over the python interpreters of our list above - the actual - # setup and lookup of interpreters in the python1/python2 factories - # respectively. - for arg in metafunc.funcargnames: - if arg in ("python1", "python2"): - metafunc.parametrize(arg, pythonlist, indirect=True) - -@pytest.mark.parametrize("obj", [42, {}, {1:3},]) -def test_basic_objects(python1, python2, obj): - python1.dumps(obj) - python2.load_and_is_true("obj == %s" % obj) - -def pytest_funcarg__python1(request): - tmpdir = request.getfuncargvalue("tmpdir") +@pytest.factory(params=pythonlist) +def python1(testcontext, tmpdir): picklefile = tmpdir.join("data.pickle") - return Python(request.param, picklefile) + return Python(testcontext.param, picklefile) -def pytest_funcarg__python2(request): - python1 = request.getfuncargvalue("python1") - return Python(request.param, python1.picklefile) +@pytest.factory(params=pythonlist) +def python2(testcontext, python1): + return Python(testcontext.param, python1.picklefile) class Python: def __init__(self, version, picklefile): @@ -58,3 +43,8 @@ class Python: """ % (str(self.picklefile), expression))) print (loadfile) py.process.cmdexec("%s %s" %(self.pythonpath, loadfile)) + +@pytest.mark.parametrize("obj", [42, {}, {1:3},]) +def test_basic_objects(python1, python2, obj): + python1.dumps(obj) + python2.load_and_is_true("obj == %s" % obj) diff --git a/doc/en/faq.txt b/doc/en/faq.txt index cb233beed..34abe4de4 100644 --- a/doc/en/faq.txt +++ b/doc/en/faq.txt @@ -123,6 +123,11 @@ it is nice to be able to search for ``pytest_funcarg__MYARG`` in source code and safely find all factory functions for the ``MYARG`` function argument. +.. note:: + + With pytest-2.3 you can use the :ref:`@pytest.factory` decorator + to mark a function as a funcarg factory. + .. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration Can I yield multiple values from a funcarg factory function? @@ -141,8 +146,12 @@ is not possible: policy - in real-world examples some combinations often should not run. -Use the `pytest_generate_tests`_ hook to solve both issues -and implement the `parametrization scheme of your choice`_. +However, with pytest-2.3 you can use the :ref:`@pytest.factory` decorator +and specify ``params`` so that all tests depending on the factory-created +resource will run multiple times with different parameters. + +You can also use the `pytest_generate_tests`_ hook to +implement the `parametrization scheme of your choice`_. .. _`pytest_generate_tests`: test/funcargs.html#parametrizing-tests .. _`parametrization scheme of your choice`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/ diff --git a/doc/en/funcarg_compare.txt b/doc/en/funcarg_compare.txt index 3d12706e4..7ca90619b 100644 --- a/doc/en/funcarg_compare.txt +++ b/doc/en/funcarg_compare.txt @@ -88,7 +88,7 @@ parametrization, i.e. calling a test multiple times with different value sets. pytest-2.3 introduces a decorator for use on the factory itself:: @pytest.factory(params=["mysql", "pg"]) - def pytest_funcarg__db(testcontext): + def db(testcontext): ... # use testcontext.param Here the factory will be invoked twice (with the respective "mysql" @@ -105,7 +105,7 @@ functions/classes were parametrized via Of course it's perfectly fine to combine parametrization and scoping:: @pytest.factory(scope="session", params=["mysql", "pg"]) - def pytest_funcarg__db(testcontext): + def db(testcontext): if testcontext.param == "mysql": db = MySQL() elif testcontext.param == "pg": @@ -137,7 +137,9 @@ aka:: def pytest_funcarg__db(request): ... -It is recommended to use the resource decorator, however. + +But it is then not possible to define scoping and parametrization. +It is thus recommended to use the factory decorator. solving per-session setup / the new @setup marker