233 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| Installation and Getting Started
 | |
| ===================================
 | |
| 
 | |
| **Compatibility**: Python 2.4-3.2, Jython, PyPy on Unix/Posix and Windows
 | |
| 
 | |
| Installation
 | |
| ----------------------------------------
 | |
| 
 | |
| Installation options::
 | |
| 
 | |
|     easy_install -U pytest  # or
 | |
|     pip install -U pytest
 | |
| 
 | |
| To check your installation has installed the correct version::
 | |
| 
 | |
|     $ py.test --version
 | |
|     This is py.test version 2.0.0.dev19, imported from /home/hpk/p/pytest/pytest
 | |
| 
 | |
| If you get an error checkout :ref:`installation issues`.
 | |
| 
 | |
| Our first test run
 | |
| ----------------------------------------------------------
 | |
| 
 | |
| Let's create a first test file with a simple test function::
 | |
| 
 | |
|     # content of test_sample.py
 | |
|     def func(x):
 | |
|         return x + 1
 | |
| 
 | |
|     def test_answer():
 | |
|         assert func(3) == 5
 | |
| 
 | |
| That's it. You can execute the test function now::
 | |
| 
 | |
|     $ py.test
 | |
|     =========================== test session starts ============================
 | |
|     platform linux2 -- Python 2.6.5 -- pytest-2.0.0.dev19
 | |
|     test path 1: /tmp/doc-exec-404
 | |
|     
 | |
|     test_sample.py F
 | |
|     
 | |
|     ================================= FAILURES =================================
 | |
|     _______________________________ test_answer ________________________________
 | |
|     
 | |
|         def test_answer():
 | |
|     >       assert func(3) == 5
 | |
|     E       assert 4 == 5
 | |
|     E        +  where 4 = func(3)
 | |
|     
 | |
