v2 of resources API draft
This commit is contained in:
parent
7a90bed19b
commit
dbaf7ee9d0
|
@ -24,7 +24,8 @@ you will see the return value of the function call::
|
|||
|
||||
$ py.test test_assert1.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_assert1.py F
|
||||
|
@ -38,7 +39,7 @@ you will see the return value of the function call::
|
|||
E + where 3 = f()
|
||||
|
||||
test_assert1.py:5: AssertionError
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
========================= 1 failed in 0.02 seconds =========================
|
||||
|
||||
py.test has support for showing the values of the most common subexpressions
|
||||
including calls, attributes, comparisons, and binary and unary
|
||||
|
@ -106,7 +107,8 @@ if you run this module::
|
|||
|
||||
$ py.test test_assert2.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_assert2.py F
|
||||
|
@ -125,7 +127,7 @@ if you run this module::
|
|||
E '5'
|
||||
|
||||
test_assert2.py:5: AssertionError
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
========================= 1 failed in 0.02 seconds =========================
|
||||
|
||||
Special comparisons are done for a number of cases:
|
||||
|
||||
|
@ -182,7 +184,7 @@ the conftest file::
|
|||
E vals: 1 != 2
|
||||
|
||||
test_foocompare.py:8: AssertionError
|
||||
1 failed in 0.01 seconds
|
||||
1 failed in 0.02 seconds
|
||||
|
||||
.. _assert-details:
|
||||
.. _`assert introspection`:
|
||||
|
|
|
@ -28,7 +28,8 @@ You can ask for available builtin or project-custom
|
|||
|
||||
$ py.test --funcargs
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collected 0 items
|
||||
pytestconfig
|
||||
the pytest config object with access to command line opts.
|
||||
|
@ -76,5 +77,7 @@ You can ask for available builtin or project-custom
|
|||
See http://docs.python.org/library/warnings.html for information
|
||||
on warning categories.
|
||||
|
||||
cov
|
||||
A pytest funcarg that provides access to the underlying coverage object.
|
||||
|
||||
============================= in 0.00 seconds =============================
|
||||
============================= in 0.01 seconds =============================
|
||||
|
|
|
@ -64,7 +64,8 @@ of the failing function and hide the other one::
|
|||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_module.py .F
|
||||
|
@ -78,8 +79,8 @@ of the failing function and hide the other one::
|
|||
|
||||
test_module.py:9: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
setting up <function test_func2 at 0x20160c8>
|
||||
==================== 1 failed, 1 passed in 0.01 seconds ====================
|
||||
setting up <function test_func2 at 0x228faa0>
|
||||
==================== 1 failed, 1 passed in 0.02 seconds ====================
|
||||
|
||||
Accessing captured output from a test function
|
||||
---------------------------------------------------
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
# The short X.Y version.
|
||||
version = release = "2.3.0.dev1"
|
||||
version = release = "2.3.0.dev5"
|
||||
|
||||
import sys, os
|
||||
|
||||
|
|
|
@ -23,4 +23,5 @@ Full pytest documentation
|
|||
:hidden:
|
||||
|
||||
changelog.txt
|
||||
examples/resources.txt
|
||||
|
||||
|
|
|
@ -44,9 +44,10 @@ then you can just invoke ``py.test`` without command line options::
|
|||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
mymodule.py .
|
||||
|
||||
========================= 1 passed in 0.02 seconds =========================
|
||||
========================= 1 passed in 0.07 seconds =========================
|
||||
|
|
|
@ -26,25 +26,29 @@ You can then restrict a test run to only run tests marked with ``webtest``::
|
|||
|
||||
$ py.test -v -m webtest
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1 -- /home/hpk/venv/1/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2 -- /home/hpk/venv/1/bin/python
|
||||
cachedir: /home/hpk/tmp/doc-exec-305/.cache
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_server.py:3: test_send_http PASSED
|
||||
|
||||
=================== 1 tests deselected by "-m 'webtest'" ===================
|
||||
================== 1 passed, 1 deselected in 0.00 seconds ==================
|
||||
================== 1 passed, 1 deselected in 0.02 seconds ==================
|
||||
|
||||
Or the inverse, running all tests except the webtest ones::
|
||||
|
||||
$ py.test -v -m "not webtest"
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1 -- /home/hpk/venv/1/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2 -- /home/hpk/venv/1/bin/python
|
||||
cachedir: /home/hpk/tmp/doc-exec-305/.cache
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_server.py:6: test_something_quick PASSED
|
||||
|
||||
================= 1 tests deselected by "-m 'not webtest'" =================
|
||||
================== 1 passed, 1 deselected in 0.01 seconds ==================
|
||||
================== 1 passed, 1 deselected in 0.02 seconds ==================
|
||||
|
||||
Registering markers
|
||||
-------------------------------------
|
||||
|
@ -143,38 +147,41 @@ the given argument::
|
|||
|
||||
$ py.test -k send_http # running with the above defined examples
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 4 items
|
||||
|
||||
test_server.py .
|
||||
|
||||
=================== 3 tests deselected by '-ksend_http' ====================
|
||||
================== 1 passed, 3 deselected in 0.01 seconds ==================
|
||||
================== 1 passed, 3 deselected in 0.02 seconds ==================
|
||||
|
||||
And you can also run all tests except the ones that match the keyword::
|
||||
|
||||
$ py.test -k-send_http
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 4 items
|
||||
|
||||
test_mark_classlevel.py ..
|
||||
test_server.py .
|
||||
|
||||
=================== 1 tests deselected by '-k-send_http' ===================
|
||||
================== 3 passed, 1 deselected in 0.01 seconds ==================
|
||||
================== 3 passed, 1 deselected in 0.02 seconds ==================
|
||||
|
||||
Or to only select the class::
|
||||
|
||||
$ py.test -kTestClass
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 4 items
|
||||
|
||||
test_mark_classlevel.py ..
|
||||
|
||||
=================== 2 tests deselected by '-kTestClass' ====================
|
||||
================== 2 passed, 2 deselected in 0.01 seconds ==================
|
||||
================== 2 passed, 2 deselected in 0.02 seconds ==================
|
||||
|
||||
.. _`adding a custom marker from a plugin`:
|
||||
|
||||
|
@ -223,23 +230,25 @@ the test needs::
|
|||
|
||||
$ py.test -E stage2
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_someenv.py s
|
||||
|
||||
======================== 1 skipped in 0.01 seconds =========================
|
||||
======================== 1 skipped in 0.02 seconds =========================
|
||||
|
||||
and here is one that specifies exactly the environment needed::
|
||||
|
||||
$ py.test -E stage1
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_someenv.py .
|
||||
|
||||
========================= 1 passed in 0.01 seconds =========================
|
||||
========================= 1 passed in 0.02 seconds =========================
|
||||
|
||||
The ``--markers`` option always gives you a list of available markers::
|
||||
|
||||
|
@ -298,7 +307,7 @@ Let's run this without capturing output and see what we get::
|
|||
glob args=('class',) kwargs={'x': 2}
|
||||
glob args=('module',) kwargs={'x': 1}
|
||||
.
|
||||
1 passed in 0.01 seconds
|
||||
1 passed in 0.02 seconds
|
||||
|
||||
marking platform specific tests with pytest
|
||||
--------------------------------------------------------------
|
||||
|
@ -351,25 +360,27 @@ then you will see two test skipped and two executed tests as expected::
|
|||
|
||||
$ py.test -rs # this option reports skip reasons
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 4 items
|
||||
|
||||
test_plat.py s.s.
|
||||
========================= short test summary info ==========================
|
||||
SKIP [2] /home/hpk/tmp/doc-exec-222/conftest.py:12: cannot run on platform linux2
|
||||
SKIP [2] /home/hpk/tmp/doc-exec-305/conftest.py:12: cannot run on platform linux2
|
||||
|
||||
=================== 2 passed, 2 skipped in 0.01 seconds ====================
|
||||
=================== 2 passed, 2 skipped in 0.02 seconds ====================
|
||||
|
||||
Note that if you specify a platform via the marker-command line option like this::
|
||||
|
||||
$ py.test -m linux2
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 4 items
|
||||
|
||||
test_plat.py .
|
||||
|
||||
=================== 3 tests deselected by "-m 'linux2'" ====================
|
||||
================== 1 passed, 3 deselected in 0.01 seconds ==================
|
||||
================== 1 passed, 3 deselected in 0.02 seconds ==================
|
||||
|
||||
then the unmarked-tests will not be run. It is thus a way to restrict the run to the specific tests.
|
||||
|
|
|
@ -49,7 +49,8 @@ You can now run the test::
|
|||
|
||||
$ py.test test_sample.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_sample.py F
|
||||
|
@ -57,7 +58,7 @@ You can now run the test::
|
|||
================================= FAILURES =================================
|
||||
_______________________________ test_answer ________________________________
|
||||
|
||||
mysetup = <conftest.MySetup instance at 0x17f21b8>
|
||||
mysetup = <conftest.MySetup instance at 0x27e5320>
|
||||
|
||||
def test_answer(mysetup):
|
||||
app = mysetup.myapp()
|
||||
|
@ -66,7 +67,7 @@ You can now run the test::
|
|||
E assert 54 == 42
|
||||
|
||||
test_sample.py:4: AssertionError
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
========================= 1 failed in 0.02 seconds =========================
|
||||
|
||||
This means that our ``mysetup`` object was successfully instantiated
|
||||
and ``mysetup.app()`` returned an initialized ``MyApp`` instance.
|
||||
|
@ -122,14 +123,15 @@ Running it yields::
|
|||
|
||||
$ py.test test_ssh.py -rs
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_ssh.py s
|
||||
========================= short test summary info ==========================
|
||||
SKIP [1] /tmp/doc-exec-220/conftest.py:22: specify ssh host with --ssh
|
||||
SKIP [1] /home/hpk/tmp/doc-exec-306/conftest.py:22: specify ssh host with --ssh
|
||||
|
||||
======================== 1 skipped in 0.01 seconds =========================
|
||||
======================== 1 skipped in 0.02 seconds =========================
|
||||
|
||||
If you specify a command line option like ``py.test --ssh=python.org`` the test will execute as expected.
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@ now execute the test specification::
|
|||
|
||||
nonpython $ py.test test_simple.yml
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_simple.yml .F
|
||||
|
@ -37,7 +38,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.11 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 +57,9 @@ consulted when reporting in ``verbose`` mode::
|
|||
|
||||
nonpython $ py.test -v
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4 -- /home/hpk/venv/0/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2 -- /home/hpk/venv/1/bin/python
|
||||
cachedir: /home/hpk/p/pytest/doc/en/.cache
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_simple.yml:1: usecase: ok PASSED
|
||||
|
@ -67,17 +70,18 @@ consulted when 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.04 seconds ====================
|
||||
|
||||
While developing your custom test collection and execution it's also
|
||||
interesting to just look at the collection tree::
|
||||
|
||||
nonpython $ py.test --collectonly
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 2 items
|
||||
<YamlFile 'test_simple.yml'>
|
||||
<YamlItem 'ok'>
|
||||
<YamlItem 'hello'>
|
||||
|
||||
============================= in 0.07 seconds =============================
|
||||
============================= in 0.04 seconds =============================
|
||||
|
|
|
@ -2,38 +2,65 @@
|
|||
V2: Creating and working with parametrized test resources
|
||||
===============================================================
|
||||
|
||||
# XXX collection versus setup-time
|
||||
# XXX parametrize-relation?
|
||||
pytest-2.X provides generalized resource parametrization, unifying
|
||||
and extending all existing funcarg and parametrization features of
|
||||
previous pytest versions. Existing test suites and plugins written
|
||||
for previous pytest versions shall run unmodified.
|
||||
|
||||
pytest-2.3 provides generalized resource management allowing
|
||||
to flexibly manage caching and parametrization across your test suite.
|
||||
This V2 draft focuses on incorporating feedback provided by Floris Bruynooghe,
|
||||
Carl Meyer and Ronny Pfannschmidt. It remains as draft documentation, pending
|
||||
further refinements and changes according to implementation or backward
|
||||
compatibility issues. The main changes to V1 are:
|
||||
|
||||
This is draft documentation, pending refinements and changes according
|
||||
to feedback and to implementation or backward compatibility issues
|
||||
(the new mechanism is supposed to allow fully backward compatible
|
||||
operations for uses of the "funcarg" mechanism.
|
||||
* changed API names (atnode -> scopenode)
|
||||
* register_factory now happens at Node.collect_init() or pytest_collection_init
|
||||
time. It will raise an Error if called during the runtestloop
|
||||
(which performs setup/call/teardown for each collected test).
|
||||
* new examples and notes related to @parametrize and metafunc.parametrize()
|
||||
* use 2.X as the version for introduction - not sure if 2.3 or 2.4 will
|
||||
actually bring it.
|
||||
* examples/uses which were previously not possible to implement easily
|
||||
are marked with "NEW" in the title.
|
||||
|
||||
the new global pytest_runtest_init hook
|
||||
(NEW) the init_collection and init_runtestloop hooks
|
||||
------------------------------------------------------
|
||||
|
||||
Prior to 2.3, pytest offered a pytest_configure and a pytest_sessionstart
|
||||
hook which was used often to setup global resources. This suffers from
|
||||
several problems. First of all, in distributed testing the master would
|
||||
also setup test resources that are never needed because it only co-ordinates
|
||||
the test run activities of the slave processes. Secondly, in large test
|
||||
suites resources are setup that might not be needed for the concrete test
|
||||
run. The first issue is solved through the introduction of a specific
|
||||
hook::
|
||||
pytest for a long time offers a pytest_configure and a pytest_sessionstart
|
||||
hook which are often used to setup global resources. This suffers from
|
||||
several problems:
|
||||
|
||||
def pytest_runtest_init(session):
|
||||
# called ahead of pytest_runtestloop() test execution
|
||||
1. in distributed testing the master process would setup test resources
|
||||
that are never needed because it only co-ordinates the test run
|
||||
activities of the slave processes.
|
||||
|
||||
This hook will only be called in processes that actually run tests.
|
||||
2. In large test suites resources are created which might not be needed
|
||||
for the concrete test run.
|
||||
|
||||
The second issue is solved through a new register/getresource API which
|
||||
will only ever setup resources if they are needed. See the following
|
||||
examples and sections on how this works.
|
||||
3. Thirdly, even if you only perform a collection (with "--collectonly")
|
||||
resource-setup will be executed.
|
||||
|
||||
4. there is no place way to allow global parametrized collection and setup
|
||||
|
||||
The existing hooks are not a good place regarding these issues. pytest-2.X
|
||||
solves all these issues through the introduction of two specific hooks
|
||||
(and the new register_factory/getresource API)::
|
||||
|
||||
def pytest_init_collection(session):
|
||||
# called ahead of pytest_collection, which implements the
|
||||
# collection process
|
||||
|
||||
def pytest_init_runtestloop(session):
|
||||
# called ahead of pytest_runtestloop() which executes the
|
||||
# setup and calling of tests
|
||||
|
||||
The pytest_init_collection hook can be used for registering resources,
|
||||
see `global resource management`_ and `parametrizing global resources`_.
|
||||
|
||||
The init_runtests can be used to setup and/or interact with global
|
||||
resources. If you just use a global resource, you may explicitely
|
||||
use it in a function argument or through a `class resource attribute`_.
|
||||
|
||||
.. _`global resource management`:
|
||||
|
||||
managing a global database resource
|
||||
---------------------------------------------------------------
|
||||
|
@ -41,6 +68,8 @@ managing a global database resource
|
|||
If you have one database object which you want to use in tests
|
||||
you can write the following into a conftest.py file::
|
||||
|
||||
# contest of conftest.py
|
||||
|
||||
class Database:
|
||||
def __init__(self):
|
||||
print ("database instance created")
|
||||
|
@ -52,51 +81,71 @@ you can write the following into a conftest.py file::
|
|||
node.addfinalizer(db.destroy)
|
||||
return db
|
||||
|
||||
def pytest_runtest_init(session):
|
||||
session.register_resource("db", factory_db, atnode=session)
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db", factory_db)
|
||||
|
||||
You can then access the constructed resource in a test like this::
|
||||
You can then access the constructed resource in a test by specifying
|
||||
the pre-registered name in your function definition::
|
||||
|
||||
def test_something(db):
|
||||
...
|
||||
|
||||
The "db" function argument will lead to a lookup of the respective
|
||||
factory value and be passed to the function body. According to the
|
||||
registration, the db object will be instantiated on a per-session basis
|
||||
and thus reused across all test functions that require it.
|
||||
The "db" function argument will lead to a lookup and call of the respective
|
||||
factory function and its result will be passed to the function body.
|
||||
As the factory is registered on the session, it will by default only
|
||||
get called once per session and its value will thus be re-used across
|
||||
the whole test session.
|
||||
|
||||
instantiating a database resource per-module
|
||||
Previously, factories would need to call the ``request.cached_setup()``
|
||||
method to manage caching. Here is how we could implement the above
|
||||
with traditional funcargs::
|
||||
|
||||
# content of conftest.py
|
||||
class DataBase:
|
||||
... as above
|
||||
|
||||
def pytest_funcarg__db(request):
|
||||
return request.cached_setup(setup=DataBase,
|
||||
teardown=lambda db: db.destroy,
|
||||
scope="session")
|
||||
|
||||
As the funcarg factory is automatically registered by detecting its
|
||||
name and because it is called each time "db" is requested, it needs
|
||||
to care for caching itself, here by calling the cached_setup() method
|
||||
to manage it. As it encodes the caching scope in the factory code body,
|
||||
py.test has no way to report this via e. g. "py.test --funcargs".
|
||||
More seriously, it's not exactly trivial to provide parametrization:
|
||||
we would need to add a "parametrize" decorator where the resource is
|
||||
used or implement a pytest_generate_tests(metafunc) hook to
|
||||
call metafunc.parametrize() with the "db" argument, and then the
|
||||
factory would need to care to pass the appropriate "extrakey" into
|
||||
cached_setup(). By contrast, the new way just requires a modified
|
||||
call to register factories::
|
||||
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db", [factory_mysql, factory_pg])
|
||||
|
||||
and no other code needs to change or get decorated.
|
||||
|
||||
(NEW) instantiating one database for each test module
|
||||
---------------------------------------------------------------
|
||||
|
||||
If you want one database instance per test module you can restrict
|
||||
caching by modifying the "atnode" parameter of the registration
|
||||
call above::
|
||||
caching by modifying the "scopenode" parameter of the registration
|
||||
call above:
|
||||
|
||||
def pytest_runtest_init(session):
|
||||
session.register_resource("db", factory_db, atnode=pytest.Module)
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db", factory_db, scopenode=pytest.Module)
|
||||
|
||||
Neither the tests nor the factory function will need to change.
|
||||
This also means that you can decide the scoping of resources
|
||||
at runtime - e.g. based on a command line option: for developer
|
||||
settings you might want per-session and for Continous Integration
|
||||
runs you might prefer per-module or even per-function scope like this::
|
||||
|
||||
def pytest_runtest_init(session):
|
||||
session.register_resource_factory("db", factory_db,
|
||||
atnode=pytest.Function)
|
||||
|
||||
parametrized resources
|
||||
----------------------------------
|
||||
|
||||
If you want to rerun tests with different resource values you can specify
|
||||
a list of factories instead of just one::
|
||||
|
||||
def pytest_runtest_init(session):
|
||||
session.register_factory("db", [factory1, factory2], atnode=session)
|
||||
|
||||
In this case all tests that depend on the "db" resource will be run twice
|
||||
using the respective values obtained from the two factory functions.
|
||||
This means that you can decide the scoping of resources at runtime -
|
||||
e.g. based on a command line option: for developer settings you might
|
||||
want per-session and for Continous Integration runs you might prefer
|
||||
per-module or even per-function scope like this::
|
||||
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db", factory_db,
|
||||
scopenode=pytest.Function)
|
||||
|
||||
Using a resource from another resource factory
|
||||
----------------------------------------------
|
||||
|
@ -105,9 +154,11 @@ You can use the database resource from a another resource factory through
|
|||
the ``node.getresource()`` method. Let's add a resource factory for
|
||||
a "db_users" table at module-level, extending the previous db-example::
|
||||
|
||||
def pytest_runtest_init(session):
|
||||
def pytest_init_collection(session):
|
||||
...
|
||||
session.register_factory("db_users", createusers, atnode=module)
|
||||
# this factory will be using a scopenode=pytest.Module because
|
||||
# it is defined in a test module.
|
||||
session.register_factory("db_users", createusers)
|
||||
|
||||
def createusers(name, node):
|
||||
db = node.getresource("db")
|
||||
|
@ -125,43 +176,194 @@ is not available at a more general scope. Concretely, if you
|
|||
table is defined as a per-session resource and the database object as a
|
||||
per-module one, the table creation cannot work on a per-session basis.
|
||||
|
||||
amending/decorating a resource / funcarg__ compatibility
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Setting resources as class attributes
|
||||
If you want to decorate a session-registered resource with
|
||||
a test-module one, you can do the following::
|
||||
|
||||
# content of conftest.py
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db_users", createusers)
|
||||
|
||||
This will register a db_users method on a per-session basis.
|
||||
If you want to create a dummy user such that all test
|
||||
methods in a test module can work with it::
|
||||
|
||||
# content of test_user_admin.py
|
||||
def setup_class(cls, db_users):
|
||||
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db_users", createcreate_users,
|
||||
scopenode=pytest.Module)
|
||||
|
||||
def create_users(name, node):
|
||||
# get the session-managed resource
|
||||
db_users = node.getresource(name)
|
||||
# add a user and define a remove_user undo function
|
||||
...
|
||||
node.addfinalizer(remove_user)
|
||||
return db_users
|
||||
|
||||
def test_user_fields(db_users):
|
||||
# work with db_users with a pre-created entry
|
||||
...
|
||||
|
||||
Using the pytest_funcarg__ mechanism, you can do the equivalent::
|
||||
|
||||
# content of test_user_admin.py
|
||||
|
||||
def pytest_funcarg__db_users(request):
|
||||
def create_user():
|
||||
db_users = request.getfuncargvalue("db_users")
|
||||
# add a user
|
||||
return db_users
|
||||
def remove_user(db_users):
|
||||
...
|
||||
return request.cached_setup(create_user, remove_user, scope="module")
|
||||
|
||||
As the funcarg mechanism is implemented in terms of the new API
|
||||
it's also possible to mix - use register_factory/getresource at plugin-level
|
||||
and pytest_funcarg__ factories at test module level.
|
||||
|
||||
As discussed previously with `global resource management`_, the funcarg-factory
|
||||
does not easily extend to provide parametrization.
|
||||
|
||||
|
||||
.. _`class resource attributes`:
|
||||
|
||||
(NEW) Setting resources as class attributes
|
||||
-------------------------------------------
|
||||
|
||||
If you want to make an attribute available on a test class, you can
|
||||
use the resource_attr marker::
|
||||
use a new mark::
|
||||
|
||||
@pytest.mark.resource_attr("db")
|
||||
@pytest.mark.class_resource("db")
|
||||
class TestClass:
|
||||
def test_something(self):
|
||||
#use self.db
|
||||
|
||||
Note that this way of using resources can be used on unittest.TestCase
|
||||
instances as well (function arguments can not be added due to unittest
|
||||
limitations).
|
||||
Note that this way of using resources work with unittest.TestCase-style
|
||||
tests as well. If you have defined "db" as a parametrized resource,
|
||||
the functions of the Test class will be run multiple times with different
|
||||
values found in "self.db".
|
||||
|
||||
Previously, pytest could not offer its resource management features
|
||||
since those were tied to passing function arguments ("funcargs") and
|
||||
this cannot be easily integrated with the unittest framework and its
|
||||
common per-project customizations.
|
||||
|
||||
|
||||
How the funcarg mechanism is implemented (internal notes)
|
||||
.. _`parametrizing global resources`:
|
||||
|
||||
(NEW) parametrizing global resources
|
||||
----------------------------------------------------
|
||||
|
||||
If you want to rerun tests with different resource values you can specify
|
||||
a list of factories instead of just one::
|
||||
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db", [factory1, factory2])
|
||||
|
||||
In this case all tests that require the "db" resource will be run twice
|
||||
using the respective values obtained from the two factory functions.
|
||||
|
||||
For reporting purposes you might want to also define identifiers
|
||||
for the db values::
|
||||
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("db", [factory1, factory2],
|
||||
ids=["mysql", "pg"])
|
||||
|
||||
This will make pytest use the respective id values when reporting
|
||||
nodeids.
|
||||
|
||||
|
||||
(New) Declaring resource usage / implicit parametrization
|
||||
----------------------------------------------------------
|
||||
|
||||
Sometimes you may have a resource that can work in multiple variants,
|
||||
like using different database backends. As another use-case,
|
||||
pytest's own test suite uses a "testdir" funcarg which helps to setup
|
||||
example scenarios, perform a subprocess-pytest run and check the output.
|
||||
However, there are many features that should also work with the pytest-xdist
|
||||
mode, distributing tests to multiple CPUs or hosts. The invocation
|
||||
variants are not visible in the function signature and cannot be easily
|
||||
addressed through a "parametrize" decorator or call. Nevertheless we want
|
||||
to have both invocation variants to be collected and executed.
|
||||
|
||||
The solution is to tell pytest that you are using a resource implicitely::
|
||||
|
||||
@pytest.mark.uses_resource("invocation-option")
|
||||
class TestClass:
|
||||
def test_method(self, testdir):
|
||||
...
|
||||
|
||||
When the testdir factory gets the parametrized "invocation-option"
|
||||
resource, it will see different values, depending on what the respective
|
||||
factories provide. To register the invocation-mode factory you would write::
|
||||
|
||||
# content of conftest.py
|
||||
def pytest_init_collection(session):
|
||||
session.register_factory("invocation-option",
|
||||
[lambda **kw: "", lambda **kw: "-n1"])
|
||||
|
||||
The testdir factory can then access it easily::
|
||||
|
||||
option = node.getresource("invocation-option", "")
|
||||
...
|
||||
|
||||
.. note::
|
||||
|
||||
apart from the "uses_resource" decoration none of the already
|
||||
written test functions needs to be modified for the new API.
|
||||
|
||||
The implicit "testdir" parametrization only happens for the tests
|
||||
which declare use of the invocation-option resource. All other
|
||||
tests will get the default value passed as the second parameter
|
||||
to node.getresource() above. You can thus restrict
|
||||
running the variants to particular tests or test sets.
|
||||
|
||||
To conclude, these three code fragments work together to allow efficient
|
||||
cross-session resource parametrization.
|
||||
|
||||
|
||||
Implementation and compatibility notes
|
||||
============================================================
|
||||
|
||||
The new API is designed to support all existing resource parametrization
|
||||
and funcarg usages. This chapter discusses implementation aspects.
|
||||
Feel free to choose ignorance and only consider the above usage-level.
|
||||
|
||||
Implementing the funcarg mechanism in terms of the new API
|
||||
-------------------------------------------------------------
|
||||
|
||||
Prior to pytest-2.3/4, pytest advertised the "funcarg" mechanism
|
||||
which provided a subset functionality to the generalized resource management.
|
||||
In fact, the previous mechanism is implemented in terms of the new API
|
||||
and should continue to work unmodified. It basically automates the
|
||||
registration of factories through automatic discovery of
|
||||
``pytest_funcarg_NAME`` function on plugins, Python modules and classes.
|
||||
Prior to pytest-2.X, pytest mainly advertised the "funcarg" mechanism
|
||||
for resource management. It provides automatic registration of
|
||||
factories through discovery of ``pytest_funcarg__NAME`` factory methods
|
||||
on plugins, test modules, classes and functions. Those factories are be
|
||||
called *each time* a resource (funcarg) is required, hence the support
|
||||
for a ``request.cached_setup" method which helps to cache resources
|
||||
across calls. Request objects internally keep a (item, requested_name,
|
||||
remaining-factories) state. The "reamaining-factories" state is
|
||||
used for implementing decorating factories; a factory for a given
|
||||
name can call ``getfuncargvalue(name)`` to invoke the next-matching
|
||||
factory factories and then amend the return value.
|
||||
|
||||
As an example let's consider the Module.setup() method::
|
||||
In order to implement the existing funcarg mechanism through
|
||||
the new API, the new API needs to internally keep around similar
|
||||
state. XXX
|
||||
|
||||
As an example let's consider the Module.setup_collect() method::
|
||||
|
||||
class Module(PyCollector):
|
||||
def setup(self):
|
||||
def setup_collect(self):
|
||||
for name, func in self.obj.__dict__.items():
|
||||
if name.startswith("pytest_funcarg__"):
|
||||
resourcename = name[len("pytest_funcarg__"):]
|
||||
self._register_factory(resourcename,
|
||||
RequestAdapter(self, name, func))
|
||||
self.register_factory(resourcename,
|
||||
RequestAdapter(self, name, func))
|
||||
|
||||
The request adapater takes care to provide the pre-2.3 API for funcarg
|
||||
factories, providing request.cached_setup/addfinalizer/getfuncargvalue
|
||||
methods.
|
||||
The request adapater takes care to provide the pre-2.X API for funcarg
|
||||
factories, i.e. request.cached_setup/addfinalizer/getfuncargvalue
|
||||
methods and some attributes.
|
||||
|
|
|
@ -61,7 +61,8 @@ factory. Running the test looks like this::
|
|||
|
||||
$ py.test test_simplefactory.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_simplefactory.py F
|
||||
|
@ -76,7 +77,7 @@ factory. Running the test looks like this::
|
|||
E assert 42 == 17
|
||||
|
||||
test_simplefactory.py:5: AssertionError
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
========================= 1 failed in 0.02 seconds =========================
|
||||
|
||||
This shows that the test function was called with a ``myfuncarg``
|
||||
argument value of ``42`` and the assert fails as expected. Here is
|
||||
|
@ -154,7 +155,8 @@ Running this will generate ten invocations of ``test_func`` passing in each of t
|
|||
|
||||
$ py.test test_example.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 10 items
|
||||
|
||||
test_example.py .........F
|
||||
|
@ -169,7 +171,7 @@ Running this will generate ten invocations of ``test_func`` passing in each of t
|
|||
E assert 9 < 9
|
||||
|
||||
test_example.py:6: AssertionError
|
||||
==================== 1 failed, 9 passed in 0.02 seconds ====================
|
||||
==================== 1 failed, 9 passed in 0.03 seconds ====================
|
||||
|
||||
Obviously, only when ``numiter`` has the value of ``9`` does the test fail. Note that the ``pytest_generate_tests(metafunc)`` hook is called during
|
||||
the test collection phase which is separate from the actual test running.
|
||||
|
@ -177,7 +179,8 @@ Let's just look at what is collected::
|
|||
|
||||
$ py.test --collectonly test_example.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 10 items
|
||||
<Module 'test_example.py'>
|
||||
<Function 'test_func[0]'>
|
||||
|
@ -191,19 +194,39 @@ Let's just look at what is collected::
|
|||
<Function 'test_func[8]'>
|
||||
<Function 'test_func[9]'>
|
||||
|
||||
============================= in 0.00 seconds =============================
|
||||
============================= in 0.02 seconds =============================
|
||||
|
||||
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.7.1 -- pytest-2.2.4 -- /home/hpk/venv/0/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2 -- /home/hpk/venv/1/bin/python
|
||||
cachedir: /home/hpk/tmp/doc-exec-271/.cache
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 10 items
|
||||
|
||||
test_example.py:5: test_func[0] PASSED
|
||||
test_example.py:5: test_func[1] PASSED
|
||||
test_example.py:5: test_func[2] PASSED
|
||||
test_example.py:5: test_func[3] PASSED
|
||||
test_example.py:5: test_func[4] PASSED
|
||||
test_example.py:5: test_func[5] PASSED
|
||||
test_example.py:5: test_func[6] PASSED
|
||||
test_example.py:5: test_func[7] PASSED
|
||||
test_example.py:5: test_func[8] PASSED
|
||||
test_example.py:5: test_func[9] FAILED
|
||||
|
||||
======================= 9 tests deselected by '-k7' ========================
|
||||
================== 1 passed, 9 deselected in 0.01 seconds ==================
|
||||
================================= FAILURES =================================
|
||||
_______________________________ test_func[9] _______________________________
|
||||
|
||||
numiter = 9
|
||||
|
||||
def test_func(numiter):
|
||||
> assert numiter < 9
|
||||
E assert 9 < 9
|
||||
|
||||
test_example.py:6: AssertionError
|
||||
==================== 1 failed, 9 passed in 0.03 seconds ====================
|
||||
|
||||
You might want to look at :ref:`more parametrization examples <paramexamples>`.
|
||||
|
||||
|
|
|
@ -22,9 +22,14 @@ Installation options::
|
|||
To check your installation has installed the correct version::
|
||||
|
||||
$ py.test --version
|
||||
This is py.test version 2.2.4, imported from /home/hpk/p/pytest/pytest.py
|
||||
This is py.test version 2.3.0.dev2, imported from /home/hpk/p/pytest/pytest.pyc
|
||||
setuptools registered plugins:
|
||||
pytest-xdist-1.8 at /home/hpk/p/pytest-xdist/xdist/plugin.pyc
|
||||
pytest-bugzilla-0.1 at /home/hpk/tmp/eanxgeek/pytest_bugzilla.pyc
|
||||
pytest-cache-0.9 at /home/hpk/p/pytest-cache/pytest_cache.pyc
|
||||
oejskit-0.9.0 at /home/hpk/p/js-infrastructure/oejskit/pytest_jstests.pyc
|
||||
pytest-pep8-1.0.1 at /home/hpk/venv/1/local/lib/python2.7/site-packages/pytest_pep8.pyc
|
||||
pytest-cov-1.6 at /home/hpk/venv/1/local/lib/python2.7/site-packages/pytest_cov.pyc
|
||||
|
||||
If you get an error checkout :ref:`installation issues`.
|
||||
|
||||
|
@ -46,7 +51,8 @@ That's it. You can execute the test function now::
|
|||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_sample.py F
|
||||
|
@ -60,7 +66,7 @@ That's it. You can execute the test function now::
|
|||
E + where 4 = func(3)
|
||||
|
||||
test_sample.py:5: AssertionError
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
========================= 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``.
|
||||
|
||||
|
@ -95,7 +101,7 @@ Running it with, this time in "quiet" reporting mode::
|
|||
$ py.test -q test_sysexit.py
|
||||
collecting ... collected 1 items
|
||||
.
|
||||
1 passed in 0.00 seconds
|
||||
1 passed in 0.02 seconds
|
||||
|
||||
.. todo:: For further ways to assert exceptions see the `raises`
|
||||
|
||||
|
@ -126,7 +132,7 @@ run the module by passing its filename::
|
|||
================================= FAILURES =================================
|
||||
____________________________ TestClass.test_two ____________________________
|
||||
|
||||
self = <test_class.TestClass instance at 0x1a956c8>
|
||||
self = <test_class.TestClass instance at 0x2343830>
|
||||
|
||||
def test_two(self):
|
||||
x = "hello"
|
||||
|
@ -134,7 +140,7 @@ run the module by passing its filename::
|
|||
E assert hasattr('hello', 'check')
|
||||
|
||||
test_class.py:8: AssertionError
|
||||
1 failed, 1 passed in 0.01 seconds
|
||||
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
|
||||
|
@ -163,7 +169,7 @@ before performing the test function call. Let's just run it::
|
|||
================================= FAILURES =================================
|
||||
_____________________________ test_needsfiles ______________________________
|
||||
|
||||
tmpdir = local('/tmp/pytest-22/test_needsfiles0')
|
||||
tmpdir = local('/home/hpk/tmp/pytest-2885/test_needsfiles0')
|
||||
|
||||
def test_needsfiles(tmpdir):
|
||||
print tmpdir
|
||||
|
@ -172,8 +178,8 @@ before performing the test function call. Let's just run it::
|
|||
|
||||
test_tmpdir.py:3: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
/tmp/pytest-22/test_needsfiles0
|
||||
1 failed in 0.01 seconds
|
||||
/home/hpk/tmp/pytest-2885/test_needsfiles0
|
||||
1 failed in 0.22 seconds
|
||||
|
||||
Before the test runs, a unique-per-test-invocation temporary directory
|
||||
was created. More info at :ref:`tmpdir handling`.
|
||||
|
|
|
@ -37,7 +37,7 @@ Welcome to pytest!
|
|||
|
||||
- **integrates many common testing methods**
|
||||
|
||||
- can integrate ``nose``, ``unittest.py`` and ``doctest.py`` style
|
||||
- can run many ``nose``, ``unittest.py`` and ``doctest.py`` style
|
||||
tests, including running testcases made for Django and trial
|
||||
- supports extended :ref:`xUnit style setup <xunitsetup>`
|
||||
- supports domain-specific :ref:`non-python tests`
|
||||
|
|
|
@ -130,7 +130,8 @@ 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.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 6 items
|
||||
|
||||
xfail_demo.py xxxxxx
|
||||
|
@ -147,7 +148,7 @@ Running it with the report-on-xfail option gives this output::
|
|||
XFAIL xfail_demo.py::test_hello6
|
||||
reason: reason
|
||||
|
||||
======================== 6 xfailed in 0.03 seconds =========================
|
||||
======================== 6 xfailed in 0.04 seconds =========================
|
||||
|
||||
.. _`evaluation of skipif/xfail conditions`:
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ Running this would result in a passed test except for the last
|
|||
|
||||
$ py.test test_tmpdir.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_tmpdir.py F
|
||||
|
@ -36,7 +37,7 @@ Running this would result in a passed test except for the last
|
|||
================================= FAILURES =================================
|
||||
_____________________________ test_create_file _____________________________
|
||||
|
||||
tmpdir = local('/tmp/pytest-23/test_create_file0')
|
||||
tmpdir = local('/home/hpk/tmp/pytest-2886/test_create_file0')
|
||||
|
||||
def test_create_file(tmpdir):
|
||||
p = tmpdir.mkdir("sub").join("hello.txt")
|
||||
|
@ -47,7 +48,7 @@ Running this would result in a passed test except for the last
|
|||
E assert 0
|
||||
|
||||
test_tmpdir.py:7: AssertionError
|
||||
========================= 1 failed in 0.02 seconds =========================
|
||||
========================= 1 failed in 0.23 seconds =========================
|
||||
|
||||
.. _`base temporary directory`:
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ Running it yields::
|
|||
|
||||
$ py.test test_unittest.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.1 -- pytest-2.2.4
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
||||
collecting ... collected 1 items
|
||||
|
||||
test_unittest.py F
|
||||
|
@ -42,7 +43,7 @@ Running it yields::
|
|||
test_unittest.py:8: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
hello
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
========================= 1 failed in 0.03 seconds =========================
|
||||
|
||||
.. _`unittest.py style`: http://docs.python.org/library/unittest.html
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ hook was invoked::
|
|||
$ python myinvoke.py
|
||||
collecting ... collected 0 items
|
||||
|
||||
in 0.00 seconds
|
||||
in 0.01 seconds
|
||||
*** test run reporting finishing
|
||||
|
||||
.. include:: links.inc
|
||||
|
|
Loading…
Reference in New Issue