
Frequently Asked Questions
**************************

* On naming, nosetests, licensing and magic

  * Why the "py" naming?  Why not "pytest"?

  * Why the "py.test" naming?

  * What's py.test's relation to "nosetests"?

  * What's this "magic" with py.test?

  * Where does my "py.test" come/import from?

* function arguments, parametrized tests and setup

  * Is using funcarg- versus xUnit-based setup a style question?

  * Why the "pytest_funcarg__*" name for funcarg factories?

  * Can I yield multiple values from a factory function?

* py.test interaction with other packages

  * Issues with py.test, multiprocess and setuptools?


On naming, nosetests, licensing and magic
=========================================


Why the "py" naming?  Why not "pytest"?
---------------------------------------

This mostly has historic reasons - the aim is to get away from the
somewhat questionable 'py' name at some point.  These days (2010) the
'py' library almost completely comprises APIs that are used by the
"py.test" tool.  There also are some other uses, e.g. of the
"py.path.local()" and other path implementations.  So it requires some
work to factor them out and do the shift.


Why the "py.test" naming?
-------------------------

because of TAB-completion under Bash/Shells.  If you hit "py.<TAB>"
you'll get a list of available development tools that all share the
"py." prefix.  Another motivation was to unify the package ("py.test")
and tool filename.


What's py.test's relation to "nosetests"?
-----------------------------------------

py.test and nose share basic philosophy when it comes to running
Python tests.  In fact, with py.test-1.1.0 it is ever easier to run
many test suites that currently work with "nosetests".  nose was
created as a clone of "py.test" when py.test was in the "0.8" release
cycle so some of the newer features introduced with py.test-1.0 and
py.test-1.1 have no counterpart in nose.


What's this "magic" with py.test?
---------------------------------

issues where people have used the term "magic" in the past:

* py/__init__.py uses the apipkg mechanism for lazy-importing and full
  control on what API you get when importing "import py".

* when an "assert" statement fails, py.test re-interprets the
  expression to show intermediate values if a test fails.  If your
  expression has side effects the intermediate values may not be the
  same, obfuscating the initial error (this is also explained at the
  command line if it happens). "py.test --no-assert" turns off assert
  re-intepretation. Sidenote: it is good practise to avoid asserts
  with side effects.


Where does my "py.test" come/import from?
-----------------------------------------

You can issue:

   py.test --version

which tells you both version and import location of the tool.


function arguments, parametrized tests and setup
================================================


Is using funcarg- versus xUnit-based setup a style question?
------------------------------------------------------------

It depends. For simple applications or for people experienced with
nose or unittest-style test setup using xUnit style setup make some
sense.  For larger test suites, parametrized testing or setup of
complex test resources using funcargs is recommended. Moreover,
funcargs are ideal for writing advanced test support code (like e.g.
the monkeypatch, the tmpdir or capture funcargs) because the support
code can register setup/teardown functions in a managed
class/module/function scope.


Why the "pytest_funcarg__*" name for funcarg factories?
-------------------------------------------------------

When experimenting with funcargs an explicit registration mechanism
was considered.  But lacking a good use case for this indirection and
flexibility we decided to go for Convention over Configuration and
allow to directly specify the factory.  Besides removing the need for
an indirection it allows to "grep" for "pytest_funcarg__MYARG" and
will safely find all factory functions for the "MYARG" function
argument.  It helps to alleviate the de-coupling of function argument
usage and creation.


Can I yield multiple values from a factory function?
----------------------------------------------------

There are two conceptual reasons why yielding from a factory function
is not possible:

* Calling factories for obtaining test function arguments is part of
  setting up and running a test.  At that point it is not possible to
  add new test calls to the test collection anymore.

* If multiple factories yielded values there would be no natural place
  to determine the combination 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.


py.test interaction with other packages
=======================================


Issues with py.test, multiprocess and setuptools?
-------------------------------------------------

On windows the multiprocess package will instantiate sub processes by
pickling and thus implicitely re-import a lot of local modules.
Unfortuantely, setuptools-0.6.11 does not "if __name__=='__main__'"
protect its generated command line script.  This leads to infinite
recursion when running a test that instantiates Processes. There are
these workarounds:

* install Distribute as a drop-in replacement for setuptools and
  install py.test

* directly use a checkout which avoids all setuptools/Distribute
  installation

If those options are not available to you, you may also manually fix
the script that is created by setuptools by inserting an "if __name__
== '__main__'".  Or you can create a "pytest.py" script with this
content and invoke that with the python version:

   import py
   if __name__ == '__main__':
       py.cmdline.pytest()
