refine docs and docstrings, fix some small bits here and there while doing that.
This commit is contained in:
parent
a698465487
commit
582486d531
|
@ -64,12 +64,16 @@ class DoctestItem(pytest.Item):
|
|||
|
||||
class DoctestTextfile(DoctestItem, pytest.File):
|
||||
def runtest(self):
|
||||
failed, tot = py.std.doctest.testfile(
|
||||
doctest = py.std.doctest
|
||||
failed, tot = doctest.testfile(
|
||||
str(self.fspath), module_relative=False,
|
||||
optionflags=doctest.ELLIPSIS,
|
||||
raise_on_error=True, verbose=0)
|
||||
|
||||
class DoctestModule(DoctestItem, pytest.File):
|
||||
def runtest(self):
|
||||
doctest = py.std.doctest
|
||||
module = self.fspath.pyimport()
|
||||
failed, tot = py.std.doctest.testmod(
|
||||
module, raise_on_error=True, verbose=0)
|
||||
failed, tot = doctest.testmod(
|
||||
module, raise_on_error=True, verbose=0,
|
||||
optionflags=doctest.ELLIPSIS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""run test suites written for nose. """
|
||||
""" run test suites written for nose. """
|
||||
|
||||
import pytest, py
|
||||
import inspect
|
||||
|
|
|
@ -762,19 +762,28 @@ def raises(ExpectedException, *args, **kwargs):
|
|||
If using Python 2.5 or above, you may use this function as a
|
||||
context manager::
|
||||
|
||||
>>> with raises(ZeroDivisionError):
|
||||
... 1/0
|
||||
>>> with raises(ZeroDivisionError):
|
||||
... 1/0
|
||||
|
||||
Or you can one of two forms:
|
||||
Or you can specify a callable by passing a to-be-called lambda::
|
||||
|
||||
if args[0] is callable: raise AssertionError if calling it with
|
||||
the remaining arguments does not raise the expected exception.
|
||||
if args[0] is a string: raise AssertionError if executing the
|
||||
the string in the calling scope does not raise expected exception.
|
||||
examples:
|
||||
>>> x = 5
|
||||
>>> raises(TypeError, lambda x: x + 'hello', x=x)
|
||||
>>> raises(TypeError, "x + 'hello'")
|
||||
>>> raises(ZeroDivisionError, lambda: 1/0)
|
||||
<ExceptionInfo ...>
|
||||
|
||||
or you can specify an arbitrary callable with arguments::
|
||||
|
||||
>>> def f(x): return 1/x
|
||||
...
|
||||
>>> raises(ZeroDivisionError, f, 0)
|
||||
<ExceptionInfo ...>
|
||||
>>> raises(ZeroDivisionError, f, x=0)
|
||||
<ExceptionInfo ...>
|
||||
|
||||
A third possibility is to use a string which which will
|
||||
be executed::
|
||||
|
||||
>>> raises(ZeroDivisionError, "f(0)")
|
||||
<ExceptionInfo ...>
|
||||
"""
|
||||
__tracebackhide__ = True
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ def pytest_namespace():
|
|||
return {'deprecated_call': deprecated_call}
|
||||
|
||||
def deprecated_call(func, *args, **kwargs):
|
||||
""" assert that calling func(*args, **kwargs)
|
||||
triggers a DeprecationWarning.
|
||||
""" assert that calling ``func(*args, **kwargs)``
|
||||
triggers a DeprecationWarning.
|
||||
"""
|
||||
warningmodule = py.std.warnings
|
||||
l = []
|
||||
|
|
|
@ -408,7 +408,8 @@ class Session(FSCollector):
|
|||
path = names.pop(0)
|
||||
if path.check(dir=1):
|
||||
assert not names, "invalid arg %r" %(arg,)
|
||||
for path in path.visit(rec=self._recurse, bf=True, sort=True):
|
||||
for path in path.visit(fil=lambda x: x.check(file=1),
|
||||
rec=self._recurse, bf=True, sort=True):
|
||||
for x in self._collectfile(path):
|
||||
yield x
|
||||
else:
|
||||
|
@ -424,12 +425,13 @@ class Session(FSCollector):
|
|||
return ihook.pytest_collect_file(path=path, parent=self)
|
||||
|
||||
def _recurse(self, path):
|
||||
ihook = self.gethookproxy(path)
|
||||
ihook = self.gethookproxy(path.dirpath())
|
||||
if ihook.pytest_ignore_collect(path=path, config=self.config):
|
||||
return
|
||||
for pat in self._norecursepatterns:
|
||||
if path.check(fnmatch=pat):
|
||||
return False
|
||||
ihook = self.gethookproxy(path)
|
||||
ihook.pytest_collect_directory(path=path, parent=self)
|
||||
return True
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ and "pytest.raises" used as the recommended default way.
|
|||
- py.test.config is now only available if you are in a test run.
|
||||
|
||||
- the following (mostly already deprecated) functionality was removed:
|
||||
|
||||
- removed support for Module/Class/... collection node definitions
|
||||
in conftest.py files. They will cause nothing special.
|
||||
- removed support for calling the pre-1.0 collection API of "run()" and "join"
|
||||
|
|
|
@ -15,6 +15,7 @@ py.test reference documentation
|
|||
xunit_setup.txt
|
||||
capture.txt
|
||||
monkeypatch.txt
|
||||
xdist.txt
|
||||
tmpdir.txt
|
||||
skipping.txt
|
||||
mark.txt
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
|
||||
.. _`pytest helpers`:
|
||||
|
||||
pytest builtin helpers
|
||||
================================================
|
||||
|
||||
builtin pytest.* helpers
|
||||
builtin pytest.* functions and helping objects
|
||||
-----------------------------------------------------
|
||||
|
||||
You can always use an interactive Python prompt and type::
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
Looping on the failing test set
|
||||
-----------------------------------------
|
||||
|
||||
``py.test --looponfailing`` (implemented through the external
|
||||
`pytest-xdist`_ plugin) allows to run a test suite,
|
||||
memorize all failures and then loop over the failing set
|
||||
of tests until they all pass. It will re-start running
|
||||
the tests when it detects file changes in your project.
|
||||
|
||||
select tests by keyword / test name search
|
||||
-----------------------------------------------------
|
||||
|
||||
.. _`selection by keyword`:
|
||||
|
||||
You can selectively run tests by specifiying a keyword
|
||||
on the command line. Examples::
|
||||
|
||||
py.test -k test_simple
|
||||
py.test -k "-test_simple"
|
||||
|
||||
will run all tests matching (or not matching) the
|
||||
"test_simple" keyword. Note that you need to quote
|
||||
the keyword if "-" is recognized as an indicator
|
||||
for a commandline option. Lastly, you may use::
|
||||
|
||||
py.test. -k "test_simple:"
|
||||
|
||||
which will run all tests after the expression has *matched once*, i.e.
|
||||
all tests that are seen after a test that matches the "test_simple"
|
||||
keyword.
|
||||
|
||||
By default, all filename parts and
|
||||
class/function names of a test function are put into the set
|
||||
of keywords for a given test. You can specify additional
|
||||
kewords like this:
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
@py.test.mark.webtest
|
||||
def test_send_http():
|
||||
...
|
||||
|
||||
and then use those keywords to select tests. See the `pytest_keyword`_
|
||||
plugin for more information.
|
||||
|
||||
.. _`pytest_keyword`: plugin/mark.html
|
||||
skip or expect-to-fail a test
|
||||
-------------------------------------------
|
||||
|
||||
py.test has a dedicated `skipping plugin`_ that allows to define
|
||||
|
||||
* define "skip" outcomes indicating a platform or a
|
||||
dependency mismatch.
|
||||
|
||||
* "xfail" outcomes indicating an "expected failure" either with
|
||||
with or without running a test.
|
||||
|
||||
* skip and xfail outcomes can be applied at module, class or method
|
||||
level or even only for certain argument sets of a parametrized function.
|
||||
|
||||
.. _`skipping plugin`: plugin/skipping.html
|
||||
.. _`funcargs mechanism`: funcargs.html
|
||||
.. _`doctest.py`: http://docs.python.org/library/doctest.html
|
||||
.. _`xUnit style setup`: xunit_setup.html
|
||||
.. _`pytest_nose`: plugin/nose.html
|
||||
|
||||
|
||||
no-boilerplate testing
|
||||
----------------------------------
|
||||
|
||||
.. _`autocollect`:
|
||||
|
||||
automatic Python test discovery
|
||||
+++++++++++++++++++++++++++++++++++
|
||||
|
||||
By default, all python modules with a ``test_*.py``
|
||||
filename are inspected for finding tests:
|
||||
|
||||
* functions with a name beginning with ``test_``
|
||||
* classes with a leading ``Test`` name and ``test`` prefixed methods.
|
||||
* ``unittest.TestCase`` subclasses
|
||||
|
||||
parametrizing test functions and functional testing
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
py.test offers the unique `funcargs mechanism`_ for setting up
|
||||
and passing project-specific objects to Python test functions.
|
||||
Test Parametrization happens by triggering a call to the same test
|
||||
function with different argument values. For doing fixtures
|
||||
using the funcarg mechanism makes your test and setup code
|
||||
more efficient and more readable. This is especially true
|
||||
for functional tests which might depend on command line
|
||||
options and a setup that needs to be shared across
|
||||
a whole test run.
|
||||
|
||||
per-test capturing of output, including subprocesses
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
By default, ``py.test`` captures all writes to stdout/stderr.
|
||||
Output from ``print`` statements as well as from subprocesses
|
||||
is captured_. When a test fails, the associated captured outputs are shown.
|
||||
This allows you to put debugging print statements in your code without
|
||||
being overwhelmed by all the output that might be generated by tests
|
||||
that do not fail.
|
||||
|
||||
.. _captured: plugin/capture.html
|
||||
|
||||
|
||||
information-rich tracebacks, PDB introspection
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
.. _`example tracebacks`: http://paste.pocoo.org/show/134814/
|
||||
|
||||
A lot of care is taken to present useful failure information
|
||||
and in particular nice and concise Python tracebacks. This
|
||||
is especially useful if you need to regularly look at failures
|
||||
from nightly runs, i.e. are detached from the actual test
|
||||
running session. Here are `example tracebacks`_ for a number of failing
|
||||
test functions. You can modify traceback printing styles through the
|
||||
command line. Using the `--pdb`` option you can automatically activate
|
||||
a PDB `Python debugger`_ when a test fails.
|
||||
|
||||
|
|
@ -5,12 +5,12 @@ no-boilerplate testing with Python
|
|||
----------------------------------
|
||||
|
||||
- automatic, fully customizable Python test discovery
|
||||
- allows fully :pep:`8` compliant coding style
|
||||
- write simple test functions and freely group tests
|
||||
- ``assert`` statement for your assertions
|
||||
- powerful parametrization of test functions
|
||||
- rely on powerful traceback and assertion reporting
|
||||
- rely on helpful traceback and failing assertion reporting
|
||||
- use ``print`` or ``pdb`` debugging on failures
|
||||
- enables fully :pep:`8` compliant coding style
|
||||
|
||||
extensive plugin and customization system
|
||||
------------------------------------------------------
|
||||
|
@ -25,11 +25,9 @@ extensive plugin and customization system
|
|||
mature command line testing tool
|
||||
--------------------------------------
|
||||
|
||||
- powerful :ref:`usage` possibilities
|
||||
- powerful :ref:`usage` possibilities, well sorted command line options
|
||||
- used in many projects, ranging from 10 to 10K tests
|
||||
- simple well sorted command line options
|
||||
- runs on Unix, Windows from Python 2.4 up to Python 3.1 and 3.2
|
||||
- is itself tested extensively on a CI server
|
||||
- tested on Unix and Windows from Python 2.4 up to Python 3.1 and 3.2
|
||||
- keyword/testname based selection of tests
|
||||
|
||||
integrates well with CI systems
|
||||
|
@ -41,7 +39,6 @@ integrates well with CI systems
|
|||
|
||||
.. _`tox`: http://codespeak.net/tox
|
||||
|
||||
|
||||
supports common testing practises and methods
|
||||
-----------------------------------------------------------
|
||||
|
||||
|
|
|
@ -36,17 +36,17 @@ That's it. You can execute the test function now::
|
|||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.6.5 -- pytest-2.0.0.dev30
|
||||
test path 1: /tmp/doc-exec-70
|
||||
|
||||
|
||||
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 =========================
|
||||
|
||||
|
@ -120,14 +120,14 @@ run the module by passing its filename::
|
|||
.F
|
||||
================================= FAILURES =================================
|
||||
____________________________ TestClass.test_two ____________________________
|
||||
|
||||
|
||||
self = <test_class.TestClass instance at 0x288fc20>
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
@ -156,14 +156,14 @@ before performing the test function call. Let's just run it::
|
|||
F
|
||||
================================= FAILURES =================================
|
||||
_____________________________ test_needsfiles ______________________________
|
||||
|
||||
|
||||
tmpdir = local('/tmp/pytest-122/test_needsfiles0')
|
||||
|
||||
|
||||
def test_needsfiles(tmpdir):
|
||||
print tmpdir
|
||||
> assert 0
|
||||
E assert 0
|
||||
|
||||
|
||||
test_tmpdir.py:3: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
/tmp/pytest-122/test_needsfiles0
|
||||
|
@ -194,29 +194,20 @@ 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.
|
||||
|
||||
Consult `distribute docs`_ to install the ``easy_install``
|
||||
tool on your machine. You may also use the older
|
||||
`setuptools`_ project but it lacks bug fixes and does not
|
||||
work on Python3. If you use Python2 you may also install pip_.
|
||||
|
||||
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.
|
||||
you need to add the Python script path to your ``PATH``, see here:
|
||||
`Python for Windows`_. You may alternatively use an `ActivePython install`_
|
||||
which does this for you automatically.
|
||||
|
||||
.. _`ActivePython install`: http://www.activestate.com/activepython/downloads
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ py.test: no-boilerplate testing with Python
|
|||
|
||||
.. note::
|
||||
version 2.0 introduces ``pytest`` as the main Python import name
|
||||
but for compatibility reasons you can continue to use ``py.test``
|
||||
in your test code.
|
||||
but for compatibility reasons you can continue to use ``import py``
|
||||
and ``py.test.XYZ`` to access :ref:`pytest helpers` in your test code.
|
||||
|
||||
Welcome to ``py.test`` documentation:
|
||||
|
||||
|
@ -25,6 +25,7 @@ Welcome to ``py.test`` documentation:
|
|||
:hidden:
|
||||
|
||||
changelog.txt
|
||||
example/attic
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
.. _`setuptools`: http://pypi.python.org/pypi/setuptools
|
||||
|
||||
.. _`easy_install`:
|
||||
.. _`distribute docs`:
|
||||
.. _`distribute`: http://pypi.python.org/pypi/distribute
|
||||
.. _`pip`: http://pypi.python.org/pypi/pip
|
||||
.. _`virtualenv`: http://pypi.python.org/pypi/virtualenv
|
||||
|
|
15
doc/nose.txt
15
doc/nose.txt
|
@ -4,7 +4,6 @@ Running test written for nose
|
|||
.. include:: links.inc
|
||||
|
||||
py.test has basic support for running tests written for nose_.
|
||||
This is implemented in :pymod:`_pytest.nose`.
|
||||
|
||||
Usage
|
||||
-------------
|
||||
|
@ -13,8 +12,8 @@ type::
|
|||
|
||||
py.test # instead of 'nosetests'
|
||||
|
||||
and you should be able to run your nose style tests and at the same
|
||||
make full use of py.test's capabilities.
|
||||
and you should be able to run your nose style tests and
|
||||
make use of py.test's capabilities.
|
||||
|
||||
Supported nose Idioms
|
||||
----------------------
|
||||
|
@ -25,18 +24,12 @@ Supported nose Idioms
|
|||
* yield-based tests and their setup
|
||||
* general usage of nose utilities
|
||||
|
||||
Unsupported idioms / issues
|
||||
Unsupported idioms / known issues
|
||||
----------------------------------
|
||||
|
||||
- nose-style doctests are not collected and executed correctly,
|
||||
also fixtures don't work.
|
||||
also doctest fixtures don't work.
|
||||
|
||||
- no nose-configuration is recognized
|
||||
|
||||
If you find other issues or have suggestions please run::
|
||||
|
||||
py.test --pastebin=all
|
||||
|
||||
and send the resulting URL to a py.test contact channel,
|
||||
at best to the mailing list.
|
||||
"""
|
||||
|
|
|
@ -52,7 +52,6 @@ earlier than further away ones.
|
|||
under a package scope or to never import anything from a
|
||||
conftest.py file.
|
||||
|
||||
.. _`installing plugins`:
|
||||
.. _`external plugins`:
|
||||
|
||||
Installing External Plugins / Searching
|
||||
|
@ -85,12 +84,11 @@ you can copy from:
|
|||
* around 20 `builtin plugins`_ which comprise py.test's own functionality
|
||||
* around 10 `external plugins`_ providing additional features
|
||||
|
||||
All of these plugins are using the documented `well specified hooks`_
|
||||
to implement their wide-ranging functionality.
|
||||
All of these plugins implement the documented `well specified hooks`_
|
||||
to extend and add functionality.
|
||||
|
||||
.. _`setuptools entry points`:
|
||||
|
||||
|
||||
Making your plugin installable by others
|
||||
-----------------------------------------------
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class TestGeneralUsage:
|
|||
def test_1(pytestconfig):
|
||||
pytestconfig.getbasetemp().ensure("hello")
|
||||
""")
|
||||
result = testdir.runpytest(p, '--basetemp=%s' %mytemp)
|
||||
result = testdir.runpytest(p, '--basetemp=%s' % mytemp)
|
||||
assert result.ret == 0
|
||||
assert mytemp.join('hello').check()
|
||||
|
||||
|
@ -239,7 +239,7 @@ class TestInvocationVariants:
|
|||
|
||||
def test_pydoc(self, testdir):
|
||||
for name in ('py.test', 'pytest'):
|
||||
result = testdir.runpython_c("import %s;help(%s)" % (name,name))
|
||||
result = testdir.runpython_c("import %s;help(%s)" % (name, name))
|
||||
assert result.ret == 0
|
||||
s = result.stdout.str()
|
||||
assert 'MarkGenerator' in s
|
||||
|
@ -325,7 +325,7 @@ class TestInvocationVariants:
|
|||
class MyPlugin:
|
||||
def pytest_addoption(self, parser):
|
||||
parser.addoption("--myopt")
|
||||
|
||||
|
||||
pytest.main(["-h"], plugins=[MyPlugin()])
|
||||
out, err = capsys.readouterr()
|
||||
assert "--myopt" in out
|
||||
|
@ -358,7 +358,6 @@ class TestInvocationVariants:
|
|||
"ERROR*file*or*package*not*found*",
|
||||
])
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="decide: feature or bug")
|
||||
def test_noclass_discovery_if_not_testcase(self, testdir):
|
||||
testpath = testdir.makepyfile("""
|
||||
|
|
|
@ -204,12 +204,12 @@ class TestCustomConftests:
|
|||
return path.basename.startswith("x") or \
|
||||
path.basename == "test_one.py"
|
||||
""")
|
||||
testdir.mkdir("xy123").ensure("test_hello.py").write(
|
||||
"syntax error"
|
||||
)
|
||||
sub = testdir.mkdir("xy123")
|
||||
sub.ensure("test_hello.py").write("syntax error")
|
||||
sub.join("conftest.py").write("syntax error")
|
||||
testdir.makepyfile("def test_hello(): pass")
|
||||
testdir.makepyfile(test_one="syntax error")
|
||||
result = testdir.runpytest()
|
||||
result = testdir.runpytest("--fulltrace")
|
||||
assert result.ret == 0
|
||||
result.stdout.fnmatch_lines(["*1 passed*"])
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@ import py, pytest
|
|||
from _pytest.mark import MarkGenerator as Mark
|
||||
|
||||
class TestMark:
|
||||
def test_pytest_exists_in_namespace_all(self):
|
||||
assert 'mark' in py.test.__all__
|
||||
assert 'mark' in pytest.__all__
|
||||
|
||||
def test_pytest_mark_notcallable(self):
|
||||
mark = Mark()
|
||||
pytest.raises((AttributeError, TypeError), "mark()")
|
||||
|
|
8
tox.ini
8
tox.ini
|
@ -24,6 +24,12 @@ commands=
|
|||
py.test -n3 -rfsxX \
|
||||
--junitxml={envlogdir}/junit-{envname}.xml []
|
||||
|
||||
[testenv:doctest]
|
||||
changedir=.
|
||||
commands=py.test --doctest-modules _pytest
|
||||
deps=
|
||||
|
||||
|
||||
[testenv:doc]
|
||||
basepython=python
|
||||
changedir=doc
|
||||
|
@ -57,6 +63,6 @@ commands=
|
|||
[pytest]
|
||||
minversion=2.0
|
||||
plugins=pytester
|
||||
addopts= -rxf --pyargs
|
||||
addopts= -rxf --pyargs --doctest-modules
|
||||
rsyncdirs=tox.ini pytest.py _pytest testing
|
||||
|
||||
|
|
Loading…
Reference in New Issue