incorporate typo/grammar fixes from Laura and respond to a number of issues she raised in comments.
Also fixed links and some other bits and pieces.
This commit is contained in:
		
							parent
							
								
									070c73ff2f
								
							
						
					
					
						commit
						fadd1a2313
					
				|  | @ -29,9 +29,8 @@ Changes between 2.0.1 and 2.0.2 | |||
|   a newer py lib version the py.path.local() implementation acknowledges | ||||
|   this. | ||||
| 
 | ||||
| - fixed typos in the docs (thanks Victor, Brianna) and particular | ||||
|   thanks to Laura who also revieved the documentation which | ||||
|   lead to some improvements. | ||||
| - fixed typos in the docs (thanks Victor Garcia, Brianna Laugher) and particular | ||||
|   thanks to Laura Creighton who also revieved parts of the documentation. | ||||
| 
 | ||||
| Changes between 2.0.0 and 2.0.1 | ||||
| ---------------------------------------------- | ||||
|  |  | |||
|  | @ -192,18 +192,16 @@ class CaptureManager: | |||
|         return rep | ||||
| 
 | ||||
| def pytest_funcarg__capsys(request): | ||||
|     """captures writes to sys.stdout/sys.stderr and makes | ||||
|     them available successively via a ``capsys.readouterr()`` method | ||||
|     which returns a ``(out, err)`` tuple of captured snapshot strings. | ||||
|     """enables capturing of writes to sys.stdout/sys.stderr and makes | ||||
|     captured output available via ``capsys.readouterr()`` method calls | ||||
|     which return a ``(out, err)`` tuple. | ||||
|     """ | ||||
|     return CaptureFuncarg(py.io.StdCapture) | ||||
| 
 | ||||
| def pytest_funcarg__capfd(request): | ||||
|     """captures writes to file descriptors 1 and 2 and makes | ||||
|     snapshotted ``(out, err)`` string tuples available | ||||
|     via the ``capsys.readouterr()`` method.  If the underlying | ||||
|     platform does not have ``os.dup`` (e.g. Jython) tests using | ||||
|     this funcarg will automatically skip. | ||||
|     """enables capturing of writes to file descriptors 1 and 2 and makes | ||||
|     captured output available via ``capsys.readouterr()`` method calls | ||||
|     which return a ``(out, err)`` tuple. | ||||
|     """ | ||||
|     if not hasattr(os, 'dup'): | ||||
|         py.test.skip("capfd funcarg needs os.dup") | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ def pytest_funcarg__monkeypatch(request): | |||
|         monkeypatch.delenv(name, value, raising=True) | ||||
|         monkeypatch.syspath_prepend(path) | ||||
| 
 | ||||
|     All modifications will be undone when the requesting | ||||
|     test function finished its execution.  The ``raising`` | ||||
|     All modifications will be undone after the requesting | ||||
|     test function has finished. The ``raising`` | ||||
|     parameter determines if a KeyError or AttributeError | ||||
|     will be raised if the set/deletion operation has no target. | ||||
|     """ | ||||
|  |  | |||
|  | @ -8,6 +8,9 @@ def pytest_funcarg__recwarn(request): | |||
| 
 | ||||
|     * ``pop(category=None)``: return last warning matching the category. | ||||
|     * ``clear()``: clear list of warnings | ||||
|     | ||||
|     See http://docs.python.org/library/warnings.html for information | ||||
|     on warning categories. | ||||
|     """ | ||||
|     if sys.version_info >= (2,7): | ||||
|         import warnings | ||||
|  |  | |||
|  | @ -59,7 +59,7 @@ def pytest_unconfigure(config): | |||
| 
 | ||||
