================================== Frequently Asked Questions ================================== .. contents:: :local: :depth: 2 On naming, nosetests, licensing and magic =========================================== Why the ``py`` naming? what is it? ------------------------------------ Because the name was kind of available and there was the idea to have the package evolve into a "standard" library kind of thing that works cross-python versions and is not tied to a particular CPython revision or its release cycle. Clearly, this was ambitious and the naming has maybe haunted the project rather than helping it. There may be a project name change and possibly a split up into different projects sometime. Why the ``py.test`` naming? ------------------------------------ the py lib contains other command line tools that all share the ``py.`` prefix which makes it easy to use TAB-completion on the shell. Another motivation was to make it obvious where testing functionality for the ``py.test`` command line tool is: in the ``py.test`` package name space. 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.0.1 it is easy to run many test suites that currently work with ``nosetests``. nose_ was created as a clone of ``py.test`` when it was in the ``0.8`` release cycle so some of the newer features_ introduced with py.test-1.0 have no counterpart in nose_. .. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.1/ .. _features: test/features.html .. _whygpl: Why did you choose a GPL-style license? ---------------------------------------- Older versions of the py lib and py.test (up until 1.0.x) were licensed under the MIT license. Starting with the 1.1 series Holger Krekel - being the main maintainer and developer since several years - decided to go for a GPL-style license mainly for these reasons: 1. increase likelyness of flow-back, contributions and publicity. 2. make use of the FSF_ efforts which produced a consistent and interoperable legal framework. 3. Potentially get some money from dual-licensing to companies. Developers want to co-operate no matter what context they are in, commercial, free, whatever. BSD-licenses sound like a fit because they minimize the need for checking for constraints from the company or legal department. They allow to use and modify software for whatever purpose. However, developers wanting to produce free software for a living often need to connect to a sustainable revenue system. When releasing software for public use they seek means, some security on getting something back: Contributions, recognition or money. The GPL license tries to foster a universe of free software and force proprietary players to contribute back. The py lib choose the Lesser GPL. It strikes a balance because it allows the code to interact in proprietary contexts and increases likelyness of flow backs. If you do have or get actual practical issues regarding licensing please get in contact_. .. _fsf: http://www.fsf.org .. _contact: contact.html What's all this "magic" with py.test? ---------------------------------------- "All this magic" usually boils down to two issues: * There is a special tweak to importing: `py/__init__.py`_ contains a dictionary which maps the importable ``py.*`` namespaces to objects in files. When looking at the project source code you see imports like ``from py.__.test.session import Session``. The the double ``__`` underscore indicates the "normal" python filesystem/namespace coupled import, i.e. it points to ``py/test/session.py``'s ``Session`` object. However, from the outside you use the "non-underscore" `py namespaces`_ so this distinction usually only shows up if you hack on internal code or see internal tracebacks. * when an ``assert`` fails, py.test re-interprets the expression to show intermediate values. This allows to use the plain ``assert`` statement instead of the many methods that you otherwise need to mimick this behaviour. This means that in case of a failing assert, your expressions gets evaluated *twice*. If your expression has side effects the outcome may be different. If the test suddenly passes you will get a detailed message. It is good practise, anyway, to not have asserts with side effects. ``py.test --nomagic`` turns off assert re-intepretation. Other than that, ``py.test`` has bugs or quirks like any other computer software. In fact, it has a *strong* focus on running robustly and has over a thousand automated tests for its own code base. .. _`py namespaces`: index.html .. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/1.0.x/py/__init__.py function arguments and parametrized tests =============================================== .. _`why pytest_pyfuncarg__ methods?`: 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 alleviates the de-coupling of function argument usage and creation. .. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration Can i yield multiple values from a factory function? ----------------------------------------------------- There are two 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`_. .. _`pytest_generate_tests`: test/funcargs.html#parametrizing-tests .. _`parametrization scheme of your choice`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/