test_ok1/doc/funcargs.txt

221 lines
7.2 KiB
Plaintext

==============================================================
creating and managing test function arguments
==============================================================
.. currentmodule:: pytest.plugin.python
.. _`funcarg mechanism`:
Test function arguments and factories
=================================================
A *funcarg* is the short name for "test function argument". Like
any other Python function a test function can receive one or multiple
arguments. When ``py.test`` prepares running a test function
it looks at the neccessary function arguments, locates and calls
factories which then provide the values to be passed to the function.
Basic funcarg example
-----------------------
Let's look at a simple self-contained example that you can put
into a test module::
# content of ./test_simplefactory.py
def pytest_funcarg__myfuncarg(request):
return 42
def test_function(myfuncarg):
assert myfuncarg == 17
Running the test looks like this::
$ py.test test_simplefactory.py
=========================== test session starts ============================
platform linux2 -- Python 2.6.5 -- pytest-2.0.0.dev17
test path 1: test_simplefactory.py
test_simplefactory.py F
================================= FAILURES =================================
______________________________ test_function _______________________________
myfuncarg = 42
def test_function(myfuncarg):
> assert myfuncarg == 17
E assert 42 == 17
test_simplefactory.py:5: AssertionError
========================= 1 failed in 0.02 seconds =========================
This means that the test function was called with a ``myfuncarg`` value
of ``42`` and the assert fails accordingly. Here is how py.test
calls the test function:
1. py.test discovers the ``test_function`` because of the ``test_`` prefix.
The test function needs a function argument named ``myfuncarg``.
A matching factory function is discovered by looking for the
name ``pytest_funcarg__myfuncarg``.
2. ``pytest_funcarg__myfuncarg(request)`` is called and
returns the value for ``myfuncarg``.
3. ``test_function(42)`` call is executed.
Note that if you misspell a function argument or want
to use one that isn't available, you'll see an error
with a list of available function arguments. You can
also issue::
py.test --funcargs test_simplefactory.py
to see available function arguments (which you can also
think of as "resources").
.. _`parametrizing tests, generalized`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/
.. _`blog post about the monkeypatch funcarg`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/
.. _`xUnit style`: xunit_setup.html
.. _`funcarg factory`:
.. _factory:
The funcarg **request** object
=============================================
Each funcarg factory receives a **request** object which is tied to a
specific test function call. A request object is passed to a funcarg
factory and provides access to test configuration and context:
.. autoclass:: pytest.plugin.python.FuncargRequest()
:members: function,cls,module,keywords,config
.. _`useful caching and finalization helpers`:
.. automethod:: FuncargRequest.addfinalizer
.. automethod:: FuncargRequest.cached_setup
.. automethod:: FuncargRequest.applymarker
.. automethod:: FuncargRequest.getfuncargvalue
.. _`test generators`:
.. _`parametrizing-tests`:
Parametrizing multiple calls to a test function
===========================================================
You can parametrize multiple runs of the same test
function by adding new test function calls with different
function argument values. Let's look at a simple self-contained
example:
Basic generated test example
----------------------------
Let's consider this test module::
# content of test_example.py
def pytest_generate_tests(metafunc):
if "numiter" in metafunc.funcargnames:
for i in range(10):
metafunc.addcall(funcargs=dict(numiter=i))
def test_func(numiter):
assert numiter < 9
Running this::
$ py.test test_example.py
=========================== test session starts ============================
platform linux2 -- Python 2.6.5 -- pytest-2.0.0.dev17
test path 1: test_example.py
test_example.py .........F
================================= FAILURES =================================
_______________________________ test_func[9] _______________________________
numiter = 9
def test_func(numiter):
> assert numiter < 9
E assert 9 < 9
test_example.py:7: AssertionError
==================== 1 failed, 9 passed in 0.03 seconds ====================
Note that the ``pytest_generate_tests(metafunc)`` hook is called during
the test collection phase. You can have a look at it with this::
$ py.test --collectonly test_example.py
<Directory 'doc-exec-167'>
<Module 'test_example.py'>
<Function 'test_func[0]'>
<Function 'test_func[1]'>
<Function 'test_func[2]'>
<Function 'test_func[3]'>
<Function 'test_func[4]'>
<Function 'test_func[5]'>
<Function 'test_func[6]'>
<Function 'test_func[7]'>
<Function 'test_func[8]'>
<Function 'test_func[9]'>
If you want to select only the run with the value ``7`` you could do::
$ py.test -v -k 7 test_example.py # or -k test_func[7]
=========================== test session starts ============================
platform linux2 -- Python 2.6.5 -- pytest-2.0.0.dev17 -- /home/hpk/venv/0/bin/python
test path 1: test_example.py
test_example.py:6: test_func[0] PASSED
test_example.py:6: test_func[1] PASSED
test_example.py:6: test_func[2] PASSED
test_example.py:6: test_func[3] PASSED
test_example.py:6: test_func[4] PASSED
test_example.py:6: test_func[5] PASSED
test_example.py:6: test_func[6] PASSED
test_example.py:6: test_func[7] PASSED
test_example.py:6: test_func[8] PASSED
test_example.py:6: test_func[9] FAILED
================================= FAILURES =================================
_______________________________ test_func[9] _______________________________
numiter = 9
def test_func(numiter):
> assert numiter < 9
E assert 9 < 9
test_example.py:7: AssertionError
==================== 1 failed, 9 passed in 0.04 seconds ====================
.. _`metafunc object`:
The **metafunc** object
-------------------------------------------
metafunc objects are passed to the ``pytest_generate_tests`` hook.
They help to inspect a testfunction and to generate tests
according to test configuration or values specified
in the class or module where a test function is defined:
``metafunc.funcargnames``: set of required function arguments for given function
``metafunc.function``: underlying python test function
``metafunc.cls``: class object where the test function is defined in or None.
``metafunc.module``: the module object where the test function is defined in.
``metafunc.config``: access to command line opts and general config
.. automethod:: Metafunc.addcall(funcargs=None, id=_notexists, param=_notexists)