+XYZZY I think this is very important, but it is written in a most confusing
+style. You need to start with a 'what is dependency injection' followed by
+a 'when is this useful?/why would you want to do this?' section, followed
+by what is a factory, then how do you make one, and then finally get to
+the basic example. Which shouldn't be a more or less meaningless example
+like the one that you have now. A still trivial, but more expressive
+example would be to inject a list of values into a test that asserts
+that every parameter it receives is even. When you send it an odd value,
+it will fail. This gives a much better sense of what this thing is good
+for. I think that people who really should be using this are not because
+they don't recognise what it is good for.
creating and managing test function arguments
Dependency injection through function arguments
allows to inject values into test functions through the *funcarg
+py.test inject values into test functions through the *funcarg
mechanism*: For each argument name in a test function signature a factory is
looked up and called to create the value. The factory can live in the
same test class, test module, in a per-directory ``conftest.py`` file or
in an external plugin. It has full access to the requesting test
, can register finalizers and invoke lifecycle-caching
+function can register finalizers and invoke lifecycle-caching
helpers. As can be expected from a systematic dependency
injection mechanism, this allows full de-coupling of resource and
fixture setup from test code, enabling more maintainable and
+XYZZY I would really prefer a lesson on how to make a factory before
+you move onto the simple example. I'd like to know about requests
+before this example, as well.
========================= 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
+of ``42`` and the assert fails accordingly. Here is how py.test
comes to call the test function this way:
1. py.test :ref:`finds <test discovery>` the ``test_function`` because
named ``myfuncarg``. A matching factory function is discovered by
looking for the name ``pytest_funcarg__myfuncarg``.
+XYZZY I think this is confusing. Better to explain this not as, here,
+run this, and then explain what has happened, but write down what you
+want to do, and then what you need to write in your test. Right now I
+think that there is nothing at all special about the name myfuncarg and
+you could have as easily called it 'x', or 'foo', or 'number'. However
+there *is* something special about the name pytest_funcarg__myfuncarg(request):
+All py.test factories have to have the prefix pytest_funcarg_ followed
+by whatever variable names you like. However, I have no clue about
+the request argument. Why couldn't you write this as
+def pytest_funcarg__myfuncarg(): ? In any case, if some of the words
+'pytest_funcarg_' are magic, then it would be better if the argument that
+could be anything was named something other than myfuncarg. The first time
+I read this I thought that this name was magic, too.
2. ``pytest_funcarg__myfuncarg(request)`` is called and
returns the value for ``myfuncarg``.
3. the test function can now be called: ``test_function(42)``
and results in the above exception because of the assertion
+ results in the above exception because of the assertion
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
+with a list of available function arguments.
+XYZZY Worth printing this here to show it. Mostly this is so that
+people who paste things they do not understand into their browser
+looking for an explanation will be googled to this page.
py.test --funcargs test_simplefactory.py
-to see available function arguments (which you can also
+to see available function arguments (which you can also
think of as "resources").
+XYZZY ah, here we get an understanding of why there is a request. ok.
+but explaining this earlier would not be a bad thing to do. I'd really
+like a section 'how to make a factory' which mentions this point
+before you give the example of it working in practice.
The funcarg **request** object
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