| def pytest_funcarg__tmpdir(request): | ||||
|     """return a temporary directory path object | ||||
|     unique to each test function invocation, | ||||
|     which is unique to each test function invocation, | ||||
|     created as a sub directory of the base temporary | ||||
|     directory.  The returned object is a `py.path.local`_ | ||||
|     path object. | ||||
|  |  | |||
|  | @ -1,15 +1,15 @@ | |||
| 
 | ||||
| Writing and reporting of assertions in tests | ||||
| ============================================ | ||||
| The writing and reporting of assertions in tests | ||||
| ================================================== | ||||
| 
 | ||||
| .. _`assert with the assert statement`: | ||||
| 
 | ||||
| assert with the ``assert`` statement | ||||
| --------------------------------------------------------- | ||||
| 
 | ||||
| ``py.test`` allows to use the standard python ``assert`` for verifying | ||||
| ``py.test`` allows you to use the standard python ``assert`` for verifying | ||||
| expectations and values in Python tests.  For example, you can write the | ||||
| following in your tests:: | ||||
| following:: | ||||
| 
 | ||||
|     # content of test_assert1.py | ||||
|     def f(): | ||||
|  | @ -18,12 +18,12 @@ following in your tests:: | |||
|     def test_function(): | ||||
|         assert f() == 4 | ||||
| 
 | ||||
| to state that your object has a certain ``attribute``. In case this | ||||
| to assert that your object returns a certain value. If this | ||||
| assertion fails you will see the value of ``x``:: | ||||
| 
 | ||||
|     $ py.test test_assert1.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_assert1.py F | ||||
|  | @ -37,30 +37,33 @@ assertion fails you will see the value of ``x``:: | |||
|     E        +  where 3 = f() | ||||
|      | ||||
|     test_assert1.py:5: AssertionError | ||||
|     ========================= 1 failed in 0.02 seconds ========================= | ||||
|     ========================= 1 failed in 0.03 seconds ========================= | ||||
| 
 | ||||
| Reporting details about the failing assertion is achieved by re-evaluating | ||||
| the assert expression and recording intermediate values. | ||||
| the assert expression and recording the intermediate values. | ||||
| 
 | ||||
| Note: If evaluating the assert expression has side effects you may get a | ||||
| warning that the intermediate values could not be determined safely.  A | ||||
| common example for this issue is reading from a file and comparing in one | ||||
| line:: | ||||
| common example of this issue is an assertion which reads from a file:: | ||||
| 
 | ||||
|         assert f.read() != '...' | ||||
| 
 | ||||
| This might fail but when re-interpretation comes along it might pass.  You can | ||||
| rewrite this (and any other expression with side effects) easily, though:: | ||||
| If this assertion fails then the re-evaluation will probably succeed! | ||||
| This is because ``f.read()`` will return an empty string when it is | ||||
| called the second time during the re-evaluation.  However, it is | ||||
| easy to rewrite the assertion and avoid any trouble:: | ||||
| 
 | ||||
|         content = f.read() | ||||
|         assert content != '...' | ||||
| 
 | ||||
| 
 | ||||
| assertions about expected exceptions | ||||
| ------------------------------------------ | ||||
| 
 | ||||
| In order to write assertions about raised exceptions, you can use | ||||
| ``pytest.raises`` as a context manager like this:: | ||||
| 
 | ||||
|     import pytest | ||||
|     with pytest.raises(ZeroDivisionError): | ||||
|         1 / 0 | ||||
| 
 | ||||
|  | @ -105,7 +108,7 @@ if you run this module:: | |||
| 
 | ||||
|     $ py.test test_assert2.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_assert2.py F | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ You can always use an interactive Python prompt and type:: | |||
|     import pytest | ||||
|     help(pytest) | ||||
| 
 | ||||
| to get an overview on available globally available helpers. | ||||
| to get an overview on the globally available helpers. | ||||
| 
 | ||||
| .. automodule:: pytest | ||||
|     :members: | ||||
|  | @ -27,20 +27,18 @@ You can ask for available builtin or project-custom | |||
|     pytestconfig | ||||
|         the pytest config object with access to command line opts. | ||||
|     capsys | ||||
|         captures writes to sys.stdout/sys.stderr and makes | ||||
|         them available successively via a ``capsys.readouterr()`` method | ||||
|         which returns a ``(out, err)`` tuple of captured snapshot strings. | ||||
|         enables capturing of writes to sys.stdout/sys.stderr and makes | ||||
|         captured output available via ``capsys.readouterr()`` method calls | ||||
|         which return a ``(out, err)`` tuple. | ||||
|          | ||||
|     capfd | ||||
|         captures writes to file descriptors 1 and 2 and makes | ||||
|         snapshotted ``(out, err)`` string tuples available | ||||
|         via the ``capsys.readouterr()`` method.  If the underlying | ||||
|         platform does not have ``os.dup`` (e.g. Jython) tests using | ||||
|         this funcarg will automatically skip. | ||||
|         enables capturing of writes to file descriptors 1 and 2 and makes | ||||
|         captured output available via ``capsys.readouterr()`` method calls | ||||
|         which return a ``(out, err)`` tuple. | ||||
|          | ||||
|     tmpdir | ||||
|         return a temporary directory path object | ||||
|         unique to each test function invocation, | ||||
|         which is unique to each test function invocation, | ||||
|         created as a sub directory of the base temporary | ||||
|         directory.  The returned object is a `py.path.local`_ | ||||
|         path object. | ||||
|  | @ -57,8 +55,8 @@ You can ask for available builtin or project-custom | |||
|         monkeypatch.delenv(name, value, raising=True) | ||||
|         monkeypatch.syspath_prepend(path) | ||||
|          | ||||
|         All modifications will be undone when the requesting | ||||
|         test function finished its execution.  The ``raising`` | ||||
|         All modifications will be undone after the requesting | ||||
|         test function has finished. The ``raising`` | ||||
|         parameter determines if a KeyError or AttributeError | ||||
|         will be raised if the set/deletion operation has no target. | ||||
|          | ||||
|  | @ -68,3 +66,6 @@ You can ask for available builtin or project-custom | |||
|         * ``pop(category=None)``: return last warning matching the category. | ||||
|         * ``clear()``: clear list of warnings | ||||
|          | ||||
|         See http://docs.python.org/library/warnings.html for information | ||||
|         on warning categories. | ||||
|          | ||||
|  |  | |||
|  | @ -1,16 +1,44 @@ | |||
| 
 | ||||
| .. _`captures`: | ||||
| 
 | ||||
| Capturing of stdout/stderr output | ||||
| Capturing of the stdout/stderr output | ||||
| ========================================================= | ||||
| 
 | ||||
| By default ``stdout`` and ``stderr`` output is captured separately for | ||||
| setup and test execution code.  If a test or a setup method fails its | ||||
| according output will usually be shown along with the failure traceback. | ||||
| In addition, ``stdin`` is set to a "null" object which will fail all | ||||
| attempts to read from it.  This is important if some code paths in | ||||
| test otherwise might lead to waiting for input - which is usually | ||||
| not desired when running automated tests. | ||||
| Default stdout/stderr/stdin capturing behaviour | ||||
| --------------------------------------------------------- | ||||
| 
 | ||||
| During test execution any output sent to ``stdout`` and ``stderr`` is | ||||
| captured.  If a test or a setup method fails its according captured | ||||
| output will usually be shown along with the failure traceback. | ||||
| 
 | ||||
| In addition, ``stdin`` is set to a "null" object which will | ||||
| fail on attempts to read from it because it is rarely desired | ||||
| to wait for interactive input when running automated tests. | ||||
| 
 | ||||
| By default capturing is done by intercepting writes to low level | ||||
| file descriptors.  This allows to capture output from simple | ||||
| print statements as well as output from a subprocess started by | ||||
| a test. | ||||
| 
 | ||||
| Setting capturing methods or disabling capturing | ||||
| ------------------------------------------------- | ||||
| 
 | ||||
| There are two ways in which ``py.test`` can perform capturing: | ||||
| 
 | ||||
| * file descriptor (FD) level capturing (default): All writes going to the | ||||
|   operating system file descriptors 1 and 2 will be captured. | ||||
| 
 | ||||
| * ``sys`` level capturing: Only writes to Python files ``sys.stdout`` | ||||
|   and ``sys.stderr`` will be captured.  No capturing of writes to | ||||
|   filedescriptors is performed. | ||||
| 
 | ||||
| .. _`disable capturing`: | ||||
| 
 | ||||
| You can influence output capturing mechanisms from the command line:: | ||||
| 
 | ||||
|     py.test -s            # disable all capturing | ||||
|     py.test --capture=sys # replace sys.stdout/stderr with in-mem files | ||||
|     py.test --capture=fd  # also point filedescriptors 1 and 2 to temp file | ||||
| 
 | ||||
| .. _printdebugging: | ||||
| 
 | ||||
|  | @ -36,7 +64,7 @@ of the failing function and hide the other one:: | |||
| 
 | ||||
|     $ py.test | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 2 items | ||||
|      | ||||
|     test_module.py .F | ||||
|  | @ -50,33 +78,9 @@ of the failing function and hide the other one:: | |||
|      | ||||
|     test_module.py:9: AssertionError | ||||
|     ----------------------------- Captured stdout ------------------------------ | ||||
|     setting up <function test_func2 at 0x2897d70> | ||||
|     setting up <function test_func2 at 0x21031b8> | ||||
|     ==================== 1 failed, 1 passed in 0.02 seconds ==================== | ||||
| 
 | ||||
| Setting capturing methods or disabling capturing | ||||
| ------------------------------------------------- | ||||
| 
 | ||||
| There are two ways in which ``py.test`` can perform capturing: | ||||
| 
 | ||||
| * ``fd`` level capturing (default): All writes going to the operating | ||||
|   system file descriptors 1 and 2 will be captured, for example writes such | ||||
|   as ``os.write(1, 'hello')``.  Capturing on ``fd``-level also includes | ||||
|   **output from subprocesses**. | ||||
| 
 | ||||
| * ``sys`` level capturing: The ``sys.stdout`` and ``sys.stderr`` will | ||||
|   will be replaced with in-memory files and the ``print`` builtin or | ||||
|   output from code like ``sys.stderr.write(...)`` will be captured with | ||||
|   this method. | ||||
| 
 | ||||
| .. _`disable capturing`: | ||||
| 
 | ||||
| You can influence output capturing mechanisms from the command line:: | ||||
| 
 | ||||
|     py.test -s            # disable all capturing | ||||
|     py.test --capture=sys # replace sys.stdout/stderr with in-mem files | ||||
|     py.test --capture=fd  # also point filedescriptors 1 and 2 to temp file | ||||
| 
 | ||||
| 
 | ||||
| Accessing captured output from a test function | ||||
| --------------------------------------------------- | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,20 +4,20 @@ basic test configuration | |||
| Command line options and configuration file settings | ||||
| ----------------------------------------------------------------- | ||||
| 
 | ||||
| You can get help on options and ini-config values by running:: | ||||
| You can get help on command line options and values in INI-style | ||||
| configurations files by using the general help option:: | ||||
| 
 | ||||
|     py.test -h   # prints options _and_ config file settings | ||||
| 
 | ||||
| This will display command line and configuration file settings | ||||
| which were registered by installed plugins. | ||||
| 
 | ||||
| How test configuration is read from configuration INI-files | ||||
| ------------------------------------------------------------- | ||||
| 
 | ||||
| how test configuration is read from setup/tox ini-files | ||||
| -------------------------------------------------------- | ||||
| 
 | ||||
| py.test searched for the first matching ini-style configuration file | ||||
| py.test searches for the first matching ini-style configuration file | ||||
| in the directories of command line argument and the directories above. | ||||
| It looks for filenames in this order:: | ||||
| It looks for file basenames in this order:: | ||||
| 
 | ||||
|     pytest.ini | ||||
|     tox.ini | ||||
|  | @ -44,29 +44,27 @@ is used to start the search. | |||
| .. _`how to change command line options defaults`: | ||||
| .. _`adding default options`: | ||||
| 
 | ||||
| how to change command line options defaults | ||||
| How to change command line options defaults | ||||
| ------------------------------------------------ | ||||
| 
 | ||||
| py.test provides a simple way to set some default | ||||
| command line options.  For example, if you want | ||||
| to always see detailed info on skipped and xfailed | ||||
| tests, as well as have terser "dot progress output", | ||||
| you can add this to your root directory:: | ||||
| It can be tedious to type the same series of command line options | ||||
| every time you use py.test .  For example, if you always want to see | ||||
| detailed info on skipped and xfailed tests, as well as have terser "dot" | ||||
| progress output, you can write it into a configuration file:: | ||||
| 
 | ||||
|     # content of pytest.ini | ||||
|     # (or tox.ini or setup.cfg) | ||||
|     [pytest] | ||||
|     addopts = -rsxX -q | ||||
| 
 | ||||
| From now on, running ``py.test`` will implicitly add | ||||
| the specified options. | ||||
| From now on, running ``py.test`` will add the specified options. | ||||
| 
 | ||||
| builtin configuration file options | ||||
| ---------------------------------------------- | ||||
| 
 | ||||
| .. confval:: minversion | ||||
| 
 | ||||
|    specifies a minimal pytest version needed for running tests. | ||||
|    specifies a minimal pytest version required for running tests. | ||||
| 
 | ||||
|         minversion = 2.1  # will fail if we run with pytest-2.0 | ||||
| 
 | ||||
|  | @ -97,14 +95,14 @@ builtin configuration file options | |||
|         [!seq]  matches any char not in seq | ||||
| 
 | ||||
|    Default patterns are ``.* _* CVS {args}``. Setting a ``norecurse`` | ||||
|    replaces the default.  Here is a customizing example for avoiding | ||||
|    a different set of directories:: | ||||
|    replaces the default.  Here is an example of how to avoid | ||||
|    certain directories:: | ||||
| 
 | ||||
|     # content of setup.cfg | ||||
|     [pytest] | ||||
|     norecursedirs = .svn _build tmp* | ||||
| 
 | ||||
|    This would tell py.test to not recurse into typical subversion or | ||||
|    This would tell py.test to not look into typical subversion or | ||||
|    sphinx-build directories or into any ``tmp`` prefixed directory. | ||||
| 
 | ||||
| .. confval:: python_files | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ download and unpack a TAR file:: | |||
| 
 | ||||
|     http://pypi.python.org/pypi/pytest/ | ||||
| 
 | ||||
| activating a checkout with setuptools | ||||
| Activating a checkout with setuptools | ||||
| -------------------------------------------- | ||||
| 
 | ||||
| With a working Distribute_ or setuptools_ installation you can type:: | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| 
 | ||||
| doctest integration for modules and test files. | ||||
| doctest integration for modules and test files | ||||
| ========================================================= | ||||
| 
 | ||||
| By default all files matching the ``test*.txt`` pattern will | ||||
|  | @ -44,7 +44,7 @@ then you can just invoke ``py.test`` without command line options:: | |||
| 
 | ||||
|     $ py.test | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     mymodule.py . | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ Let's write a simple test function using a ``mysetup`` funcarg:: | |||
| To run this test py.test needs to find and call a factory to | ||||
| obtain the required ``mysetup`` function argument.  To make | ||||
| an according factory findable we write down a specifically named factory | ||||
| method in a :ref:`local plugin`:: | ||||
| method in a :ref:`local plugin <localplugin>` :: | ||||
| 
 | ||||
|     # content of conftest.py | ||||
|     from myapp import MyApp | ||||
|  | @ -49,7 +49,7 @@ You can now run the test:: | |||
| 
 | ||||
|     $ py.test test_sample.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_sample.py F | ||||
|  | @ -57,7 +57,7 @@ You can now run the test:: | |||
|     ================================= FAILURES ================================= | ||||
|     _______________________________ test_answer ________________________________ | ||||
|      | ||||
|     mysetup = <conftest.MySetup instance at 0x2526440> | ||||
|     mysetup = <conftest.MySetup instance at 0x1e2db90> | ||||
|      | ||||
|         def test_answer(mysetup): | ||||
|             app = mysetup.myapp() | ||||
|  | @ -122,12 +122,12 @@ Running it yields:: | |||
| 
 | ||||
|     $ py.test test_ssh.py -rs | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_ssh.py s | ||||
|     ========================= short test summary info ========================== | ||||
|     SKIP [1] /tmp/doc-exec-166/conftest.py:22: specify ssh host with --ssh | ||||
|     SKIP [1] /tmp/doc-exec-35/conftest.py:22: specify ssh host with --ssh | ||||
|      | ||||
|     ======================== 1 skipped in 0.02 seconds ========================= | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ now execute the test specification:: | |||
| 
 | ||||
|     nonpython $ py.test test_simple.yml | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 2 items | ||||
|      | ||||
|     test_simple.yml .F | ||||
|  | @ -37,7 +37,7 @@ now execute the test specification:: | |||
|     usecase execution failed | ||||
|        spec failed: 'some': 'other' | ||||
|        no further details known at this point. | ||||
|     ==================== 1 failed, 1 passed in 0.06 seconds ==================== | ||||
|     ==================== 1 failed, 1 passed in 0.36 seconds ==================== | ||||
| 
 | ||||
| You get one dot for the passing ``sub1: sub1`` check and one failure. | ||||
| Obviously in the above ``conftest.py`` you'll want to implement a more | ||||
|  | @ -56,7 +56,7 @@ reporting in ``verbose`` mode:: | |||
| 
 | ||||
|     nonpython $ py.test -v | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 -- /home/hpk/venv/0/bin/python | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 -- /home/hpk/venv/0/bin/python | ||||
|     collecting ... collected 2 items | ||||
|      | ||||
|     test_simple.yml:1: usecase: ok PASSED | ||||
|  | @ -67,7 +67,7 @@ reporting in ``verbose`` mode:: | |||
|     usecase execution failed | ||||
|        spec failed: 'some': 'other' | ||||
|        no further details known at this point. | ||||
|     ==================== 1 failed, 1 passed in 0.06 seconds ==================== | ||||
|     ==================== 1 failed, 1 passed in 0.08 seconds ==================== | ||||
| 
 | ||||
| While developing your custom test collection and execution it's also | ||||
| interesting to just look at the collection tree:: | ||||
|  |  | |||
|  | @ -125,7 +125,7 @@ And then when we run the test:: | |||
|     ================================= FAILURES ================================= | ||||
|     __________________________ test_db_initialized[1] __________________________ | ||||
|      | ||||
|     db = <conftest.DB2 instance at 0x1a5b488> | ||||
|     db = <conftest.DB2 instance at 0x1873170> | ||||
|      | ||||
|         def test_db_initialized(db): | ||||
|             # a dummy test | ||||
|  | @ -179,7 +179,7 @@ the respective settings:: | |||
|     ================================= FAILURES ================================= | ||||
|     __________________________ test_db_initialized[1] __________________________ | ||||
|      | ||||
|     db = <conftest.DB2 instance at 0xf81c20> | ||||
|     db = <conftest.DB2 instance at 0x2cc75f0> | ||||
|      | ||||
|         def test_db_initialized(db): | ||||
|             # a dummy test | ||||
|  | @ -190,7 +190,7 @@ the respective settings:: | |||
|     test_backends.py:6: Failed | ||||
|     _________________________ TestClass.test_equals[0] _________________________ | ||||
|      | ||||
|     self = <test_parametrize.TestClass instance at 0xf93050>, a = 1, b = 2 | ||||
|     self = <test_parametrize.TestClass instance at 0x2cd3050>, a = 1, b = 2 | ||||
|      | ||||
|         def test_equals(self, a, b): | ||||
|     >       assert a == b | ||||
|  | @ -199,7 +199,7 @@ the respective settings:: | |||
|     test_parametrize.py:17: AssertionError | ||||
|     ______________________ TestClass.test_zerodivision[1] ______________________ | ||||
|      | ||||
|     self = <test_parametrize.TestClass instance at 0xf93098>, a = 3, b = 2 | ||||
|     self = <test_parametrize.TestClass instance at 0x2cd3998>, a = 3, b = 2 | ||||
|      | ||||
|         def test_zerodivision(self, a, b): | ||||
|     >       pytest.raises(ZeroDivisionError, "a/b") | ||||
|  | @ -247,7 +247,7 @@ Running it gives similar results as before:: | |||
|     ================================= FAILURES ================================= | ||||
|     _________________________ TestClass.test_equals[0] _________________________ | ||||
|      | ||||
|     self = <test_parametrize2.TestClass instance at 0x27e15a8>, a = 1, b = 2 | ||||
|     self = <test_parametrize2.TestClass instance at 0x10b29e0>, a = 1, b = 2 | ||||
|      | ||||
|         @params([dict(a=1, b=2), dict(a=3, b=3), ]) | ||||
|         def test_equals(self, a, b): | ||||
|  | @ -257,7 +257,7 @@ Running it gives similar results as before:: | |||
|     test_parametrize2.py:19: AssertionError | ||||
|     ______________________ TestClass.test_zerodivision[1] ______________________ | ||||
|      | ||||
|     self = <test_parametrize2.TestClass instance at 0x2953bd8>, a = 3, b = 2 | ||||
|     self = <test_parametrize2.TestClass instance at 0x10bdb00>, a = 3, b = 2 | ||||
|      | ||||
|         @params([dict(a=1, b=0), dict(a=3, b=2)]) | ||||
|         def test_zerodivision(self, a, b): | ||||
|  | @ -286,4 +286,4 @@ Running it (with Python-2.4 through to Python2.7 installed):: | |||
|    . $ py.test -q multipython.py | ||||
|    collecting ... collected 75 items | ||||
|    ....s....s....s....ssssss....s....s....s....ssssss....s....s....s....ssssss | ||||
|    48 passed, 27 skipped in 1.59 seconds | ||||
|    48 passed, 27 skipped in 1.92 seconds | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ get on the terminal - we are working on that): | |||
| 
 | ||||
|     assertion $ py.test failure_demo.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 39 items | ||||
|      | ||||
|     failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | ||||
|  | @ -30,7 +30,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:15: AssertionError | ||||
|     _________________________ TestFailing.test_simple __________________________ | ||||
|      | ||||
|     self = <failure_demo.TestFailing object at 0x1b42950> | ||||
|     self = <failure_demo.TestFailing object at 0x1b3b5d0> | ||||
|      | ||||
|         def test_simple(self): | ||||
|             def f(): | ||||
|  | @ -40,13 +40,13 @@ get on the terminal - we are working on that): | |||
|          | ||||
|     >       assert f() == g() | ||||
|     E       assert 42 == 43 | ||||
|     E        +  where 42 = <function f at 0x1b33de8>() | ||||
|     E        +  and   43 = <function g at 0x1b47140>() | ||||
|     E        +  where 42 = <function f at 0x1b3f410>() | ||||
|     E        +  and   43 = <function g at 0x1b3f0c8>() | ||||
|      | ||||
|     failure_demo.py:28: AssertionError | ||||
|     ____________________ TestFailing.test_simple_multiline _____________________ | ||||
|      | ||||
|     self = <failure_demo.TestFailing object at 0x1b42c50> | ||||
|     self = <failure_demo.TestFailing object at 0x1b2e6d0> | ||||
|      | ||||
|         def test_simple_multiline(self): | ||||
|             otherfunc_multi( | ||||
|  | @ -66,19 +66,19 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:12: AssertionError | ||||
|     ___________________________ TestFailing.test_not ___________________________ | ||||
|      | ||||
|     self = <failure_demo.TestFailing object at 0x1b42190> | ||||
|     self = <failure_demo.TestFailing object at 0x1b3b950> | ||||
|      | ||||
|         def test_not(self): | ||||
|             def f(): | ||||
|                 return 42 | ||||
|     >       assert not f() | ||||
|     E       assert not 42 | ||||
|     E        +  where 42 = <function f at 0x1b47320>() | ||||
|     E        +  where 42 = <function f at 0x1b3f668>() | ||||
|      | ||||
|     failure_demo.py:38: AssertionError | ||||
|     _________________ TestSpecialisedExplanations.test_eq_text _________________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b42150> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b3b490> | ||||
|      | ||||
|         def test_eq_text(self): | ||||
|     >       assert 'spam' == 'eggs' | ||||
|  | @ -89,7 +89,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:42: AssertionError | ||||
|     _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b48610> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b2ed10> | ||||
|      | ||||
|         def test_eq_similar_text(self): | ||||
|     >       assert 'foo 1 bar' == 'foo 2 bar' | ||||
|  | @ -102,7 +102,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:45: AssertionError | ||||
|     ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b38f90> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b3bf10> | ||||
|      | ||||
|         def test_eq_multiline_text(self): | ||||
|     >       assert 'foo\nspam\nbar' == 'foo\neggs\nbar' | ||||
|  | @ -115,7 +115,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:48: AssertionError | ||||
|     ______________ TestSpecialisedExplanations.test_eq_long_text _______________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b42cd0> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b3b890> | ||||
|      | ||||
|         def test_eq_long_text(self): | ||||
|             a = '1'*100 + 'a' + '2'*100 | ||||
|  | @ -132,7 +132,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:53: AssertionError | ||||
|     _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba6a90> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b538d0> | ||||
|      | ||||
|         def test_eq_long_text_multiline(self): | ||||
|             a = '1\n'*100 + 'a' + '2\n'*100 | ||||
|  | @ -156,7 +156,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:58: AssertionError | ||||
|     _________________ TestSpecialisedExplanations.test_eq_list _________________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba6bd0> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b53b50> | ||||
|      | ||||
|         def test_eq_list(self): | ||||
|     >       assert [0, 1, 2] == [0, 1, 3] | ||||
|  | @ -166,7 +166,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:61: AssertionError | ||||
|     ______________ TestSpecialisedExplanations.test_eq_list_long _______________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b42910> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b3b390> | ||||
|      | ||||
|         def test_eq_list_long(self): | ||||
|             a = [0]*100 + [1] + [3]*100 | ||||
|  | @ -178,7 +178,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:66: AssertionError | ||||
|     _________________ TestSpecialisedExplanations.test_eq_dict _________________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba6f90> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b53b10> | ||||
|      | ||||
|         def test_eq_dict(self): | ||||
|     >       assert {'a': 0, 'b': 1} == {'a': 0, 'b': 2} | ||||
|  | @ -191,7 +191,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:69: AssertionError | ||||
|     _________________ TestSpecialisedExplanations.test_eq_set __________________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b485d0> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b439d0> | ||||
|      | ||||
|         def test_eq_set(self): | ||||
|     >       assert set([0, 10, 11, 12]) == set([0, 20, 21]) | ||||
|  | @ -207,7 +207,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:72: AssertionError | ||||
|     _____________ TestSpecialisedExplanations.test_eq_longer_list ______________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba2850> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b58750> | ||||
|      | ||||
|         def test_eq_longer_list(self): | ||||
|     >       assert [1,2] == [1,2,3] | ||||
|  | @ -217,7 +217,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:75: AssertionError | ||||
|     _________________ TestSpecialisedExplanations.test_in_list _________________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba2f10> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b58f10> | ||||
|      | ||||
|         def test_in_list(self): | ||||
|     >       assert 1 in [0, 2, 3, 4, 5] | ||||
|  | @ -226,7 +226,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:78: AssertionError | ||||
|     __________ TestSpecialisedExplanations.test_not_in_text_multiline __________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba2990> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b3b9d0> | ||||
|      | ||||
|         def test_not_in_text_multiline(self): | ||||
|             text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail' | ||||
|  | @ -244,7 +244,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:82: AssertionError | ||||
|     ___________ TestSpecialisedExplanations.test_not_in_text_single ____________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b42110> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b53bd0> | ||||
|      | ||||
|         def test_not_in_text_single(self): | ||||
|             text = 'single foo line' | ||||
|  | @ -257,7 +257,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:86: AssertionError | ||||
|     _________ TestSpecialisedExplanations.test_not_in_text_single_long _________ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba65d0> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b583d0> | ||||
|      | ||||
|         def test_not_in_text_single_long(self): | ||||
|             text = 'head ' * 50 + 'foo ' + 'tail ' * 20 | ||||
|  | @ -270,7 +270,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:90: AssertionError | ||||
|     ______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______ | ||||
|      | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1ba2c50> | ||||
|     self = <failure_demo.TestSpecialisedExplanations object at 0x1b53890> | ||||
|      | ||||
|         def test_not_in_text_single_long_term(self): | ||||
|             text = 'head ' * 50 + 'f'*70 + 'tail ' * 20 | ||||
|  | @ -289,7 +289,7 @@ get on the terminal - we are working on that): | |||
|             i = Foo() | ||||
|     >       assert i.b == 2 | ||||
|     E       assert 1 == 2 | ||||
|     E        +  where 1 = <failure_demo.Foo object at 0x1ba2ad0>.b | ||||
|     E        +  where 1 = <failure_demo.Foo object at 0x1b58a90>.b | ||||
|      | ||||
|     failure_demo.py:101: AssertionError | ||||
|     _________________________ test_attribute_instance __________________________ | ||||
|  | @ -299,8 +299,8 @@ get on the terminal - we are working on that): | |||
|                 b = 1 | ||||
|     >       assert Foo().b == 2 | ||||
|     E       assert 1 == 2 | ||||
|     E        +  where 1 = <failure_demo.Foo object at 0x1ba2110>.b | ||||
|     E        +    where <failure_demo.Foo object at 0x1ba2110> = <class 'failure_demo.Foo'>() | ||||
|     E        +  where 1 = <failure_demo.Foo object at 0x1b53dd0>.b | ||||
|     E        +    where <failure_demo.Foo object at 0x1b53dd0> = <class 'failure_demo.Foo'>() | ||||
|      | ||||
|     failure_demo.py:107: AssertionError | ||||
|     __________________________ test_attribute_failure __________________________ | ||||
|  | @ -316,7 +316,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:116:  | ||||
|     _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  | ||||
|      | ||||
|     self = <failure_demo.Foo object at 0x1ba2a90> | ||||
|     self = <failure_demo.Foo object at 0x1b582d0> | ||||
|      | ||||
|         def _get_b(self): | ||||
|     >       raise Exception('Failed to get attrib') | ||||
|  | @ -332,15 +332,15 @@ get on the terminal - we are working on that): | |||
|                 b = 2 | ||||
|     >       assert Foo().b == Bar().b | ||||
|     E       assert 1 == 2 | ||||
|     E        +  where 1 = <failure_demo.Foo object at 0x1ba2950>.b | ||||
|     E        +    where <failure_demo.Foo object at 0x1ba2950> = <class 'failure_demo.Foo'>() | ||||
|     E        +  and   2 = <failure_demo.Bar object at 0x1ba2390>.b | ||||
|     E        +    where <failure_demo.Bar object at 0x1ba2390> = <class 'failure_demo.Bar'>() | ||||
|     E        +  where 1 = <failure_demo.Foo object at 0x1b58450>.b | ||||
|     E        +    where <failure_demo.Foo object at 0x1b58450> = <class 'failure_demo.Foo'>() | ||||
|     E        +  and   2 = <failure_demo.Bar object at 0x1b58590>.b | ||||
|     E        +    where <failure_demo.Bar object at 0x1b58590> = <class 'failure_demo.Bar'>() | ||||
|      | ||||
|     failure_demo.py:124: AssertionError | ||||
|     __________________________ TestRaises.test_raises __________________________ | ||||
|      | ||||
|     self = <failure_demo.TestRaises instance at 0x1bb3488> | ||||
|     self = <failure_demo.TestRaises instance at 0x1bf0440> | ||||
|      | ||||
|         def test_raises(self): | ||||
|             s = 'qwe' | ||||
|  | @ -352,10 +352,10 @@ get on the terminal - we are working on that): | |||
|     >   int(s) | ||||
|     E   ValueError: invalid literal for int() with base 10: 'qwe' | ||||
|      | ||||
|     <0-codegen /home/hpk/p/pytest/_pytest/python.py:822>:1: ValueError | ||||
|     <0-codegen /home/hpk/p/pytest/_pytest/python.py:825>:1: ValueError | ||||
|     ______________________ TestRaises.test_raises_doesnt _______________________ | ||||
|      | ||||
|     self = <failure_demo.TestRaises instance at 0x1bb3098> | ||||
|     self = <failure_demo.TestRaises instance at 0x1bf0368> | ||||
|      | ||||
|         def test_raises_doesnt(self): | ||||
|     >       raises(IOError, "int('3')") | ||||
|  | @ -364,7 +364,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:136: Failed | ||||
|     __________________________ TestRaises.test_raise ___________________________ | ||||
|      | ||||
|     self = <failure_demo.TestRaises instance at 0x1ba7d40> | ||||
|     self = <failure_demo.TestRaises instance at 0x1be22d8> | ||||
|      | ||||
|         def test_raise(self): | ||||
|     >       raise ValueError("demo error") | ||||
|  | @ -373,7 +373,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:139: ValueError | ||||
|     ________________________ TestRaises.test_tupleerror ________________________ | ||||
|      | ||||
|     self = <failure_demo.TestRaises instance at 0x1b5cc68> | ||||
|     self = <failure_demo.TestRaises instance at 0x1b566c8> | ||||
|      | ||||
|         def test_tupleerror(self): | ||||
|     >       a,b = [1] | ||||
|  | @ -382,7 +382,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:142: ValueError | ||||
|     ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ | ||||
|      | ||||
|     self = <failure_demo.TestRaises instance at 0x1bb1488> | ||||
|     self = <failure_demo.TestRaises instance at 0x1beb440> | ||||
|      | ||||
|         def test_reinterpret_fails_with_print_for_the_fun_of_it(self): | ||||
|             l = [1,2,3] | ||||
|  | @ -395,7 +395,7 @@ get on the terminal - we are working on that): | |||
|     l is [1, 2, 3] | ||||
|     ________________________ TestRaises.test_some_error ________________________ | ||||
|      | ||||
|     self = <failure_demo.TestRaises instance at 0x1bb9128> | ||||
|     self = <failure_demo.TestRaises instance at 0x1bef0e0> | ||||
|      | ||||
|         def test_some_error(self): | ||||
|     >       if namenotexi: | ||||
|  | @ -423,7 +423,7 @@ get on the terminal - we are working on that): | |||
|     <2-codegen 'abc-123' /home/hpk/p/pytest/doc/example/assertion/failure_demo.py:162>:2: AssertionError | ||||
|     ____________________ TestMoreErrors.test_complex_error _____________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bb8f80> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bf3fc8> | ||||
|      | ||||
|         def test_complex_error(self): | ||||
|             def f(): | ||||
|  | @ -452,7 +452,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:5: AssertionError | ||||
|     ___________________ TestMoreErrors.test_z1_unpack_error ____________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bab200> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1b56ab8> | ||||
|      | ||||
|         def test_z1_unpack_error(self): | ||||
|             l = [] | ||||
|  | @ -462,7 +462,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:179: ValueError | ||||
|     ____________________ TestMoreErrors.test_z2_type_error _____________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bb36c8> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bf0200> | ||||
|      | ||||
|         def test_z2_type_error(self): | ||||
|             l = 3 | ||||
|  | @ -472,20 +472,20 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:183: TypeError | ||||
|     ______________________ TestMoreErrors.test_startswith ______________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bbce60> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bf7dd0> | ||||
|      | ||||
|         def test_startswith(self): | ||||
|             s = "123" | ||||
|             g = "456" | ||||
|     >       assert s.startswith(g) | ||||
|     E       assert False | ||||
|     E        +  where False = <built-in method startswith of str object at 0x1ad6bd0>('456') | ||||
|     E        +    where <built-in method startswith of str object at 0x1ad6bd0> = '123'.startswith | ||||
|     E        +  where False = <built-in method startswith of str object at 0x1abeb10>('456') | ||||
|     E        +    where <built-in method startswith of str object at 0x1abeb10> = '123'.startswith | ||||
|      | ||||
|     failure_demo.py:188: AssertionError | ||||
|     __________________ TestMoreErrors.test_startswith_nested ___________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bbeb48> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bf8a70> | ||||
|      | ||||
|         def test_startswith_nested(self): | ||||
|             def f(): | ||||
|  | @ -494,15 +494,15 @@ get on the terminal - we are working on that): | |||
|                 return "456" | ||||
|     >       assert f().startswith(g()) | ||||
|     E       assert False | ||||
|     E        +  where False = <built-in method startswith of str object at 0x1ad6bd0>('456') | ||||
|     E        +    where <built-in method startswith of str object at 0x1ad6bd0> = '123'.startswith | ||||
|     E        +      where '123' = <function f at 0x1baade8>() | ||||
|     E        +    and   '456' = <function g at 0x1baad70>() | ||||
|     E        +  where False = <built-in method startswith of str object at 0x1abeb10>('456') | ||||
|     E        +    where <built-in method startswith of str object at 0x1abeb10> = '123'.startswith | ||||
|     E        +      where '123' = <function f at 0x1bf9050>() | ||||
|     E        +    and   '456' = <function g at 0x1bf90c8>() | ||||
|      | ||||
|     failure_demo.py:195: AssertionError | ||||
|     _____________________ TestMoreErrors.test_global_func ______________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bbe098> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bf0248> | ||||
|      | ||||
|         def test_global_func(self): | ||||
|     >       assert isinstance(globf(42), float) | ||||
|  | @ -513,19 +513,19 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:198: AssertionError | ||||
|     _______________________ TestMoreErrors.test_instance _______________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1ba7bd8> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1be2998> | ||||
|      | ||||
|         def test_instance(self): | ||||
|             self.x = 6*7 | ||||
|     >       assert self.x != 42 | ||||
|     E       assert 42 != 42 | ||||
|     E        +  where 42 = 42 | ||||
|     E        +    where 42 = <failure_demo.TestMoreErrors instance at 0x1ba7bd8>.x | ||||
|     E        +    where 42 = <failure_demo.TestMoreErrors instance at 0x1be2998>.x | ||||
|      | ||||
|     failure_demo.py:202: AssertionError | ||||
|     _______________________ TestMoreErrors.test_compare ________________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bbca28> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bf7f80> | ||||
|      | ||||
|         def test_compare(self): | ||||
|     >       assert globf(10) < 5 | ||||
|  | @ -535,7 +535,7 @@ get on the terminal - we are working on that): | |||
|     failure_demo.py:205: AssertionError | ||||
|     _____________________ TestMoreErrors.test_try_finally ______________________ | ||||
|      | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bc0908> | ||||
|     self = <failure_demo.TestMoreErrors instance at 0x1bfb878> | ||||
|      | ||||
|         def test_try_finally(self): | ||||
|             x = 1 | ||||
|  | @ -544,4 +544,4 @@ get on the terminal - we are working on that): | |||
|     E           assert 1 == 0 | ||||
|      | ||||
|     failure_demo.py:210: AssertionError | ||||
|     ======================== 39 failed in 0.22 seconds ========================= | ||||
|     ======================== 39 failed in 0.26 seconds ========================= | ||||
|  |  | |||
|  | @ -109,13 +109,13 @@ directory with the above conftest.py:: | |||
| 
 | ||||
|     $ py.test | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev0 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     gw0 I / gw1 I / gw2 I / gw3 I | ||||
|     gw0 [0] / gw1 [0] / gw2 [0] / gw3 [0] | ||||
|      | ||||
|     scheduling tests via LoadScheduling | ||||
|      | ||||
|     =============================  in 0.37 seconds ============================= | ||||
|     =============================  in 0.35 seconds ============================= | ||||
| 
 | ||||
| .. _`excontrolskip`: | ||||
| 
 | ||||
|  | @ -156,12 +156,12 @@ and when running it will see a skipped "slow" test:: | |||
| 
 | ||||
|     $ py.test -rs    # "-rs" means report details on the little 's' | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev0 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 2 items | ||||
|      | ||||
|     test_module.py .s | ||||
|     ========================= short test summary info ========================== | ||||
|     SKIP [1] /tmp/doc-exec-275/conftest.py:9: need --runslow option to run | ||||
|     SKIP [1] /tmp/doc-exec-40/conftest.py:9: need --runslow option to run | ||||
|      | ||||
|     =================== 1 passed, 1 skipped in 0.02 seconds ==================== | ||||
| 
 | ||||
|  | @ -169,7 +169,7 @@ Or run it including the ``slow`` marked test:: | |||
| 
 | ||||
|     $ py.test --runslow | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev0 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 2 items | ||||
|      | ||||
|     test_module.py .. | ||||
|  | @ -213,7 +213,7 @@ Let's run our little function:: | |||
|     E       Failed: not configured: 42 | ||||
|      | ||||
|     test_checkconfig.py:8: Failed | ||||
|     1 failed in 0.02 seconds | ||||
|     1 failed in 0.03 seconds | ||||
| 
 | ||||
| Detect if running from within a py.test run | ||||
| -------------------------------------------------------------- | ||||
|  | @ -261,7 +261,7 @@ which will add the string to the test header accordingly:: | |||
| 
 | ||||
|     $ py.test | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev0 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     project deps: mylib-1.1 | ||||
|     collecting ... collected 0 items | ||||
|      | ||||
|  | @ -284,7 +284,7 @@ which will add info only when run with "--v":: | |||
| 
 | ||||
|     $ py.test -v | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev0 -- /home/hpk/venv/0/bin/python | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 -- /home/hpk/venv/0/bin/python | ||||
|     info1: did you know that ... | ||||
|     did you? | ||||
|     collecting ... collected 0 items | ||||
|  | @ -295,7 +295,7 @@ and nothing when run plainly:: | |||
| 
 | ||||
|     $ py.test | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev0 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 0 items | ||||
|      | ||||
|     =============================  in 0.00 seconds ============================= | ||||
|  |  | |||
							
								
								
									
										32
									
								
								doc/extracol
								
								
								
								
							
							
						
						
									
										32
									
								
								doc/extracol
								
								
								
								
							|  | @ -1,32 +0,0 @@ | |||
| changing Python test discovery patterns | ||||
| -------------------------------------------------- | ||||
| 
 | ||||
| You can influence python test file, function and class prefixes through | ||||
| the :confval:`python_patterns` configuration valueto determine which | ||||
| files are checked and which test functions are found.  Example for using | ||||
| a scheme that builds on ``check`` rather than on ``test`` prefixes:: | ||||
| 
 | ||||
| 
 | ||||
|     # content of setup.cfg | ||||
|     [pytest] | ||||
|     python_patterns = | ||||
|         files: check_*.py | ||||
|         functions: check_ | ||||
|         classes: Check | ||||
| 
 | ||||
| See  | ||||
|     :confval:`python_funcprefixes` and :confval:`python_classprefixes` | ||||
| 
 | ||||
| 
 | ||||
|     changing test file discovery | ||||
|     ----------------------------------------------------- | ||||
| 
 | ||||
|     You can specify patterns where python tests are found:: | ||||
|       | ||||
|         python_testfilepatterns = | ||||
|             testing/**/{purebasename}.py | ||||
|             testing/*.py | ||||
| 
 | ||||
|     .. note:: | ||||
| 
 | ||||
|        conftest.py files are never considered for test discovery | ||||
							
								
								
									
										59
									
								
								doc/faq.txt
								
								
								
								
							
							
						
						
									
										59
									
								
								doc/faq.txt
								
								
								
								
							|  | @ -12,25 +12,26 @@ On naming, nosetests, licensing and magic | |||
| Why a ``py.test`` instead of a ``pytest`` command? | ||||
| ++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| Some historic, some practical reasons: ``py.test`` used to be part of | ||||
| the ``py`` package which provided several developer utilities, | ||||
| all starting with ``py.<TAB>``, providing nice TAB-completion. If | ||||
| Some of the reasons are historic, others are practical.  ``py.test`` | ||||
| used to be part of the ``py`` package which provided several developer | ||||
| utilities, all starting with ``py.<TAB>``, thus providing nice | ||||
| TAB-completion. If | ||||
| you install ``pip install pycmd`` you get these tools from a separate | ||||
| package.  These days the command line tool could be called ``pytest`` | ||||
| but then again many people have gotten used to the old name and there | ||||
| is another tool named "pytest" so we just decided to stick with | ||||
| since many people have gotten used to the old name and there | ||||
| is another tool named "pytest" we just decided to stick with | ||||
| ``py.test``. | ||||
| 
 | ||||
| What's the relation to nose and unittest? | ||||
| How does py.test relate to nose and unittest? | ||||
| +++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| py.test and nose_ share basic philosophy when it comes | ||||
| to running Python tests.  In fact, you can run many tests | ||||
| written nose with py.test.  nose_ was originally created | ||||
| to running and writing Python tests.  In fact, you can run many tests | ||||
| written for nose with py.test.  nose_ was originally created | ||||
| as a clone of ``py.test`` when py.test was in the ``0.8`` release | ||||
| cycle.  As of version 2.0 support for running unittest test | ||||
| suites is majorly improved and you should be able to run | ||||
| many Django and Twisted test suites. | ||||
| cycle.  Note that starting with pytest-2.0 support for running unittest | ||||
| test suites is majorly improved and you should be able to run | ||||
| many Django and Twisted test suites without modification. | ||||
| 
 | ||||
| .. _features: test/features.html | ||||
| 
 | ||||
|  | @ -39,22 +40,20 @@ What's this "magic" with py.test? | |||
| ++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| Around 2007 (version ``0.8``) some people claimed that py.test | ||||
| was using too much "magic".  It has been refactored a lot.  Thrown | ||||
| out old code.  Deprecated unused approaches and code.  And it is today | ||||
| probably one of the smallest, most universally runnable and most | ||||
| customizable testing frameworks for Python.   It's true that | ||||
| ``py.test`` uses metaprogramming techniques, i.e. it views | ||||
| test code similar to how compilers view programs, using a | ||||
| somewhat abstract internal model. | ||||
| was using too much "magic".  Partly this has been fixed by removing | ||||
| unused, deprecated or complicated code.  It is today probably one | ||||
| of the smallest, most universally runnable and most | ||||
| customizable testing frameworks for Python.   However, | ||||
| ``py.test`` still uses many metaprogramming techniques and | ||||
| reading its source is thus likely not something for Python beginners. | ||||
| 
 | ||||
| It's also true that the no-boilerplate testing is implemented by making | ||||
| use of the Python assert statement through "re-interpretation": | ||||
| A second "magic" issue arguably the assert statement re-intepreation: | ||||
| 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). | ||||
| has side effects (better to avoid them anyway!) 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-interpretation. | ||||
| Sidenote: it is good practise to avoid asserts with side effects. | ||||
| 
 | ||||
| .. _`py namespaces`: index.html | ||||
| .. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/trunk/py/__init__.py | ||||
|  | @ -69,7 +68,7 @@ Is using funcarg- versus xUnit setup a style question? | |||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| For simple applications and for people experienced with nose_ or | ||||
| unittest-style test setup using `xUnit style setup`_ often | ||||
| unittest-style test setup using `xUnit style setup`_ probably | ||||
| feels natural.  For larger test suites, parametrized testing | ||||
| or setup of complex test resources using funcargs_ may feel more natural. | ||||
| Moreover, funcargs are ideal for writing advanced test support | ||||
|  | @ -86,13 +85,11 @@ in a managed class/module/function scope. | |||
| Why the ``pytest_funcarg__*`` name for funcarg factories? | ||||
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| We alternatively implemented an explicit registration mechanism for | ||||
| function argument factories.  But lacking a good use case for this | ||||
| indirection and flexibility we decided to go for `Convention over | ||||
| Configuration`_ and rather have factories specified by convention. | ||||
| Besides removing the need for an registration indirection it allows to | ||||
| "grep" for ``pytest_funcarg__MYARG`` and will safely find all factory | ||||
| functions for the ``MYARG`` function argument. | ||||
| We like `Convention over Configuration`_ and didn't see much point | ||||
| in allowing a more flexible or abstract mechanism.  Moreover, | ||||
| is is nice to be able to search for ``pytest_funcarg__MYARG`` in | ||||
| a source code and safely find all factory functions for | ||||
| the ``MYARG`` function argument. | ||||
| 
 | ||||
| .. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| ============================================================== | ||||
| creating and managing test function arguments | ||||
| Injecting objects into test functions (funcargs) | ||||
| ============================================================== | ||||
| 
 | ||||
| .. currentmodule:: _pytest.python | ||||
|  | @ -11,16 +11,26 @@ creating and managing test function arguments | |||
| Dependency injection through function arguments | ||||
| ================================================= | ||||
| 
 | ||||
| py.test allows to 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 | ||||
| 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 | ||||
| easy-to-modify test suites. | ||||
| 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. | ||||
| 
 | ||||
| The basic mechanism for injecting objects is also called the | ||||
| *funcarg mechanism* because objects are ultimatly 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. | ||||
| 
 | ||||
| .. _`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. | ||||
| 
 | ||||
| A test function may be invoked multiple times in which case we | ||||
| speak of :ref:`parametrized testing <parametrizing-tests>`. This can be | ||||
|  | @ -28,13 +38,13 @@ 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. | ||||
| 
 | ||||
| 
 | ||||
| .. _funcarg: | ||||
| 
 | ||||
| Basic funcarg example | ||||
| ----------------------- | ||||
| Basic injection example | ||||
| -------------------------------- | ||||
| 
 | ||||
| Let's look at a simple self-contained example that you can put | ||||
| into a test module:: | ||||
| Let's look at a simple self-contained test module:: | ||||
| 
 | ||||
|     # content of ./test_simplefactory.py | ||||
|     def pytest_funcarg__myfuncarg(request): | ||||
|  | @ -43,11 +53,15 @@ into a test module:: | |||
|     def test_function(myfuncarg): | ||||
|         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 test_simplefactory.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_simplefactory.py F | ||||
|  | @ -64,8 +78,8 @@ Running the test looks like this:: | |||
|     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 | ||||
| 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: | ||||
| 
 | ||||
| 1. py.test :ref:`finds <test discovery>` the ``test_function`` because | ||||
|  | @ -76,14 +90,15 @@ comes to call the test function this way: | |||
| 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 | ||||
| 3. the test function can now be called: ``test_function(42)``. | ||||
|    This results in the above exception because of the assertion | ||||
|    mismatch. | ||||
| 
 | ||||
| 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:: | ||||
| with a list of available function arguments. | ||||
| 
 | ||||
| You can always issue:: | ||||
| 
 | ||||
|     py.test --funcargs test_simplefactory.py | ||||
| 
 | ||||
|  | @ -152,7 +167,7 @@ Running this:: | |||
| 
 | ||||
|     $ py.test test_example.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 10 items | ||||
|      | ||||
|     test_example.py .........F | ||||
|  | @ -167,7 +182,7 @@ Running this:: | |||
|     E       assert 9 < 9 | ||||
|      | ||||
|     test_example.py:7: AssertionError | ||||
|     ==================== 1 failed, 9 passed in 0.03 seconds ==================== | ||||
|     ==================== 1 failed, 9 passed in 0.05 seconds ==================== | ||||
| 
 | ||||
| Note that the ``pytest_generate_tests(metafunc)`` hook is called during | ||||
| the test collection phase which is separate from the actual test running. | ||||
|  | @ -190,7 +205,7 @@ 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.6 -- pytest-2.0.1 -- /home/hpk/venv/0/bin/python | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 -- /home/hpk/venv/0/bin/python | ||||
|     collecting ... collected 10 items | ||||
|      | ||||
|     test_example.py:6: test_func[7] PASSED | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ Installation options:: | |||
| To check your installation has installed the correct version:: | ||||
| 
 | ||||
|     $ py.test --version | ||||
|     This is py.test version 2.0.1, imported from /home/hpk/p/pytest/pytest.py | ||||
|     This is py.test version 2.0.2.dev2, imported from /home/hpk/p/pytest/pytest.py | ||||
|     setuptools registered plugins: | ||||
|       pytest-xdist-1.6.dev2 at /home/hpk/p/pytest-xdist/xdist/plugin.pyc | ||||
|       pytest-pep8-0.7 at /home/hpk/p/pytest-pep8/pytest_pep8.pyc | ||||
|  | @ -41,7 +41,7 @@ That's it. You can execute the test function now:: | |||
| 
 | ||||
|     $ py.test | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_sample.py F | ||||
|  | @ -57,7 +57,7 @@ That's it. You can execute the test function now:: | |||
|     test_sample.py:5: AssertionError | ||||
|     ========================= 1 failed in 0.02 seconds ========================= | ||||
| 
 | ||||
| py.test found the ``test_answer`` function by following :ref:`standard test discovery rules <test discovery>`, basically detecting the ``test_`` prefixes.  We got a failure report because our little ``func(3)`` call did not return ``5``.  The report is formatted using the :ref:`standard traceback reporting`. | ||||
| py.test found the ``test_answer`` function by following :ref:`standard test discovery rules <test discovery>`, basically detecting the ``test_`` prefixes.  We got a failure report because our little ``func(3)`` call did not return ``5``. | ||||
| 
 | ||||
| .. note:: | ||||
| 
 | ||||
|  | @ -80,10 +80,10 @@ py.test found the ``test_answer`` function by following :ref:`standard test disc | |||
| 
 | ||||
| .. _`assert statement`: http://docs.python.org/reference/simple_stmts.html#the-assert-statement | ||||
| 
 | ||||
| Asserting a certain exception is raised | ||||
| Asserting that a certain exception is raised | ||||
| -------------------------------------------------------------- | ||||
| 
 | ||||
| If you want to assert some code raises an exception you can | ||||
| If you want to assert that some code raises an exception you can | ||||
| use the ``raises`` helper:: | ||||
| 
 | ||||
|     # content of test_sysexit.py | ||||
|  | @ -107,9 +107,9 @@ Running it with, this time in "quiet" reporting mode:: | |||
| Grouping multiple tests in a class | ||||
| -------------------------------------------------------------- | ||||
| 
 | ||||
| If you start to have more than a few tests it often makes sense | ||||
| to group tests logically, in classes and modules.  Let's put two | ||||
| tests in a class like this:: | ||||
| Once you start to have more than a few tests it often makes sense | ||||
| to group tests logically, in classes and modules.  Let's write a class | ||||
| containing two tests:: | ||||
| 
 | ||||
|     # content of test_class.py | ||||
|     class TestClass: | ||||
|  | @ -131,7 +131,7 @@ run the module by passing its filename:: | |||
|     ================================= FAILURES ================================= | ||||
|     ____________________________ TestClass.test_two ____________________________ | ||||
|      | ||||
|     self = <test_class.TestClass instance at 0x178b2d8> | ||||
|     self = <test_class.TestClass instance at 0x187d758> | ||||
|      | ||||
|         def test_two(self): | ||||
|             x = "hello" | ||||
|  | @ -140,7 +140,7 @@ run the module by passing its filename:: | |||
|     E        +  where False = hasattr('hello', 'check') | ||||
|      | ||||
|     test_class.py:8: AssertionError | ||||
|     1 failed, 1 passed in 0.02 seconds | ||||
|     1 failed, 1 passed in 0.04 seconds | ||||
| 
 | ||||
| The first test passed, the second failed. Again we can easily see | ||||
| the intermediate values used in the assertion, helping us to | ||||
|  | @ -169,7 +169,7 @@ before performing the test function call.  Let's just run it:: | |||
|     ================================= FAILURES ================================= | ||||
|     _____________________________ test_needsfiles ______________________________ | ||||
|      | ||||
|     tmpdir = local('/tmp/pytest-101/test_needsfiles0') | ||||
|     tmpdir = local('/tmp/pytest-92/test_needsfiles0') | ||||
|      | ||||
|         def test_needsfiles(tmpdir): | ||||
|             print tmpdir | ||||
|  | @ -178,8 +178,8 @@ before performing the test function call.  Let's just run it:: | |||
|      | ||||
|     test_tmpdir.py:3: AssertionError | ||||
|     ----------------------------- Captured stdout ------------------------------ | ||||
|     /tmp/pytest-101/test_needsfiles0 | ||||
|     1 failed in 0.03 seconds | ||||
|     /tmp/pytest-92/test_needsfiles0 | ||||
|     1 failed in 0.14 seconds | ||||
| 
 | ||||
| Before the test runs, a unique-per-test-invocation temporary directory | ||||
| was created.  More info at :ref:`tmpdir handling`. | ||||
|  | @ -194,7 +194,7 @@ where to go next | |||
| Here are a few suggestions where to go next: | ||||
| 
 | ||||
| * :ref:`cmdline` for command line invocation examples | ||||
| * :ref:`good practises` for virtualenv, test layout, genscript support | ||||
| * :ref:`good practises <goodpractises>` for virtualenv, test layout, genscript support | ||||
| * :ref:`apiref` for documentation and examples on using py.test | ||||
| * :ref:`plugins` managing and writing plugins | ||||
| 
 | ||||
|  | @ -228,7 +228,7 @@ py.test not found on Windows despite installation? | |||
| - **Jython2.5.1 on Windows XP**: `Jython does not create command line launchers`_ | ||||
|   so ``py.test`` will not work correctly.  You may install py.test on | ||||
|   CPython and type ``py.test --genscript=mytest`` and then use | ||||
|   ``jython mytest`` to run py.test for your tests to run in Jython. | ||||
|   ``jython mytest`` to run py.test for your tests to run with Jython. | ||||
| 
 | ||||
|  :ref:`examples` for more complex examples | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,14 +8,11 @@ Good Integration Practises | |||
| Work with virtual environments | ||||
| ----------------------------------------------------------- | ||||
| 
 | ||||
| We recommend to work with virtualenv_ environments and use easy_install_ | ||||
| We recommend to use virtualenv_ environments and use easy_install_ | ||||
| (or pip_) for installing your application dependencies as well as | ||||
| the ``pytest`` package itself.  This way you get a much more reproducible | ||||
| the ``pytest`` package itself.  This way you will get a much more reproducible | ||||
| environment.  A good tool to help you automate test runs against multiple | ||||
| dependency configurations or Python interpreters is `tox`_, | ||||
| independently created by the main py.test author.  The latter | ||||
| is also useful for integration with the continuous integration | ||||
| server Hudson_. | ||||
| dependency configurations or Python interpreters is `tox`_. | ||||
| 
 | ||||
| .. _`virtualenv`: http://pypi.python.org/pypi/virtualenv | ||||
| .. _`buildout`: http://www.buildout.org/ | ||||
|  | @ -24,10 +21,11 @@ server Hudson_. | |||
| Use tox and Continuous Integration servers | ||||
| ------------------------------------------------- | ||||
| 
 | ||||
| If you are (often) releasing code to the public you | ||||
| If you frequently relase code to the public you | ||||
| may want to look into `tox`_, the virtualenv test automation | ||||
| tool and its `pytest support <http://codespeak.net/tox/example/pytest.html>`_. | ||||
| The basic idea is to generate a JUnitXML file through the ``--junitxml=PATH`` option and have a continuous integration server like Hudson_ pick it up. | ||||
| The basic idea is to generate a JUnitXML file through the ``--junitxml=PATH`` option and have a continuous integration server like Jenkins_ pick it up | ||||
| and generate reports. | ||||
| 
 | ||||
| .. _standalone: | ||||
| .. _`genscript method`: | ||||
|  | @ -90,7 +88,7 @@ If you now type:: | |||
| this will execute your tests using ``runtest.py``. As this is a | ||||
| standalone version of ``py.test`` no prior installation whatsoever is | ||||
| required for calling the test command. You can also pass additional | ||||
| arguments to the subprocess-calls like your test directory or other | ||||
| arguments to the subprocess-calls such as your test directory or other | ||||
| options. | ||||
| 
 | ||||
| .. _`test discovery`: | ||||
|  | @ -101,14 +99,14 @@ Conventions for Python test discovery | |||
| 
 | ||||
| ``py.test`` implements the following standard test discovery: | ||||
| 
 | ||||
| * collection starts from initial command line arguments | ||||
| * collection starts from the initial command line arguments | ||||
|   which may be directories, filenames or test ids. | ||||
| * recurse into directories, unless they match :confval:`norecursedirs` | ||||
| * ``test_*.py`` or ``*_test.py`` files, imported by their `package name`_. | ||||
| * ``Test`` prefixed test classes (without an ``__init__`` method) | ||||
| * ``test_`` prefixed test functions or methods are test items | ||||
| 
 | ||||
| For changing and customization example, see :doc:`example/pythoncollection`. | ||||
| For examples of how to cnd cusotmize your test discovery :doc:`example/pythoncollection`. | ||||
| 
 | ||||
| py.test additionally discovers tests using the standard | ||||
| :ref:`unittest.TestCase <unittest.TestCase>` subclassing technique. | ||||
|  | @ -154,8 +152,8 @@ You can always run your tests by pointing to it:: | |||
| 
 | ||||
|     Test modules are imported under their fully qualified name as follows: | ||||
| 
 | ||||
|     * find ``basedir`` -- this is the first "upward" directory not | ||||
|       containing an ``__init__.py`` | ||||
|     * find ``basedir`` -- this is the first "upward" (towards the root) | ||||
|       directory not containing an ``__init__.py`` | ||||
| 
 | ||||
|     * perform ``sys.path.insert(0, basedir)`` to make the fully | ||||
|       qualified test module path importable. | ||||
|  |  | |||
|  | @ -4,23 +4,25 @@ Welcome to ``py.test``! | |||
| ============================================= | ||||
| 
 | ||||
| 
 | ||||
| - **a mature fully featured testing tool** | ||||
| - **a mature full-featured testing tool** | ||||
| 
 | ||||
|  - runs on Posix/Windows, Python 2.4-3.2, PyPy and Jython | ||||
|  - continuously `tested on many Python interpreters <http://hudson.testrun.org/view/pytest/job/pytest/>`_ | ||||
|  - used in :ref:`many projects and organisations <projects>`, ranging from 10 to 10000 tests | ||||
|  - used in :ref:`many projects and organisations <projects>`, in test | ||||
|    suites ranging from 10 to 10s of thousands of tests | ||||
|  - has :ref:`comprehensive documentation <toc>` | ||||
|  - comes with :ref:`tested examples <examples>` | ||||
|  - supports :ref:`good integration practises <goodpractises>` | ||||
| 
 | ||||
| - **provides no-boilerplate testing** | ||||
| 
 | ||||
|  - makes it :ref:`easy to get started <getstarted>`, refined :ref:`usage options <usage>` | ||||
|  - makes it :ref:`easy to get started <getstarted>`, | ||||
|  - refined :ref:`usage options <usage>` | ||||
|  - :ref:`assert with the assert statement` | ||||
|  - helpful :ref:`traceback and failing assertion reporting <tbreportdemo>` | ||||
|  - allows :ref:`print debugging <printdebugging>` and :ref:`generic output | ||||
|    capturing <captures>` | ||||
|  - supports :pep:`8` compliant coding style in tests | ||||
|  - allows :ref:`print debugging <printdebugging>` and :ref:`the | ||||
|    capturing of standard output during test execution <captures>` | ||||
|  - supports :pep:`8` compliant coding styles in tests | ||||
| 
 | ||||
| - **supports functional testing and complex test setups** | ||||
| 
 | ||||
|  | @ -39,7 +41,7 @@ Welcome to ``py.test``! | |||
|    tests, including running testcases made for Django and trial | ||||
|  - supports extended :ref:`xUnit style setup <xunitsetup>` | ||||
|  - supports domain-specific :ref:`non-python tests` | ||||
|  - supports generating testing coverage reports | ||||
|  - supports the generation of testing coverage reports | ||||
|  - `Javascript unit- and functional testing`_ | ||||
| 
 | ||||
| - **extensive plugin and customization system** | ||||
|  |  | |||
|  | @ -16,4 +16,5 @@ | |||
| .. _`pip`: http://pypi.python.org/pypi/pip | ||||
| .. _`virtualenv`: http://pypi.python.org/pypi/virtualenv | ||||
| .. _hudson: http://hudson-ci.org/ | ||||
| .. _jenkins: http://jenkins-ci.org/ | ||||
| .. _tox: http://codespeak.net/tox | ||||
|  |  | |||
							
								
								
									
										14
									
								
								doc/mark.txt
								
								
								
								
							
							
						
						
									
										14
									
								
								doc/mark.txt
								
								
								
								
							|  | @ -7,12 +7,12 @@ mark test functions with attributes | |||
| .. currentmodule:: _pytest.mark | ||||
| 
 | ||||
| By using the ``pytest.mark`` helper you can instantiate | ||||
| decorators that will set named meta data on test functions. | ||||
| decorators that will set named metadata on test functions. | ||||
| 
 | ||||
| Marking a single function | ||||
| ---------------------------------------------------- | ||||
| 
 | ||||
| You can "mark" a test function with meta data like this:: | ||||
| You can "mark" a test function with metadata like this:: | ||||
| 
 | ||||
|     import pytest | ||||
|     @pytest.mark.webtest | ||||
|  | @ -20,7 +20,7 @@ You can "mark" a test function with meta data like this:: | |||
|         ... | ||||
| 
 | ||||
| This will set the function attribute ``webtest`` to a :py:class:`MarkInfo` | ||||
| instance.  You can also specify parametrized meta data like this:: | ||||
| instance.  You can also specify parametrized metadata like this:: | ||||
| 
 | ||||
|     # content of test_mark.py | ||||
| 
 | ||||
|  | @ -44,7 +44,7 @@ Marking whole classes or modules | |||
| ---------------------------------------------------- | ||||
| 
 | ||||
| If you are programming with Python2.6 you may use ``pytest.mark`` decorators | ||||
| with classes to apply markers to all its test methods:: | ||||
| with classes to apply markers to all of its test methods:: | ||||
| 
 | ||||
|     # content of test_mark_classlevel.py | ||||
|     import pytest | ||||
|  | @ -88,7 +88,7 @@ You can use the ``-k`` command line option to select tests:: | |||
| 
 | ||||
|     $ py.test -k webtest  # running with the above defined examples yields | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 4 items | ||||
|      | ||||
|     test_mark.py .. | ||||
|  | @ -100,7 +100,7 @@ And you can also run all tests except the ones that match the keyword:: | |||
| 
 | ||||
|     $ py.test -k-webtest | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 4 items | ||||
|      | ||||
|     ===================== 4 tests deselected by '-webtest' ===================== | ||||
|  | @ -110,7 +110,7 @@ Or to only select the class:: | |||
| 
 | ||||
|     $ py.test -kTestClass | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 4 items | ||||
|      | ||||
|     test_mark_classlevel.py .. | ||||
|  |  | |||
|  | @ -9,8 +9,8 @@ on global settings or which invokes code which cannot be easily | |||
| tested such as network access.  The ``monkeypatch`` function argument | ||||
| helps you to safely set/delete an attribute, dictionary item or | ||||
| environment variable or to modify ``sys.path`` for importing. | ||||
| See the `monkeypatch blog post`_ one some introduction material | ||||
| and motivation. | ||||
| See the `monkeypatch blog post`_ for some introduction material | ||||
| and a discussion of its motivation. | ||||
| 
 | ||||
| .. _`monkeypatch blog post`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/ | ||||
| 
 | ||||
|  | @ -18,7 +18,7 @@ and motivation. | |||
| Simple example: patching ``os.path.expanduser`` | ||||
| --------------------------------------------------- | ||||
| 
 | ||||
| If you e.g. want to pretend that ``os.expanduser`` returns a certain | ||||
| If, for instance, you want to pretend that ``os.expanduser`` returns a certain | ||||
| directory, you can use the :py:meth:`monkeypatch.setattr` method to | ||||
| patch this function before calling into a function which uses it:: | ||||
| 
 | ||||
|  | @ -39,7 +39,7 @@ will be undone. | |||
| .. background check: | ||||
|    $ py.test | ||||
|    =========================== test session starts ============================ | ||||
|    platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|    platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|    collecting ... collected 0 items | ||||
|     | ||||
|    =============================  in 0.00 seconds ============================= | ||||
|  |  | |||
|  | @ -16,5 +16,5 @@ these renaming rules:: | |||
|     py.test.cmdline.main -> pytest.main | ||||
| 
 | ||||
| The old ``py.test.*`` ways to access functionality remain | ||||
| valid but you are encouraged to do global renames according | ||||
| valid but you are encouraged to do global renaming according | ||||
| to the above rules in your test code. | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| .. _plugins: | ||||
| 
 | ||||
| Working with plugins and conftest files | ||||
| ============================================= | ||||
| 
 | ||||
| .. _`local plugin`: | ||||
| 
 | ||||
| py.test implements all aspects of configuration, collection, running and reporting by calling `well specified hooks`_.  Virtually any Python module can be registered as a plugin.  It can implement any number of hook functions (usually two or three) which all have a ``pytest_`` prefix, making hook functions easy to distinguish and find.  There are three basic locations types: | ||||
| 
 | ||||
| * `builtin plugins`_: loaded from py.test's own ``pytest/plugin`` directory. | ||||
|  | @ -12,14 +12,17 @@ py.test implements all aspects of configuration, collection, running and reporti | |||
| .. _`pytest/plugin`: http://bitbucket.org/hpk42/pytest/src/tip/pytest/plugin/ | ||||
| .. _`conftest.py plugins`: | ||||
| .. _`conftest.py`: | ||||
| .. _`localplugin`: | ||||
| .. _`conftest`: | ||||
| 
 | ||||
| conftest.py: local per-directory plugins | ||||
| -------------------------------------------------------------- | ||||
| 
 | ||||
| local ``conftest.py`` plugins contain directory-specific hook | ||||
| implementations.  Session and test running activities will | ||||
| invoke all hooks defined in "higher up" ``conftest.py`` files. | ||||
| Example: Assume the following layout and content of files:: | ||||
| invoke all hooks defined in ``conftest.py`` files closer to the | ||||
| root of the filesystem.  Example: Assume the following layout | ||||
| and content of files:: | ||||
| 
 | ||||
|     a/conftest.py: | ||||
|         def pytest_runtest_setup(item): | ||||
|  | @ -39,11 +42,6 @@ Here is how you might run it:: | |||
|      py.test test_flat.py   # will not show "setting up" | ||||
|      py.test a/test_sub.py  # will show "setting up" | ||||
| 
 | ||||
| A note on ordering: ``py.test`` loads all ``conftest.py`` files upwards | ||||
| from the command line file arguments.  It usually performs look up | ||||
| right-to-left, i.e.  the hooks in "closer" conftest files will be called | ||||
| earlier than further away ones. | ||||
| 
 | ||||
| .. Note:: | ||||
|     If you have ``conftest.py`` files which do not reside in a | ||||
|     python package directory (i.e. one containing an ``__init__.py``) then | ||||
|  | @ -112,12 +110,12 @@ Making your plugin installable by others | |||
| ----------------------------------------------- | ||||
| 
 | ||||
| If you want to make your plugin externally available, you | ||||
| may define a so called entry point for your distribution so | ||||
| may define a so-called entry point for your distribution so | ||||
| that ``py.test`` finds your plugin module.  Entry points are | ||||
| a feature that is provided by `setuptools`_ or `Distribute`_. | ||||
| The concrete entry point is ``pytest11``.  To make your plugin | ||||
| available you can insert the following lines in your | ||||
| setuptools/distribute-based setup-invocation: | ||||
| py.test looks up the ``pytest11`` entrypoint to discover its | ||||
| plugins and you can thus make your plugin available by definig | ||||
| it in your setuptools/distribute-based setup-invocation: | ||||
| 
 | ||||
| .. sourcecode:: python | ||||
| 
 | ||||
|  | @ -137,8 +135,8 @@ setuptools/distribute-based setup-invocation: | |||
|     ) | ||||
| 
 | ||||
| If a package is installed this way, py.test will load | ||||
| ``myproject.pluginmodule`` and accordingly call functions | ||||
| if they match the `well specified hooks`_. | ||||
| ``myproject.pluginmodule`` as a plugin which can define | ||||
| `well specified hooks`_. | ||||
| 
 | ||||
| Plugin discovery order at tool startup | ||||
| -------------------------------------------- | ||||
|  | @ -260,11 +258,11 @@ hook specification and validation | |||
| 
 | ||||
| py.test calls hook functions to implement initialization, running, | ||||
| test execution and reporting.  When py.test loads a plugin it validates | ||||
| that all hook functions conform to their respective hook specification. | ||||
| that each hook function conforms to its respective hook specification. | ||||
| Each hook function name and its argument names need to match a hook | ||||
| specification exactly but it is allowed for a hook function to accept | ||||
| *less* parameters than specified.  If you mistype argument names or the | ||||
| hook name itself you get useful errors. | ||||
| specification.  However, a hook function may accept *fewer* parameters | ||||
| by simply not specifying them.  If you mistype argument names or the | ||||
| hook name itself you get an error showing the available arguments. | ||||
| 
 | ||||
| initialisation, command line and configuration hooks | ||||
| -------------------------------------------------------------------- | ||||
|  | @ -292,8 +290,9 @@ All all runtest related hooks receive a :py:class:`pytest.Item` object. | |||
| 
 | ||||
| For deeper understanding you may look at the default implementation of | ||||
| these hooks in :py:mod:`_pytest.runner` and maybe also | ||||
| in :py:mod:`_pytest.pdb` which intercepts creation | ||||
| of reports in order to drop to interactive debugging. | ||||
| in :py:mod:`_pytest.pdb` which interacts with :py:mod:`_pytest.capture` | ||||
| and its input/output capturing in order to immediately drop | ||||
| into interactive debugging when a test failure occurs. | ||||
| 
 | ||||
| The :py:mod:`_pytest.terminal` reported specifically uses | ||||
| the reporting hook to print information about a test run. | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ Some organisations using py.test | |||
| * `Shootq <http://web.shootq.com/>`_ | ||||
| * `Stups department of Heinrich Heine University Düsseldorf <http://www.stups.uni-duesseldorf.de/projects.php>`_ | ||||
| * `cellzome <http://www.cellzome.com/>`_ | ||||
| * `Open End, Gotenborg <http://www.openend.se>`_ | ||||
| * `Open End, Gothenborg <http://www.openend.se>`_ | ||||
| * `Laboraratory of Bioinformatics, Warsaw <http://genesilico.pl/>`_ | ||||
| * `merlinux, Germany <http://merlinux.eu>`_ | ||||
| * many more ... (please be so kind to send a note via :ref:`contact`) | ||||
|  |  | |||
|  | @ -1,2 +1,2 @@ | |||
| [pytest] | ||||
| # just defined to prevent the root level tox.ini to kick in | ||||
| # just defined to prevent the root level tox.ini from kicking in | ||||
|  |  | |||
|  | @ -5,19 +5,18 @@ skip and xfail mechanisms | |||
| ===================================================================== | ||||
| 
 | ||||
| You can skip or "xfail" test functions, either by marking functions | ||||
| through a decorator or by calling the ``pytest.skip|xfail`` functions. | ||||
| with a decorator or by calling the ``pytest.skip|xfail`` functions. | ||||
| 
 | ||||
| A *skip* means that you expect your test to pass unless a certain configuration or condition (e.g. wrong Python interpreter, missing dependency) prevents it to run.  And *xfail* means that you expect your test to fail because there is an | ||||
| implementation problem.  py.test counts and lists *xfailing* tests separately | ||||
| and you can provide info such as a bug number or a URL to provide a | ||||
| human readable problem context. | ||||
| and it is possible to give additional information, such as bug number or a URL. | ||||
| 
 | ||||
| Usually detailed information about skipped/xfailed tests is not shown | ||||
| Detailed information about skipped/xfailed tests is by default not shown | ||||
| at the end of a test run to avoid cluttering the output.  You can use | ||||
| the ``-r`` option to see details corresponding to the "short" letters | ||||
| shown in the test progress:: | ||||
| 
 | ||||
|     py.test -rxs  # show extra info on skips and xfail tests | ||||
|     py.test -rxs  # show extra info on skips and xfails | ||||
| 
 | ||||
| (See :ref:`how to change command line options defaults`) | ||||
| 
 | ||||
|  | @ -26,7 +25,7 @@ shown in the test progress:: | |||
| Skipping a single function | ||||
| ------------------------------------------- | ||||
| 
 | ||||
| Here is an example for marking a test function to be skipped | ||||
| Here is an example of marking a test function to be skipped | ||||
| when run on a Python3 interpreter:: | ||||
| 
 | ||||
|     import sys | ||||
|  | @ -60,7 +59,7 @@ on a test configuration value:: | |||
|     def test_function(...): | ||||
|         ... | ||||
| 
 | ||||
| Create a shortcut for your conditional skip decorator | ||||
| You can create a shortcut for your conditional skip decorator | ||||
| at module level like this:: | ||||
| 
 | ||||
|     win32only = pytest.mark.skipif("sys.platform != 'win32'") | ||||
|  | @ -73,9 +72,9 @@ at module level like this:: | |||
| skip all test functions of a class | ||||
| -------------------------------------- | ||||
| 
 | ||||
| As with all function :ref:`marking` you can do it at | ||||
| As with all function :ref:`mark` you can skip test functions at the | ||||
| `whole class- or module level`_.  Here is an example | ||||
| for skipping all methods of a test class based on platform:: | ||||
| for skipping all methods of a test class based on the platform:: | ||||
| 
 | ||||
|     class TestPosixCalls: | ||||
|         pytestmark = pytest.mark.skipif("sys.platform == 'win32'") | ||||
|  | @ -93,9 +92,7 @@ the skipif decorator on classes:: | |||
|         def test_function(self): | ||||
|             "will not be setup or run under 'win32' platform" | ||||
| 
 | ||||
| It is fine in general to apply multiple "skipif" decorators | ||||
| on a single function - this means that if any of the conditions | ||||
| apply the function will be skipped. | ||||
| Using multiple "skipif" decorators on a single function is generally fine - it means that if any of the conditions apply the function execution will be skipped. | ||||
| 
 | ||||
| .. _`whole class- or module level`: mark.html#scoped-marking | ||||
| 
 | ||||
|  | @ -122,16 +119,16 @@ By specifying on the commandline:: | |||
| you can force the running and reporting of an ``xfail`` marked test | ||||
| as if it weren't marked at all. | ||||
| 
 | ||||
| Same as with skipif_ you can also selectively expect a failure | ||||
| depending on platform:: | ||||
| As with skipif_ you can also mark your expectation of a failure | ||||
| on a particular platform:: | ||||
| 
 | ||||
|     @pytest.mark.xfail("sys.version_info >= (3,0)") | ||||
|     def test_function(): | ||||
|         ... | ||||
| 
 | ||||
| You can also avoid running an "xfail" test at all or | ||||
| You can furthermore prevent the running of an "xfail" test or | ||||
| specify a reason such as a bug ID or similar.  Here is | ||||
| a simple test file with usages: | ||||
| a simple test file with the several usages: | ||||
| 
 | ||||
| .. literalinclude:: example/xfail_demo.py | ||||
| 
 | ||||
|  | @ -139,10 +136,10 @@ Running it with the report-on-xfail option gives this output:: | |||
| 
 | ||||
|     example $ py.test -rx xfail_demo.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     collecting ... collected 5 items | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 6 items | ||||
|      | ||||
|     xfail_demo.py xxxxx | ||||
|     xfail_demo.py xxxxxx | ||||
|     ========================= short test summary info ========================== | ||||
|     XFAIL xfail_demo.py::test_hello | ||||
|     XFAIL xfail_demo.py::test_hello2 | ||||
|  | @ -152,9 +149,11 @@ Running it with the report-on-xfail option gives this output:: | |||
|     XFAIL xfail_demo.py::test_hello4 | ||||
|       bug 110 | ||||
|     XFAIL xfail_demo.py::test_hello5 | ||||
|       condition: pytest.__version__[0] != "17" | ||||
|     XFAIL xfail_demo.py::test_hello6 | ||||
|       reason: reason | ||||
|      | ||||
|     ======================== 5 xfailed in 0.04 seconds ========================= | ||||
|     ======================== 6 xfailed in 0.06 seconds ========================= | ||||
| 
 | ||||
| imperative xfail from within a test or setup function | ||||
| ------------------------------------------------------ | ||||
|  | @ -177,8 +176,8 @@ or within a test or test setup function:: | |||
|     docutils = pytest.importorskip("docutils") | ||||
| 
 | ||||
| If ``docutils`` cannot be imported here, this will lead to a | ||||
| skip outcome of the test.  You can also skip depending if | ||||
| if a library does not come with a high enough version:: | ||||
| skip outcome of the test.  You can also skip based on the | ||||
| version number of a library:: | ||||
| 
 | ||||
|     docutils = pytest.importorskip("docutils", minversion="0.3") | ||||
| 
 | ||||
|  | @ -188,7 +187,7 @@ imperative skip from within a test or setup function | |||
| ------------------------------------------------------ | ||||
| 
 | ||||
| If for some reason you cannot declare skip-conditions | ||||
| you can also imperatively produce a Skip-outcome from | ||||
| you can also imperatively produce a skip-outcome from | ||||
| within test or setup code.  Example:: | ||||
| 
 | ||||
|     def test_function(): | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ Running this would result in a passed test except for the last | |||
| 
 | ||||
|     $ py.test test_tmpdir.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_tmpdir.py F | ||||
|  | @ -36,7 +36,7 @@ Running this would result in a passed test except for the last | |||
|     ================================= FAILURES ================================= | ||||
|     _____________________________ test_create_file _____________________________ | ||||
|      | ||||
|     tmpdir = local('/tmp/pytest-102/test_create_file0') | ||||
|     tmpdir = local('/tmp/pytest-93/test_create_file0') | ||||
|      | ||||
|         def test_create_file(tmpdir): | ||||
|             p = tmpdir.mkdir("sub").join("hello.txt") | ||||
|  | @ -47,14 +47,14 @@ Running this would result in a passed test except for the last | |||
|     E       assert 0 | ||||
|      | ||||
|     test_tmpdir.py:7: AssertionError | ||||
|     ========================= 1 failed in 0.03 seconds ========================= | ||||
|     ========================= 1 failed in 0.04 seconds ========================= | ||||
| 
 | ||||
| .. _`base temporary directory`: | ||||
| 
 | ||||
| the default base temporary directory | ||||
| ----------------------------------------------- | ||||
| 
 | ||||
| Temporary directories are by default created as sub directories of | ||||
| Temporary directories are by default created as sub-directories of | ||||
| the system temporary directory.  The base name will be ``pytest-NUM`` where | ||||
| ``NUM`` will be incremented with each test run.  Moreover, entries older | ||||
| than 3 temporary directories will be removed. | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ py.test has limited support for running Python `unittest.py style`_ tests. | |||
| It will automatically collect ``unittest.TestCase`` subclasses | ||||
| and their ``test`` methods in test files.  It will invoke | ||||
| ``setUp/tearDown`` methods but also perform py.test's standard ways | ||||
| of treating tests like e.g. IO capturing:: | ||||
| of treating tests such as IO capturing:: | ||||
| 
 | ||||
|     # content of test_unittest.py | ||||
| 
 | ||||
|  | @ -24,7 +24,7 @@ Running it yields:: | |||
| 
 | ||||
|     $ py.test test_unittest.py | ||||
|     =========================== test session starts ============================ | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.1 | ||||
|     platform linux2 -- Python 2.6.6 -- pytest-2.0.2.dev2 | ||||
|     collecting ... collected 1 items | ||||
|      | ||||
|     test_unittest.py F | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ calling pytest through ``python -m pytest`` | |||
| 
 | ||||
| .. versionadded:: 2.0 | ||||
| 
 | ||||
| If you use Python-2.5 or above you can invoke testing through the | ||||
| If you use Python-2.5 or later you can invoke testing through the | ||||
| Python interpreter from the command line:: | ||||
| 
 | ||||
|     python -m pytest [...] | ||||
|  | @ -20,8 +20,8 @@ Python interpreter from the command line:: | |||
| This is equivalent to invoking the command line script ``py.test [...]`` | ||||
| directly. | ||||
| 
 | ||||
| Getting help on version, option names, environment vars | ||||
| ----------------------------------------------------------- | ||||
| Getting help on version, option names, environment variables | ||||
| -------------------------------------------------------------- | ||||
| 
 | ||||
| :: | ||||
| 
 | ||||
|  | @ -96,7 +96,7 @@ can use a helper:: | |||
| .. versionadded: 2.0.0 | ||||
| 
 | ||||
| In previous versions you could only enter PDB tracing if | ||||
| you :ref:`disable capturing`. | ||||
| you disable capturing on the command line via ``py.test -s``. | ||||
| 
 | ||||
| creating JUnitXML format files | ||||
| ---------------------------------------------------- | ||||
|  |  | |||
|  | @ -7,13 +7,13 @@ xdist: pytest distributed testing plugin | |||
| The `pytest-xdist`_ plugin extends py.test with some unique | ||||
| test execution modes: | ||||
| 
 | ||||
| * Looponfail: run your tests repeatedly in a subprocess.  After each run py.test | ||||
|   waits until a file in your project changes and then re-runs the previously | ||||
|   failing tests.  This is repeated until all tests pass after which again | ||||
|   a full run is performed. | ||||
| * Looponfail: run your tests repeatedly in a subprocess.  After each | ||||
|   run, py.test waits until a file in your project changes and then | ||||
|   re-runs the previously failing tests.  This is repeated until all | ||||
|   tests pass.  At this point a full run is again performed. | ||||
| 
 | ||||
| * multiprocess Load-balancing: if you have multiple CPUs or hosts you can use | ||||
|   those for a combined test run.  This allows to speed up | ||||
|   them for a combined test run.  This allows to speed up | ||||
|   development or to use special resources of remote machines. | ||||
| 
 | ||||
| * Multi-Platform coverage: you can specify different Python interpreters | ||||
|  | @ -25,8 +25,8 @@ are reported back and displayed to your local terminal. | |||
| You may specify different Python versions and interpreters. | ||||
| 
 | ||||
| 
 | ||||
| Installation | ||||
| ----------------------- | ||||
| Installation of xdist plugin | ||||
| ------------------------------ | ||||
| 
 | ||||
| Install the plugin with:: | ||||
| 
 | ||||
|  | @ -55,13 +55,13 @@ To send tests to multiple CPUs, type:: | |||
|     py.test -n NUM | ||||
| 
 | ||||
| Especially for longer running tests or tests requiring | ||||
| a lot of IO this can lead to considerable speed ups. | ||||
| a lot of I/O this can lead to considerable speed ups. | ||||
| 
 | ||||
| 
 | ||||
| Running tests in a Python subprocess | ||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| To instantiate a python2.4 sub process and send tests to it, you may type:: | ||||
| To instantiate a Python-2.4 subprocess and send tests to it, you may type:: | ||||
| 
 | ||||
|     py.test -d --tx popen//python=python2.4 | ||||
| 
 | ||||
|  | @ -70,10 +70,10 @@ Python interpreter, found in your system binary lookup path. | |||
| 
 | ||||
| If you prefix the --tx option value like this:: | ||||
| 
 | ||||
|     --tx 3*popen//python=python2.4 | ||||
|     py.test -d --tx 3*popen//python=python2.4 | ||||
| 
 | ||||
| then three subprocesses would be created and tests | ||||
| will be load-balanced across these three processes. | ||||
| then three subprocesses would be created and the tests | ||||
| will be distributed to three subprocesses and run simultanously. | ||||
| 
 | ||||
| .. _looponfailing: | ||||
| 
 | ||||
|  | @ -82,11 +82,13 @@ Running tests in looponfailing mode | |||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| For refactoring a project with a medium or large test suite | ||||
| you can use the looponfailing mode, simply add the ``--f`` option:: | ||||
| you can use the looponfailing mode. Simply add the ``--f`` option:: | ||||
| 
 | ||||
|     py.test -f | ||||
|     | ||||
| and py.test will run your tests, then wait for file changes and re-run the failing test set.  Of course you can pass in more options to select tests or test files.  File changes are detected by looking at the root directory - you can override this automatic default by an ini-file setting:: | ||||
| and py.test will run your tests. Assuming you have failures it will then | ||||
| wait for file changes and re-run the failing test set.  File changes are detected by looking at ``looponfailingroots`` root directories and all of their contents (recursively).  If the default for this value does not work for you you | ||||
| can change it in your project by setting a configuration option:: | ||||
| 
 | ||||
|     # content of a pytest.ini, setup.cfg or tox.ini file | ||||
|     [pytest] | ||||
|  | @ -98,26 +100,28 @@ Sending tests to remote SSH accounts | |||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| Suppose you have a package ``mypkg`` which contains some | ||||
| tests that you can successfully run locally. And you | ||||
| tests that you can successfully run locally. And you also | ||||
| have a ssh-reachable machine ``myhost``.  Then | ||||
| you can ad-hoc distribute your tests by typing:: | ||||
| 
 | ||||
|     py.test -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg | ||||
| 
 | ||||
| This will synchronize your ``mypkg`` package directory | ||||
| to an remote ssh account and then locally collect tests | ||||
| and send them to remote places for execution. | ||||
| with a remote ssh account and then collect and run your | ||||
| tests at the remote side. | ||||
| 
 | ||||
| You can specify multiple ``--rsyncdir`` directories | ||||
| to be sent to the remote side. | ||||
| 
 | ||||
| **NOTE:** For py.test to collect and send tests correctly | ||||
| you not only need to make sure all code and tests | ||||
| directories are rsynced, but that any test (sub) directory | ||||
| also has an ``__init__.py`` file because internally | ||||
| py.test references tests as a fully qualified python | ||||
| module path.  **You will otherwise get strange errors** | ||||
| during setup of the remote side. | ||||
| .. XXX CHECK | ||||
| 
 | ||||
|     **NOTE:** For py.test to collect and send tests correctly | ||||
|     you not only need to make sure all code and tests | ||||
|     directories are rsynced, but that any test (sub) directory | ||||
|     also has an ``__init__.py`` file because internally | ||||
|     py.test references tests as a fully qualified python | ||||
|     module path.  **You will otherwise get strange errors** | ||||
|     during setup of the remote side. | ||||
| 
 | ||||
| Sending tests to remote Socket Servers | ||||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
|  | @ -158,8 +162,7 @@ Specifying test exec environments in an ini file | |||
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
| 
 | ||||
| pytest (since version 2.0) supports ini-style configuration. | ||||
| You can for example make running with three subprocesses | ||||
| your default like this:: | ||||
| For example, you could make running with three subprocesses your default:: | ||||
| 
 | ||||
|     [pytest] | ||||
|     addopts = -n3 | ||||
|  |  | |||
|  | @ -65,7 +65,7 @@ Similarly, the following methods are called around each method invocation:: | |||
|         with a setup_method call. | ||||
|         """ | ||||
| 
 | ||||
| If you rather define test functions directly at module level | ||||
| If you would rather define test functions directly at module level | ||||
| you can also use the following functions to implement fixtures:: | ||||
| 
 | ||||
|     def setup_function(function): | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue