commit
4cf46c2723
|
@ -1,7 +1,7 @@
|
||||||
Changes between 1.0.0b7 and 1.0.0b8
|
Changes between 1.0.0b7 and 1.0.0b8
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
* workaround a logging module interaction ("closing already closed
|
* workaround a buggy logging module interaction ("closing already closed
|
||||||
files"). Thanks to Sridhar Ratnakumar for triggering.
|
files"). Thanks to Sridhar Ratnakumar for triggering.
|
||||||
|
|
||||||
* if plugins use "py.test.importorskip" for importing
|
* if plugins use "py.test.importorskip" for importing
|
||||||
|
@ -12,7 +12,9 @@ Changes between 1.0.0b7 and 1.0.0b8
|
||||||
- refined funcargs doc , use the term "factory" instead
|
- refined funcargs doc , use the term "factory" instead
|
||||||
of "provider"
|
of "provider"
|
||||||
- added a new talk/tutorial doc page
|
- added a new talk/tutorial doc page
|
||||||
|
- better download page
|
||||||
- better plugin docstrings
|
- better plugin docstrings
|
||||||
|
- added new plugins page and automatic doc generation script
|
||||||
|
|
||||||
* fixed teardown problem related to partially failing funcarg setups
|
* fixed teardown problem related to partially failing funcarg setups
|
||||||
(thanks MrTopf for reporting), "pytest_runtest_teardown" is now
|
(thanks MrTopf for reporting), "pytest_runtest_teardown" is now
|
||||||
|
|
3
MANIFEST
3
MANIFEST
|
@ -28,6 +28,7 @@ doc/test/examples.txt
|
||||||
doc/test/extend.txt
|
doc/test/extend.txt
|
||||||
doc/test/features.txt
|
doc/test/features.txt
|
||||||
doc/test/funcargs.txt
|
doc/test/funcargs.txt
|
||||||
|
doc/test/plugins.txt
|
||||||
doc/test/quickstart.txt
|
doc/test/quickstart.txt
|
||||||
doc/test/talks.txt
|
doc/test/talks.txt
|
||||||
doc/test/test.txt
|
doc/test/test.txt
|
||||||
|
@ -37,6 +38,7 @@ example/assertion/failure_demo.py
|
||||||
example/assertion/test_failures.py
|
example/assertion/test_failures.py
|
||||||
example/assertion/test_setup_flow_example.py
|
example/assertion/test_setup_flow_example.py
|
||||||
example/execnet/popen_read_multiple.py
|
example/execnet/popen_read_multiple.py
|
||||||
|
example/execnet/redirect_remote_output.py
|
||||||
example/execnet/svn-sync-repo.py
|
example/execnet/svn-sync-repo.py
|
||||||
example/execnet/sysinfo.py
|
example/execnet/sysinfo.py
|
||||||
example/funcarg/conftest.py
|
example/funcarg/conftest.py
|
||||||
|
@ -59,6 +61,7 @@ example/funcarg/test_simpleprovider.py
|
||||||
example/genhtml.py
|
example/genhtml.py
|
||||||
example/genhtmlcss.py
|
example/genhtmlcss.py
|
||||||
example/genxml.py
|
example/genxml.py
|
||||||
|
makepluginlist.py
|
||||||
py/LICENSE
|
py/LICENSE
|
||||||
py/__init__.py
|
py/__init__.py
|
||||||
py/_com.py
|
py/_com.py
|
||||||
|
|
|
@ -173,20 +173,20 @@ class Project:
|
||||||
stylesheet=stylesheet, encoding=encoding)
|
stylesheet=stylesheet, encoding=encoding)
|
||||||
content = strip_html_header(content, encoding=encoding)
|
content = strip_html_header(content, encoding=encoding)
|
||||||
|
|
||||||
page = self.Page(self, "[%s] " % txtpath.purebasename,
|
title = "[%s] %s" % (txtpath.purebasename, py.version)
|
||||||
|
page = self.Page(self, title,
|
||||||
outputpath, stylesheeturl=stylesheet)
|
outputpath, stylesheeturl=stylesheet)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
svninfo = txtpath.info()
|
modified = py.process.cmdexec(
|
||||||
modified = " modified %s by %s" % (worded_time(svninfo.mtime),
|
"hg tip --template 'last modified {date|shortdate}'"
|
||||||
getrealname(svninfo.last_author))
|
)
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except py.process.cmdexec.Error:
|
||||||
raise
|
|
||||||
except:
|
|
||||||
modified = " "
|
modified = " "
|
||||||
|
|
||||||
page.contentspace.append(
|
page.contentspace.append(
|
||||||
html.div(html.div(modified, style="float: right; font-style: italic;"),
|
html.div(html.div(modified,
|
||||||
|
style="float: right; font-style: italic;"),
|
||||||
id = 'docinfoline'))
|
id = 'docinfoline'))
|
||||||
|
|
||||||
page.contentspace.append(py.xml.raw(content))
|
page.contentspace.append(py.xml.raw(content))
|
||||||
|
|
128
doc/download.txt
128
doc/download.txt
|
@ -6,12 +6,11 @@ Downloading
|
||||||
|
|
||||||
Latest Release, see `PyPI project page`_
|
Latest Release, see `PyPI project page`_
|
||||||
|
|
||||||
"easy_install py"
|
using setuptools / easy_install
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
With a working `setuptools installation`_ you can type::
|
With a working `setuptools installation`_ you can type::
|
||||||
|
|
||||||
|
|
||||||
easy_install -U py
|
easy_install -U py
|
||||||
|
|
||||||
to get the latest release of the py lib. The ``-U`` switch
|
to get the latest release of the py lib. The ``-U`` switch
|
||||||
|
@ -26,21 +25,77 @@ install the full py lib. If you don't have a compiler available
|
||||||
you can still install the py lib but without greenlets - look
|
you can still install the py lib but without greenlets - look
|
||||||
below for the ``install_lib`` target.
|
below for the ``install_lib`` target.
|
||||||
|
|
||||||
**IMPORTANT NOTE**: if you are using Windows and have previous
|
**IMPORTANT NOTE**: if you are using Windows and have
|
||||||
installations of the py lib on your system, please download
|
0.8 versions of the py lib on your system, please download
|
||||||
and execute http://codespeak.net/svn/py/build/winpathclean.py
|
and execute http://codespeak.net/svn/py/build/winpathclean.py
|
||||||
This will check that no previous files are getting in the way.
|
This will check that no previous files are getting in the way.
|
||||||
(Unfortunately we don't know about a way to execute this
|
You can find out the py lib version with::
|
||||||
code automatically during the above install).
|
|
||||||
|
|
||||||
Installing on Debian or Fedora
|
import py
|
||||||
|
print py.version
|
||||||
|
|
||||||
|
|
||||||
|
.. _`checkout`:
|
||||||
|
|
||||||
|
Installing from version control / develop mode
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
To follow development or help with fixing things
|
||||||
|
for the next release, checkout the complete code
|
||||||
|
and documentation source with mercurial_::
|
||||||
|
|
||||||
|
hg clone https://bitbucket.org/hpk42/py-trunk/
|
||||||
|
|
||||||
|
With a working `setuptools installation`_ you can then issue::
|
||||||
|
|
||||||
|
python setup.py develop
|
||||||
|
|
||||||
|
in order to work with your checkout version.
|
||||||
|
|
||||||
|
.. _mercurial: http://mercurial.selenic.com/wiki/
|
||||||
|
|
||||||
|
Working without setuptools / from source
|
||||||
|
==========================================
|
||||||
|
|
||||||
|
If you have a checkout_ or a tarball_ it is actually not neccessary to issue
|
||||||
|
``setup.py`` commands in order to use py lib and its tools. You can
|
||||||
|
simply add the root directory to ``PYTHONPATH`` and ``py/bin`` or
|
||||||
|
``py\bin\win32`` to your ``PATH`` settings.
|
||||||
|
|
||||||
|
There are also helper scripts to set the environment
|
||||||
|
on windows::
|
||||||
|
|
||||||
|
c:\\path\to\checkout\py\env.cmd
|
||||||
|
|
||||||
|
and on linux/osx you can add something like this to
|
||||||
|
your shell initialization::
|
||||||
|
|
||||||
|
eval `python ~/path/to/checkout/py/env.py`
|
||||||
|
|
||||||
|
both of which which will get you good settings
|
||||||
|
for ``PYTHONPATH`` and ``PATH``.
|
||||||
|
|
||||||
|
Note also that the command line scripts will look
|
||||||
|
for "nearby" py libs, so if you have a layout like this::
|
||||||
|
|
||||||
|
mypkg/
|
||||||
|
subpkg1/
|
||||||
|
tests/
|
||||||
|
tests/
|
||||||
|
py/
|
||||||
|
|
||||||
|
then issuing ``py.test subpkg1`` will use the py lib
|
||||||
|
from that projects root directory.
|
||||||
|
|
||||||
|
Debian and RPM packages
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
As of July 2009 pytest/pylib 1.0 RPMs and Debian packages
|
As of July 2009 pytest/pylib 1.0 RPMs and Debian packages
|
||||||
are not yet available.
|
are not yet available. So you will only find older
|
||||||
|
versions.
|
||||||
|
|
||||||
On Debian systems look for ``python-codespeak-lib``.
|
On Debian systems look for ``python-codespeak-lib``.
|
||||||
*This package is probably outdated - if somebody
|
*But this package is probably outdated - if somebody
|
||||||
can help with bringing this up to date,
|
can help with bringing this up to date,
|
||||||
that would be very much appreciated.*
|
that would be very much appreciated.*
|
||||||
|
|
||||||
|
@ -50,12 +105,14 @@ Dwayne Bailey has thankfully put together a Fedora `RPM`_.
|
||||||
|
|
||||||
.. _`setuptools installation`: http://pypi.python.org/pypi/setuptools
|
.. _`setuptools installation`: http://pypi.python.org/pypi/setuptools
|
||||||
|
|
||||||
Downloading a tar/zip archive and installing that
|
.. _tarball:
|
||||||
|
|
||||||
|
Installing from a TAR archive
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
You need a working `setuptools installation`_.
|
You need a working `setuptools installation`_.
|
||||||
|
|
||||||
Go to the python package index (pypi) and download a tar or zip file:
|
Go to the python package index (pypi) and download a tar file:
|
||||||
|
|
||||||
http://pypi.python.org/pypi/py/
|
http://pypi.python.org/pypi/py/
|
||||||
|
|
||||||
|
@ -63,52 +120,3 @@ and unpack it to a directory, where you then type::
|
||||||
|
|
||||||
python setup.py install
|
python setup.py install
|
||||||
|
|
||||||
Installing from subversion / develop mode
|
|
||||||
============================================
|
|
||||||
|
|
||||||
To follow development or help with fixing things
|
|
||||||
for the next release, checkout the complete code
|
|
||||||
and documentation source with mercurial::
|
|
||||||
|
|
||||||
hg clone https://bitbucket.org/hpk42/py-trunk/
|
|
||||||
|
|
||||||
or with subversion:
|
|
||||||
|
|
||||||
svn co http://codespeak.net/svn/py/trunk
|
|
||||||
|
|
||||||
With a working `setuptools installation`_ you can then issue::
|
|
||||||
|
|
||||||
python setup.py develop
|
|
||||||
|
|
||||||
in order to work with your checkout version.
|
|
||||||
|
|
||||||
|
|
||||||
Working with multiple py lib versions / svn externals
|
|
||||||
=======================================================
|
|
||||||
|
|
||||||
If you happen to have multiple versions of the py lib
|
|
||||||
around or you ship the py lib as an svn-external to
|
|
||||||
then you might want to use py lib scripts more directly.
|
|
||||||
For example if you have a project layout like this::
|
|
||||||
|
|
||||||
mypkg/
|
|
||||||
subpkg1/
|
|
||||||
tests/
|
|
||||||
tests/
|
|
||||||
py/ # as svn-external, could be specific tag/version
|
|
||||||
|
|
||||||
then you want to make sure that the actual local py lib is used
|
|
||||||
and not another system-wide version. For this you need to add
|
|
||||||
``py/bin`` or ``py\bin\win32`` respectively to your system's PATH settings.
|
|
||||||
|
|
||||||
You can do this by executing (on windows) a script to set the environment::
|
|
||||||
|
|
||||||
c:\\path\to\checkout\py\env.cmd
|
|
||||||
|
|
||||||
or on linux/osx you can add something like this to your shell
|
|
||||||
initialization::
|
|
||||||
|
|
||||||
eval `python ~/path/to/checkout/py/env.py`
|
|
||||||
|
|
||||||
to get good settings for PYTHONPATH and PATH.
|
|
||||||
|
|
||||||
|
|
|
@ -39,27 +39,3 @@ Minor support functionality
|
||||||
.. _`py.xml`: xml.html
|
.. _`py.xml`: xml.html
|
||||||
.. _`miscellaneous features`: misc.html
|
.. _`miscellaneous features`: misc.html
|
||||||
|
|
||||||
Full Contents
|
|
||||||
===================================
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
test
|
|
||||||
execnet
|
|
||||||
path
|
|
||||||
code
|
|
||||||
bin
|
|
||||||
xml
|
|
||||||
io
|
|
||||||
log
|
|
||||||
misc
|
|
||||||
coding-style
|
|
||||||
contact
|
|
||||||
download
|
|
||||||
releases
|
|
||||||
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
||||||
|
|
|
@ -6,13 +6,16 @@ Extending and customizing py.test
|
||||||
|
|
||||||
py.test implements much of its functionality by calling `well specified
|
py.test implements much of its functionality by calling `well specified
|
||||||
hooks`_. Python modules which contain such hook functions are called
|
hooks`_. Python modules which contain such hook functions are called
|
||||||
plugins. Hook functions are discovered in ``conftest.py`` files or
|
plugins. Hook functions are discovered in ``conftest.py`` files or in
|
||||||
in **named** plugins. ``conftest.py`` files are sometimes called "anonymous"
|
`named plugins`_. ``conftest.py`` files are sometimes called
|
||||||
or conftest plugins. They are useful for keeping test extensions close
|
"anonymous" or conftest plugins. They are useful for keeping test
|
||||||
to the application package. Named plugins are normal python modules or packages
|
extensions close to your application. Named plugins are normal python
|
||||||
that can be distributed separately. Named plugins need to follow a naming pattern;
|
modules or packages that can be distributed separately. Named plugins
|
||||||
they have an all lowercase ``pytest_`` prefixed name. While conftest plugins are
|
need to follow a naming pattern; they have an all lowercase ``pytest_``
|
||||||
discovered automatically, named plugins must be explicitely specified.
|
prefixed name. While conftest plugins are discovered automatically,
|
||||||
|
named plugins must be explicitely specified.
|
||||||
|
|
||||||
|
.. _`named plugins`: plugins.html
|
||||||
|
|
||||||
.. _`tool startup`:
|
.. _`tool startup`:
|
||||||
.. _`test tool starts up`:
|
.. _`test tool starts up`:
|
||||||
|
|
|
@ -292,7 +292,8 @@ To make it easier to distinguish the generated tests it is possible to specify a
|
||||||
easy to extend
|
easy to extend
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
Since 1.0 py.test has advanced `extension mechanisms`_.
|
Since 1.0 py.test has advanced `extension mechanisms`_
|
||||||
|
and a growing `list of plugins`_.
|
||||||
One can can easily modify or add aspects for for
|
One can can easily modify or add aspects for for
|
||||||
purposes such as:
|
purposes such as:
|
||||||
|
|
||||||
|
@ -301,6 +302,7 @@ purposes such as:
|
||||||
* running non-python tests
|
* running non-python tests
|
||||||
* managing custom test state setup
|
* managing custom test state setup
|
||||||
|
|
||||||
|
.. _`list of plugins`: plugins.html
|
||||||
.. _`extension mechanisms`: extend.html
|
.. _`extension mechanisms`: extend.html
|
||||||
|
|
||||||
.. _`reStructured Text`: http://docutils.sourceforge.net
|
.. _`reStructured Text`: http://docutils.sourceforge.net
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
=====================================================
|
||||||
|
Plugins related to Python test functions and programs
|
||||||
|
=====================================================
|
||||||
|
* `pytest_xfail`_ mark tests as expected-to-fail and report them separately.
|
||||||
|
|
||||||
|
* `pytest_figleaf`_ write and report coverage data with 'figleaf'.
|
||||||
|
|
||||||
|
* `pytest_monkeypatch`_ safely patch object attributes, dicts and environment variables.
|
||||||
|
|
||||||
|
* `pytest_iocapture`_ 'capsys' and 'capfd' funcargs for capturing stdout/stderror.
|
||||||
|
|
||||||
|
* `pytest_recwarn`_ helpers for asserting deprecation and other warnings.
|
||||||
|
|
||||||
|
|
||||||
|
==============================================
|
||||||
|
Plugins for other testing styles and languages
|
||||||
|
==============================================
|
||||||
|
* `pytest_unittest`_ automatically discover and run traditional "unittest.py" style tests.
|
||||||
|
|
||||||
|
* `pytest_doctest`_ collect and execute doctests from modules and test files.
|
||||||
|
|
||||||
|
* `pytest_restdoc`_ perform ReST syntax, local and remote reference tests on .rst/.txt files.
|
||||||
|
|
||||||
|
* `pytest_oejskit`_ Testing Javascript in real browsers
|
||||||
|
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
Plugins for generic reporting and failure logging
|
||||||
|
=================================================
|
||||||
|
* `pytest_pocoo`_ submit failure information to paste.pocoo.org
|
||||||
|
|
||||||
|
* `pytest_resultlog`_ resultlog plugin for machine-readable logging of test results.
|
||||||
|
|
||||||
|
* `pytest_terminal`_ terminal reporting of the full testing process.
|
||||||
|
|
||||||
|
|
||||||
|
=====================================
|
||||||
|
internal plugins / core functionality
|
||||||
|
=====================================
|
||||||
|
* `pytest_pdb`_ interactive debugging with the Python Debugger.
|
||||||
|
|
||||||
|
* `pytest_keyword`_ py.test.mark / keyword plugin
|
||||||
|
|
||||||
|
* `pytest_hooklog`_ log invocations of extension hooks to a file.
|
||||||
|
|
||||||
|
* `pytest_runner`_ collect and run test items and create reports.
|
||||||
|
|
||||||
|
* `pytest_execnetcleanup`_ cleanup execnet gateways during test function runs.
|
||||||
|
|
||||||
|
* `pytest_pytester`_ funcargs and support code for testing py.test's own functionality.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _`pytest_xfail`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_xfail.py
|
||||||
|
.. _`pytest_figleaf`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_figleaf.py
|
||||||
|
.. _`pytest_monkeypatch`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_monkeypatch.py
|
||||||
|
.. _`pytest_iocapture`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_iocapture.py
|
||||||
|
.. _`pytest_recwarn`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_recwarn.py
|
||||||
|
.. _`pytest_unittest`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_unittest.py
|
||||||
|
.. _`pytest_doctest`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_doctest.py
|
||||||
|
.. _`pytest_restdoc`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_restdoc.py
|
||||||
|
.. _`pytest_oejskit`: http://bitbucket.org/pedronis/js-infrastructure/src/tip/pytest_jstests.py
|
||||||
|
.. _`pytest_pocoo`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_pocoo.py
|
||||||
|
.. _`pytest_resultlog`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_resultlog.py
|
||||||
|
.. _`pytest_terminal`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_terminal.py
|
||||||
|
.. _`pytest_pdb`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_pdb.py
|
||||||
|
.. _`pytest_keyword`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_keyword.py
|
||||||
|
.. _`pytest_hooklog`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_hooklog.py
|
||||||
|
.. _`pytest_runner`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_runner.py
|
||||||
|
.. _`pytest_execnetcleanup`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_execnetcleanup.py
|
||||||
|
.. _`pytest_pytester`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_pytester.py
|
|
@ -11,6 +11,8 @@ quickstart_: for getting started immediately.
|
||||||
|
|
||||||
features_: a walk through basic features and usage.
|
features_: a walk through basic features and usage.
|
||||||
|
|
||||||
|
`available plugins`_: list of py.test plugins
|
||||||
|
|
||||||
funcargs_: powerful parametrized test function setup
|
funcargs_: powerful parametrized test function setup
|
||||||
|
|
||||||
`distributed testing`_: distribute test runs to other machines and platforms.
|
`distributed testing`_: distribute test runs to other machines and platforms.
|
||||||
|
@ -21,6 +23,7 @@ config_: ``conftest.py`` files and the config object
|
||||||
|
|
||||||
talks_: talk and tutorial slides
|
talks_: talk and tutorial slides
|
||||||
|
|
||||||
|
.. _`available plugins`: plugins.html
|
||||||
.. _talks: talks.html
|
.. _talks: talks.html
|
||||||
.. _quickstart: quickstart.html
|
.. _quickstart: quickstart.html
|
||||||
.. _features: features.html
|
.. _features: features.html
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
"""
|
||||||
|
redirect output from remote to a local function
|
||||||
|
showcasing features of the channel object:
|
||||||
|
|
||||||
|
- sending a channel over a channel
|
||||||
|
- adapting a channel to a file object
|
||||||
|
- setting a callback for receiving channel data
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import py
|
||||||
|
|
||||||
|
gw = py.execnet.PopenGateway()
|
||||||
|
|
||||||
|
outchan = gw.remote_exec("""
|
||||||
|
import sys
|
||||||
|
outchan = channel.gateway.newchannel()
|
||||||
|
sys.stdout = outchan.makefile("w")
|
||||||
|
channel.send(outchan)
|
||||||
|
""").receive()
|
||||||
|
|
||||||
|
# note: callbacks execute in receiver thread!
|
||||||
|
def write(data):
|
||||||
|
print "received:", repr(data)
|
||||||
|
outchan.setcallback(write)
|
||||||
|
|
||||||
|
gw.remote_exec("""
|
||||||
|
print 'hello world'
|
||||||
|
print 'remote execution ends'
|
||||||
|
""").waitclose()
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
|
||||||
|
import py
|
||||||
|
import sys
|
||||||
|
WIDTH = 75
|
||||||
|
|
||||||
|
plugins = [
|
||||||
|
('Plugins related to Python test functions and programs',
|
||||||
|
'xfail figleaf monkeypatch iocapture recwarn',),
|
||||||
|
('Plugins for other testing styles and languages',
|
||||||
|
'unittest doctest restdoc osjskit'),
|
||||||
|
('Plugins for generic reporting and failure logging',
|
||||||
|
'pocoo resultlog terminal',),
|
||||||
|
('internal plugins / core functionality',
|
||||||
|
'pdb keyword hooklog runner execnetcleanup pytester',
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
externals = {
|
||||||
|
'osjskit': ('`pytest_oejskit`_ Testing Javascript in real browsers',
|
||||||
|
'''
|
||||||
|
jskit contains infrastructure and in particular a py.test plugin to enable running tests for JavaScript code inside browsers directly using py.test as the test driver. Running inside the browsers comes with some speed cost, on the other hand it means for example the code is tested against the real-word DOM implementations.
|
||||||
|
|
||||||
|
The approach also enables to write integration tests such that the JavaScript code is tested against server-side Python code mocked as necessary. Any server-side framework that can already be exposed through WSGI (or for which a subset of WSGI can be written to accommodate the jskit own needs) can play along.
|
||||||
|
|
||||||
|
jskit also contains code to help modularizing JavaScript code which can be used to describe and track dependencies dynamically during development and that can help resolving them statically when deploying/packaging.
|
||||||
|
|
||||||
|
jskit depends on simplejson. It also uses MochiKit - of which it ships a version within itself for convenience - for its own working though in does not imposes its usage on tested code.
|
||||||
|
|
||||||
|
jskit was initially developed by Open End AB and is released under the MIT license.
|
||||||
|
''', 'http://pypi.python.org/pypi/oejskit',
|
||||||
|
('pytest_oejskit',
|
||||||
|
'http://bitbucket.org/pedronis/js-infrastructure/src/tip/pytest_jstests.py',
|
||||||
|
))}
|
||||||
|
|
||||||
|
class ExternalDoc:
|
||||||
|
def __init__(self, name):
|
||||||
|
self.title, self.longdesc, self.url, sourcelink = externals[name]
|
||||||
|
self.sourcelink = sourcelink
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class PluginDoc:
|
||||||
|
def __init__(self, plugin):
|
||||||
|
self.plugin = plugin
|
||||||
|
doc = plugin.__doc__.strip()
|
||||||
|
i = doc.find("\n")
|
||||||
|
if i == -1:
|
||||||
|
title = doc
|
||||||
|
longdesc = "XXX no long description available"
|
||||||
|
else:
|
||||||
|
title = doc[:i].strip()
|
||||||
|
longdesc = doc[i+1:].strip()
|
||||||
|
purename = plugin.__name__.split(".")[-1].strip()
|
||||||
|
self.title = "`%s`_ %s" %(purename, title)
|
||||||
|
self.longdesc = longdesc
|
||||||
|
self.sourcelink = (purename,
|
||||||
|
"http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/" +
|
||||||
|
purename + ".py")
|
||||||
|
|
||||||
|
def warn(msg):
|
||||||
|
print >>sys.stderr, "WARNING:", msg
|
||||||
|
|
||||||
|
|
||||||
|
def makedoc(name):
|
||||||
|
if name in externals:
|
||||||
|
return ExternalDoc(name)
|
||||||
|
config.pluginmanager.import_plugin(name)
|
||||||
|
plugin = config.pluginmanager.getplugin(name)
|
||||||
|
if plugin is None:
|
||||||
|
return None
|
||||||
|
return PluginDoc(plugin)
|
||||||
|
|
||||||
|
def header():
|
||||||
|
#print "=" * WIDTH
|
||||||
|
#print "list of available py.test plugins"
|
||||||
|
#print "=" * WIDTH
|
||||||
|
print
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
config = py.test.config
|
||||||
|
config.parse([])
|
||||||
|
config.pluginmanager.do_configure(config)
|
||||||
|
|
||||||
|
header()
|
||||||
|
|
||||||
|
links = []
|
||||||
|
for cat, specs in plugins:
|
||||||
|
pluginlist = specs.split()
|
||||||
|
print len(cat) * "="
|
||||||
|
print cat
|
||||||
|
print len(cat) * "="
|
||||||
|
for name in pluginlist:
|
||||||
|
doc = makedoc(name)
|
||||||
|
if doc is None:
|
||||||
|
warn("skipping", name)
|
||||||
|
continue
|
||||||
|
print "* " + str(doc.title)
|
||||||
|
#print len(doc.title) * "*"
|
||||||
|
#print doc.longdesc
|
||||||
|
links.append(doc.sourcelink)
|
||||||
|
print
|
||||||
|
print
|
||||||
|
print
|
||||||
|
for link in links:
|
||||||
|
warn(repr(link))
|
||||||
|
print ".. _`%s`: %s" % (link[0], link[1])
|
|
@ -18,8 +18,9 @@ For questions please check out http://pylib.org/contact.html
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from initpkg import initpkg
|
from initpkg import initpkg
|
||||||
|
trunk = None
|
||||||
|
|
||||||
version = "trunk"
|
version = trunk or "1.0.0b8"
|
||||||
|
|
||||||
initpkg(__name__,
|
initpkg(__name__,
|
||||||
description = "py.test and pylib: advanced testing tool and networking lib",
|
description = "py.test and pylib: advanced testing tool and networking lib",
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
"""
|
"""
|
||||||
py.test hooks / extension points
|
py.test plugin hooks
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Command line and configuration hooks
|
# Command line and configuration
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
""" called before commandline parsing. """
|
""" called before commandline parsing. """
|
||||||
|
|
||||||
|
@ -17,26 +18,12 @@ def pytest_configure(config):
|
||||||
def pytest_namespace(config):
|
def pytest_namespace(config):
|
||||||
""" return dict of name->object to become available at py.test.*"""
|
""" return dict of name->object to become available at py.test.*"""
|
||||||
|
|
||||||
|
|
||||||
def pytest_unconfigure(config):
|
def pytest_unconfigure(config):
|
||||||
""" called before test process is exited. """
|
""" called before test process is exited. """
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# test Session related hooks
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def pytest_sessionstart(session):
|
|
||||||
""" before session.main() is called. """
|
|
||||||
|
|
||||||
def pytest_sessionfinish(session, exitstatus, excrepr=None):
|
|
||||||
""" whole test run finishes. """
|
|
||||||
|
|
||||||
def pytest_deselected(items):
|
|
||||||
""" repeatedly called for test items deselected by keyword. """
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# collection hooks
|
# collection hooks
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_collect_directory(path, parent):
|
def pytest_collect_directory(path, parent):
|
||||||
""" return Collection node or None for the given path. """
|
""" return Collection node or None for the given path. """
|
||||||
|
@ -50,6 +37,9 @@ def pytest_collectstart(collector):
|
||||||
def pytest_collectreport(rep):
|
def pytest_collectreport(rep):
|
||||||
""" collector finished collecting. """
|
""" collector finished collecting. """
|
||||||
|
|
||||||
|
def pytest_deselected(items):
|
||||||
|
""" called for test items deselected by keyword. """
|
||||||
|
|
||||||
def pytest_make_collect_report(collector):
|
def pytest_make_collect_report(collector):
|
||||||
""" perform a collection and return a collection. """
|
""" perform a collection and return a collection. """
|
||||||
pytest_make_collect_report.firstresult = True
|
pytest_make_collect_report.firstresult = True
|
||||||
|
@ -58,9 +48,9 @@ pytest_make_collect_report.firstresult = True
|
||||||
def pytest_itemstart(item, node=None):
|
def pytest_itemstart(item, node=None):
|
||||||
""" test item gets collected. """
|
""" test item gets collected. """
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Python test function related hooks
|
# Python test function related hooks
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_pycollect_makeitem(collector, name, obj):
|
def pytest_pycollect_makeitem(collector, name, obj):
|
||||||
""" return custom item/collector for a python object in a module, or None. """
|
""" return custom item/collector for a python object in a module, or None. """
|
||||||
|
@ -73,9 +63,14 @@ pytest_pyfunc_call.firstresult = True
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
""" generate (multiple) parametrized calls to a test function."""
|
""" generate (multiple) parametrized calls to a test function."""
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# generic runtest related hooks
|
# generic runtest related hooks
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def pytest_runtest_protocol(item):
|
||||||
|
""" implement fixture, run and report protocol. """
|
||||||
|
pytest_runtest_protocol.firstresult = True
|
||||||
|
|
||||||
def pytest_runtest_setup(item):
|
def pytest_runtest_setup(item):
|
||||||
""" called before pytest_runtest_call(). """
|
""" called before pytest_runtest_call(). """
|
||||||
|
|
||||||
|
@ -85,10 +80,6 @@ def pytest_runtest_call(item):
|
||||||
def pytest_runtest_teardown(item):
|
def pytest_runtest_teardown(item):
|
||||||
""" called after pytest_runtest_call(). """
|
""" called after pytest_runtest_call(). """
|
||||||
|
|
||||||
def pytest_runtest_protocol(item):
|
|
||||||
""" run given test item and return test report. """
|
|
||||||
pytest_runtest_protocol.firstresult = True
|
|
||||||
|
|
||||||
def pytest_runtest_makereport(item, call):
|
def pytest_runtest_makereport(item, call):
|
||||||
""" make ItemTestReport for the given item and call outcome. """
|
""" make ItemTestReport for the given item and call outcome. """
|
||||||
pytest_runtest_makereport.firstresult = True
|
pytest_runtest_makereport.firstresult = True
|
||||||
|
@ -96,9 +87,20 @@ pytest_runtest_makereport.firstresult = True
|
||||||
def pytest_runtest_logreport(rep):
|
def pytest_runtest_logreport(rep):
|
||||||
""" process item test report. """
|
""" process item test report. """
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# generic reporting hooks (invoked from pytest_terminal.py)
|
# test session related hooks
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def pytest_sessionstart(session):
|
||||||
|
""" before session.main() is called. """
|
||||||
|
|
||||||
|
def pytest_sessionfinish(session, exitstatus, excrepr=None):
|
||||||
|
""" whole test run finishes. """
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# generic reporting hooks (invoked from pytest_terminal)
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_report_teststatus(rep):
|
def pytest_report_teststatus(rep):
|
||||||
""" return shortletter and verbose word. """
|
""" return shortletter and verbose word. """
|
||||||
pytest_report_teststatus.firstresult = True
|
pytest_report_teststatus.firstresult = True
|
||||||
|
@ -112,33 +114,17 @@ def pytest_report_iteminfo(item):
|
||||||
"""
|
"""
|
||||||
pytest_report_iteminfo.firstresult = True
|
pytest_report_iteminfo.firstresult = True
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# doctest hooks
|
# doctest hooks
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_doctest_prepare_content(content):
|
def pytest_doctest_prepare_content(content):
|
||||||
""" return processed content for a given doctest"""
|
""" return processed content for a given doctest"""
|
||||||
pytest_doctest_prepare_content.firstresult = True
|
pytest_doctest_prepare_content.firstresult = True
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# misc hooks
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def pytest_plugin_registered(plugin):
|
|
||||||
""" a new py lib plugin got registered. """
|
|
||||||
|
|
||||||
def pytest_plugin_unregistered(plugin):
|
|
||||||
""" a py lib plugin got unregistered. """
|
|
||||||
|
|
||||||
def pytest_internalerror(excrepr):
|
|
||||||
""" called for internal errors. """
|
|
||||||
|
|
||||||
def pytest_trace(category, msg):
|
|
||||||
""" called for debug info. """
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# distributed testing
|
# distributed testing
|
||||||
# ------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
def pytest_testnodeready(node):
|
def pytest_testnodeready(node):
|
||||||
""" Test Node is ready to operate. """
|
""" Test Node is ready to operate. """
|
||||||
|
@ -152,3 +138,19 @@ def pytest_rescheduleitems(items):
|
||||||
def pytest_looponfailinfo(failreports, rootdirs):
|
def pytest_looponfailinfo(failreports, rootdirs):
|
||||||
""" info for repeating failing tests. """
|
""" info for repeating failing tests. """
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# internal debugging hooks
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def pytest_plugin_registered(plugin):
|
||||||
|
""" a new py lib plugin got registered. """
|
||||||
|
|
||||||
|
def pytest_plugin_unregistered(plugin):
|
||||||
|
""" a py lib plugin got unregistered. """
|
||||||
|
|
||||||
|
def pytest_internalerror(excrepr):
|
||||||
|
""" called for internal errors. """
|
||||||
|
|
||||||
|
def pytest_trace(category, msg):
|
||||||
|
""" called for debug info. """
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
"""
|
"""
|
||||||
write and report coverage data using the 'figleaf' module.
|
write and report coverage data with 'figleaf'.
|
||||||
|
|
||||||
|
This plugin generates test coverage data or HTML files
|
||||||
|
from running tests against a code base.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
"""
|
"""
|
||||||
helpers for asserting deprecation and other warnings.
|
helpers for asserting deprecation and other warnings.
|
||||||
|
|
||||||
recwarn: function argument where one can call recwarn.pop() to get
|
**recwarn**: function argument where one can call recwarn.pop() to get
|
||||||
the last warning that would have been shown.
|
the last warning that would have been shown.
|
||||||
|
|
||||||
py.test.deprecated_call(func, *args, **kwargs):
|
**py.test.deprecated_call(func, *args, **kwargs)**: assert that the given function call triggers a deprecation warning.
|
||||||
assert that a function call triggers a deprecation warning.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import py
|
import py
|
||||||
|
|
|
@ -6,7 +6,7 @@ import py
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
group = parser.addgroup("resultlog", "resultlog plugin options")
|
group = parser.addgroup("resultlog", "resultlog plugin options")
|
||||||
group.addoption('--resultlog', action="store", dest="resultlog", metavar="path",
|
group.addoption('--resultlog', action="store", dest="resultlog", metavar="path", default=None,
|
||||||
help="path for machine-readable result log.")
|
help="path for machine-readable result log.")
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
mark tests as expected-to-fail and report them separately.
|
mark tests as expected-to-fail and report them separately.
|
||||||
|
|
||||||
example:
|
example::
|
||||||
|
|
||||||
@py.test.mark.xfail
|
@py.test.mark.xfail
|
||||||
def test_hello():
|
def test_hello():
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -25,12 +25,13 @@ For questions please check out http://pylib.org/contact.html
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
trunk = None
|
||||||
def main():
|
def main():
|
||||||
setup(
|
setup(
|
||||||
name='py',
|
name='py',
|
||||||
description='py.test and pylib: advanced testing tool and networking lib',
|
description='py.test and pylib: advanced testing tool and networking lib',
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
version='trunk',
|
version= trunk or '1.0.0b8',
|
||||||
url='http://pylib.org',
|
url='http://pylib.org',
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
|
|
Loading…
Reference in New Issue