|     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`.
 | |
| 
 | |
| .. note::
 | |
| 
 | |
|     You can simply use the ``assert`` statement for coding expectations because
 | |
|     intermediate values will be presented to you. This is much easier than
 | |
|     learning all the `the JUnit legacy methods`_ which are even inconsistent
 | |
|     with Python's own coding guidelines (but consistent with
 | |
|     Java-style naming).
 | |
| 
 | |
|     There is only one seldomly hit caveat to using asserts: if your
 | |
|     assertion expression fails and has side effects then re-evaluating
 | |
|     it for presenting intermediate values can go wrong.  It's easy to fix:
 | |
|     compute the value ahead of the assert and then do the
 | |
|     assertion or use the assert "message" syntax::
 | |
| 
 | |
|        assert expr, "message" # show "message" if expr is not True
 | |
| 
 | |
| .. _`the JUnit legacy methods`: http://docs.python.org/library/unittest.html#test-cases
 | |
| 
 | |
| .. _`assert statement`: http://docs.python.org/reference/simple_stmts.html#the-assert-statement
 | |
| 
 | |
| Asserting a certain exception is raised
 | |
| --------------------------------------------------------------
 | |
| 
 | |
| If you want to assert some code raises an exception you can
 | |
| use the ``raises`` helper::
 | |
| 
 | |
|     # content of test_sysexit.py
 | |
|     import py
 | |
|     def f():
 | |
|         raise SystemExit(1)
 | |
| 
 | |
|     def test_mytest():
 | |
|         with py.test.raises(SystemExit):
 | |
|             f()
 | |
| 
 | |
| Running it with, this time in "quiet" reporting mode::
 | |
| 
 | |
|     $ py.test -q test_sysexit.py
 | |
|     .
 | |
|     1 passed in 0.01 seconds
 | |
| 
 | |
| .. todo:: For further ways to assert exceptions see the `raises`
 | |
| 
 | |
| 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::
 | |
| 
 | |
|     # content of test_class.py
 | |
|     class TestClass:
 | |
|         def test_one(self):
 | |
|             x = "this"
 | |
|             assert 'h' in x
 | |
| 
 | |
|         def test_two(self):
 | |
|             x = "hello"
 | |
|             assert hasattr(x, 'check')
 | |
| 
 | |
| The two tests are found because of the standard :ref:`test discovery`.
 | |
| There is no need to subclass anything.  We can simply
 | |
| run the module by passing its filename::
 | |
| 
 | |
|     $ py.test -q test_class.py
 | |
|     .F
 | |
|     ================================= FAILURES =================================
 | |
|     ____________________________ TestClass.test_two ____________________________
 | |
|     
 | |
|     self = <test_class.TestClass instance at 0x2c2c560>
 | |
|     
 | |
|         def test_two(self):
 | |
|             x = "hello"
 | |
|     >       assert hasattr(x, 'check')
 | |
|     E       assert hasattr('hello', 'check')
 | |
|     
 | |
|     test_class.py:8: AssertionError
 | |
|     1 failed, 1 passed in 0.02 seconds
 | |
| 
 | |
| The first test passed, the second failed. Again we can easily see
 | |
| the intermediate values used in the assertion, helping us to
 | |
| understand the reason for the failure.
 | |
| 
 | |
| Going functional: requesting a unique temporary directory
 | |
| --------------------------------------------------------------
 | |
| 
 | |
| For functional tests one often needs to create some files
 | |
| and pass them to application objects.  py.test provides
 | |
| the versatile :ref:`funcarg mechanism` which allows to request
 | |
| arbitrary resources, for example a unique temporary directory::
 | |
| 
 | |
|     # content of test_tmpdir.py
 | |
|     def test_needsfiles(tmpdir):
 | |
|         print tmpdir
 | |
|         assert 0
 | |
| 
 | |
| We list the name ``tmpdir`` in the test function signature and
 | |
| py.test will lookup and call a factory to create the resource 
 | |
| before performing the test function call.  Let's just run it::
 | |
| 
 | |
|     $ py.test -q test_tmpdir.py
 | |
|     F
 | |
|     ================================= FAILURES =================================
 | |
|     _____________________________ test_needsfiles ______________________________
 | |
|     
 | |
|     tmpdir = local('/tmp/pytest-240/test_needsfiles0')
 | |
|     
 | |
|         def test_needsfiles(tmpdir):
 | |
|             print tmpdir
 | |
|     >       assert 0
 | |
|     E       assert 0
 | |
|     
 | |
|     test_tmpdir.py:3: AssertionError
 | |
|     ----------------------------- Captured stdout ------------------------------
 | |
|     /tmp/pytest-240/test_needsfiles0
 | |
|     1 failed in 0.04 seconds
 | |
| 
 | |
| Before the test runs, a unique-per-test-invocation temporary directory
 | |
| was created.  More info at :ref:`tmpdir handling`.
 | |
| 
 | |
| You can find out what kind of builtin :ref:`funcargs` exist by typing::
 | |
| 
 | |
|     py.test --funcargs   # shows builtin and custom function arguments
 | |
| 
 | |
| 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:`apiref` for documentation and examples on using py.test
 | |
| * :ref:`plugins` managing and writing plugins
 | |
| 
 | |
| .. _`installation issues`:
 | |
| 
 | |
| Known Installation issues
 | |
| ------------------------------
 | |
| 
 | |
| easy_install or pip not found?
 | |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 | |
| 
 | |
| Consult `distribute docs <distribute>`_ to install the ``easy_install``
 | |
| tool on your machine.  You may also use the original but somewhat older
 | |
| `setuptools`_ project although we generally recommend to use
 | |
| ``distribute`` because it contains more bug fixes and also works for
 | |
| Python3.
 | |
| 
 | |
| For Python2 you can also consult pip_ for the popular ``pip`` tool.
 | |
| 
 | |
| However, If you want to install on Python3 you need to use Distribute_ which
 | |
| provides the ``easy_install`` utility.
 | |
| 
 | |
| 
 | |
| py.test not found on Windows despite installation?
 | |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 | |
| 
 | |
| .. _`Python for Windows`: http://www.imladris.com/Scripts/PythonForWindows.html
 | |
| 
 | |
| 
 | |
| - **Windows**: If "easy_install" or "py.test" are not found
 | |
|   please see here for preparing your environment for running
 | |
|   command line tools: `Python for Windows`_.  You may alternatively
 | |
|   use an `ActivePython install`_ which makes command line tools
 | |
|   automatically available under Windows.
 | |
| 
 | |
| .. _`ActivePython install`: http://www.activestate.com/activepython/downloads
 | |
| 
 | |
| .. _`Jython does not create command line launchers`: http://bugs.jython.org/issue1491
 | |
| 
 | |
| - **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.
 | |
| 
 | |
|  :ref:`examples` for more complex examples
 | |
| 
 | |
| .. include:: links.inc
 |