mid-scale refactoring to make request API available directly on items.
This commit was slightly tricky because i want to backward compatibility especially for the oejskit plugin which uses Funcarg-filling for non-Function objects.
This commit is contained in:
+28
-41
@@ -11,26 +11,27 @@ Injecting objects into test functions (funcargs)
|
||||
Dependency injection through function arguments
|
||||
=================================================
|
||||
|
||||
py.test lets you inject objects into test functions and precisely
|
||||
control their life cycle in relation to the test execution. It is
|
||||
also possible to run a test function multiple times with different objects.
|
||||
py.test lets you inject objects into test invocations and precisely
|
||||
control their life cycle in relation to the overall test execution. Moreover,
|
||||
you can run a test function multiple times injecting different objects.
|
||||
|
||||
The basic mechanism for injecting objects is also called the
|
||||
*funcarg mechanism* because objects are ultimately injected
|
||||
by calling a test function with it as an argument. Unlike the
|
||||
classical xUnit approach *funcargs* relate more to `Dependency Injection`_
|
||||
because they help to de-couple test code from objects required for
|
||||
them to execute.
|
||||
them to execute. At test writing time you do not need to care for the
|
||||
details of how your required resources are constructed or if they
|
||||
live through a function, class, module or session scope.
|
||||
|
||||
.. _`Dependency injection`: http://en.wikipedia.org/wiki/Dependency_injection
|
||||
|
||||
To create a value with which to call a test function a factory function
|
||||
is called which gets full access to the test function context and can
|
||||
register finalizers or invoke lifecycle-caching helpers. The factory
|
||||
can be implemented in same test class or test module, or in a
|
||||
per-directory ``conftest.py`` file or even in an external plugin. This
|
||||
allows full de-coupling of test code and objects needed for test
|
||||
execution.
|
||||
can be implemented in same test class or test module, in a
|
||||
per-directory ``conftest.py`` file or in an external plugin. This
|
||||
allows total de-coupling of test and setup code.
|
||||
|
||||
A test function may be invoked multiple times in which case we
|
||||
speak of :ref:`parametrized testing <parametrizing-tests>`. This can be
|
||||
@@ -38,7 +39,7 @@ very useful if you want to test e.g. against different database backends
|
||||
or with multiple numerical arguments sets and want to reuse the same set
|
||||
of test functions.
|
||||
|
||||
py.test comes with :ref:`builtinfuncargs` and there are some refined usages in the examples section.
|
||||
py.test comes with some :ref:`builtinfuncargs` and there are some refined usages in the examples section.
|
||||
|
||||
.. _funcarg:
|
||||
|
||||
@@ -55,10 +56,8 @@ Let's look at a simple self-contained test module::
|
||||
assert myfuncarg == 17
|
||||
|
||||
This test function needs an injected object named ``myfuncarg``.
|
||||
py.test will discover and call the factory named
|
||||
``pytest_funcarg__myfuncarg`` within the same module in this case.
|
||||
|
||||
Running the test looks like this::
|
||||
py.test will automatically discover and call the ``pytest_funcarg__myfuncarg``
|
||||
factory. Running the test looks like this::
|
||||
|
||||
$ py.test test_simplefactory.py
|
||||
=========================== test session starts ============================
|
||||
@@ -79,9 +78,9 @@ Running the test looks like this::
|
||||
test_simplefactory.py:5: AssertionError
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
|
||||
This means that indeed the test function was called with a ``myfuncarg``
|
||||
argument value of ``42`` and the assert fails. Here is how py.test
|
||||
comes to call the test function this way:
|
||||
This shows that the test function was called with a ``myfuncarg``
|
||||
argument value of ``42`` and the assert fails as expected. Here is
|
||||
how py.test comes to call the test function this way:
|
||||
|
||||
1. py.test :ref:`finds <test discovery>` the ``test_function`` because
|
||||
of the ``test_`` prefix. The test function needs a function argument
|
||||
@@ -99,13 +98,22 @@ 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 always issue::
|
||||
.. Note::
|
||||
|
||||
py.test --funcargs test_simplefactory.py
|
||||
You can always issue::
|
||||
|
||||
to see available function arguments (which you can also
|
||||
think of as "resources").
|
||||
py.test --funcargs test_simplefactory.py
|
||||
|
||||
to see available function arguments.
|
||||
|
||||
The request object passed to factories
|
||||
-----------------------------------------
|
||||
|
||||
Each funcarg factory receives a :py:class:`~_pytest.main.Request` object which
|
||||
provides methods to manage caching and finalization in the context of the
|
||||
test invocation as well as several attributes of the the underlying test item. In fact, as of version pytest-2.3, the request API is implemented on all Item
|
||||
objects and therefore the request object has general :py:class:`Node attributes and methods <_pytest.main.Node>` attributes. This is a backward compatible
|
||||
change so no changes are neccessary for pre-2.3 funcarg factories.
|
||||
|
||||
.. _`parametrizing tests, generalized`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/
|
||||
|
||||
@@ -116,27 +124,6 @@ think of as "resources").
|
||||
.. _`funcarg factory`:
|
||||
.. _factory:
|
||||
|
||||
The funcarg **request** object
|
||||
=============================================
|
||||
|
||||
Each funcarg factory receives a **request** object 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.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`:
|
||||
.. _`parametrized test functions`:
|
||||
|
||||
Reference in New Issue
Block a user