add some missing files
This commit is contained in:
parent
582486d531
commit
0325441099
|
@ -0,0 +1,17 @@
|
||||||
|
import py
|
||||||
|
import subprocess
|
||||||
|
def test_build_docs(tmpdir):
|
||||||
|
doctrees = tmpdir.join("doctrees")
|
||||||
|
htmldir = tmpdir.join("html")
|
||||||
|
subprocess.check_call([
|
||||||
|
"sphinx-build", "-W", "-bhtml",
|
||||||
|
"-d", str(doctrees), ".", str(htmldir)])
|
||||||
|
|
||||||
|
def test_linkcheck(tmpdir):
|
||||||
|
doctrees = tmpdir.join("doctrees")
|
||||||
|
htmldir = tmpdir.join("html")
|
||||||
|
subprocess.check_call(
|
||||||
|
["sphinx-build", "-blinkcheck",
|
||||||
|
"-d", str(doctrees), ".", str(htmldir)])
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
|
||||||
|
.. _`accept example`:
|
||||||
|
|
||||||
|
example: specifying and selecting acceptance tests
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
# ./conftest.py
|
||||||
|
def pytest_option(parser):
|
||||||
|
group = parser.getgroup("myproject")
|
||||||
|
group.addoption("-A", dest="acceptance", action="store_true",
|
||||||
|
help="run (slow) acceptance tests")
|
||||||
|
|
||||||
|
def pytest_funcarg__accept(request):
|
||||||
|
return AcceptFuncarg(request)
|
||||||
|
|
||||||
|
class AcceptFuncarg:
|
||||||
|
def __init__(self, request):
|
||||||
|
if not request.config.option.acceptance:
|
||||||
|
pytest.skip("specify -A to run acceptance tests")
|
||||||
|
self.tmpdir = request.config.mktemp(request.function.__name__, numbered=True)
|
||||||
|
|
||||||
|
def run(self, cmd):
|
||||||
|
""" called by test code to execute an acceptance test. """
|
||||||
|
self.tmpdir.chdir()
|
||||||
|
return py.process.cmdexec(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
and the actual test function example:
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
def test_some_acceptance_aspect(accept):
|
||||||
|
accept.tmpdir.mkdir("somesub")
|
||||||
|
result = accept.run("ls -la")
|
||||||
|
assert "somesub" in result
|
||||||
|
|
||||||
|
If you run this test without specifying a command line option
|
||||||
|
the test will get skipped with an appropriate message. Otherwise
|
||||||
|
you can start to add convenience and test support methods
|
||||||
|
to your AcceptFuncarg and drive running of tools or
|
||||||
|
applications and provide ways to do assertions about
|
||||||
|
the output.
|
||||||
|
|
||||||
|
.. _`decorate a funcarg`:
|
||||||
|
|
||||||
|
example: decorating a funcarg in a test module
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
For larger scale setups it's sometimes useful to decorare
|
||||||
|
a funcarg just for a particular test module. We can
|
||||||
|
extend the `accept example`_ by putting this in our test module:
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
def pytest_funcarg__accept(request):
|
||||||
|
# call the next factory (living in our conftest.py)
|
||||||
|
arg = request.getfuncargvalue("accept")
|
||||||
|
# create a special layout in our tempdir
|
||||||
|
arg.tmpdir.mkdir("special")
|
||||||
|
return arg
|
||||||
|
|
||||||
|
class TestSpecialAcceptance:
|
||||||
|
def test_sometest(self, accept):
|
||||||
|
assert accept.tmpdir.join("special").check()
|
||||||
|
|
||||||
|
Our module level factory will be invoked first and it can
|
||||||
|
ask its request object to call the next factory and then
|
||||||
|
decorate its result. This mechanism allows us to stay
|
||||||
|
ignorant of how/where the function argument is provided -
|
||||||
|
in our example from a `conftest plugin`_.
|
||||||
|
|
||||||
|
sidenote: the temporary directory used here are instances of
|
||||||
|
the `py.path.local`_ class which provides many of the os.path
|
||||||
|
methods in a convenient way.
|
||||||
|
|
||||||
|
.. _`py.path.local`: ../path.html#local
|
||||||
|
.. _`conftest plugin`: customize.html#conftestplugin
|
|
@ -0,0 +1,170 @@
|
||||||
|
xdist: pytest distributed testing plugin
|
||||||
|
===============================================================
|
||||||
|
|
||||||
|
The `pytest-xdist`_ plugin extends py.test with some unique
|
||||||
|
test execution modes:
|
||||||
|
|
||||||
|
* Looponfail: run your tests repeatedly in a subprocess. After each run py.test
|
||||||
|
waits until a file in your project changes and then re-runs the previously
|
||||||
|
failing tests. This is repeated until all tests pass after which again
|
||||||
|
a full run is performed.
|
||||||
|
|
||||||
|
* multiprocess Load-balancing: if you have multiple CPUs or hosts you can use
|
||||||
|
those for a combined test run. This allows to speed up
|
||||||
|
development or to use special resources of remote machines.
|
||||||
|
|
||||||
|
* Multi-Platform coverage: you can specify different Python interpreters
|
||||||
|
or different platforms and run tests in parallel on all of them.
|
||||||
|
|
||||||
|
Before running tests remotely, ``py.test`` efficiently "rsyncs" your
|
||||||
|
program source code to the remote place. All test results
|
||||||
|
are reported back and displayed to your local terminal.
|
||||||
|
You may specify different Python versions and interpreters.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Install the plugin with::
|
||||||
|
|
||||||
|
easy_install pytest-xdist
|
||||||
|
|
||||||
|
# or
|
||||||
|
|
||||||
|
pip install pytest-xdist
|
||||||
|
|
||||||
|
or use the package in develope/in-place mode with
|
||||||
|
a checkout of the `pytest-xdist repository`_ ::
|
||||||
|
|
||||||
|
python setup.py develop
|
||||||
|
|
||||||
|
Usage examples
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Speed up test runs by sending tests to multiple CPUs
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
To send tests to multiple CPUs, type::
|
||||||
|
|
||||||
|
py.test -n NUM
|
||||||
|
|
||||||
|
Especially for longer running tests or tests requiring
|
||||||
|
a lot of IO this can lead to considerable speed ups.
|
||||||
|
|
||||||
|
|
||||||
|
Running tests in a Python subprocess
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
To instantiate a python2.4 sub process and send tests to it, you may type::
|
||||||
|
|
||||||
|
py.test -d --tx popen//python=python2.4
|
||||||
|
|
||||||
|
This will start a subprocess which is run with the "python2.4"
|
||||||
|
Python interpreter, found in your system binary lookup path.
|
||||||
|
|
||||||
|
If you prefix the --tx option value like this::
|
||||||
|
|
||||||
|
--tx 3*popen//python=python2.4
|
||||||
|
|
||||||
|
then three subprocesses would be created and tests
|
||||||
|
will be load-balanced across these three processes.
|
||||||
|
|
||||||
|
|
||||||
|
Sending tests to remote SSH accounts
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
Suppose you have a package ``mypkg`` which contains some
|
||||||
|
tests that you can successfully run locally. And you
|
||||||
|
have a ssh-reachable machine ``myhost``. Then
|
||||||
|
you can ad-hoc distribute your tests by typing::
|
||||||
|
|
||||||
|
py.test -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg
|
||||||
|
|
||||||
|
This will synchronize your ``mypkg`` package directory
|
||||||
|
to an remote ssh account and then locally collect tests
|
||||||
|
and send them to remote places for execution.
|
||||||
|
|
||||||
|
You can specify multiple ``--rsyncdir`` directories
|
||||||
|
to be sent to the remote side.
|
||||||
|
|
||||||
|
**NOTE:** For py.test to collect and send tests correctly
|
||||||
|
you not only need to make sure all code and tests
|
||||||
|
directories are rsynced, but that any test (sub) directory
|
||||||
|
also has an ``__init__.py`` file because internally
|
||||||
|
py.test references tests as a fully qualified python
|
||||||
|
module path. **You will otherwise get strange errors**
|
||||||
|
during setup of the remote side.
|
||||||
|
|
||||||
|
Sending tests to remote Socket Servers
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
Download the single-module `socketserver.py`_ Python program
|
||||||
|
and run it like this::
|
||||||
|
|
||||||
|
python socketserver.py
|
||||||
|
|
||||||
|
It will tell you that it starts listening on the default
|
||||||
|
port. You can now on your home machine specify this
|
||||||
|
new socket host with something like this::
|
||||||
|
|
||||||
|
py.test -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg
|
||||||
|
|
||||||
|
|
||||||
|
.. _`atonce`:
|
||||||
|
|
||||||
|
Running tests on many platforms at once
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
The basic command to run tests on multiple platforms is::
|
||||||
|
|
||||||
|
py.test --dist=each --tx=spec1 --tx=spec2
|
||||||
|
|
||||||
|
If you specify a windows host, an OSX host and a Linux
|
||||||
|
environment this command will send each tests to all
|
||||||
|
platforms - and report back failures from all platforms
|
||||||
|
at once. The specifications strings use the `xspec syntax`_.
|
||||||
|
|
||||||
|
.. _`xspec syntax`: http://codespeak.net/execnet/trunk/basics.html#xspec
|
||||||
|
|
||||||
|
.. _`socketserver.py`: http://bitbucket.org/hpk42/execnet/raw/2af991418160/execnet/script/socketserver.py
|
||||||
|
|
||||||
|
.. _`execnet`: http://codespeak.net/execnet
|
||||||
|
|
||||||
|
Specifying test exec environments in an ini file
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
pytest (since version 2.0) supports ini-style cofiguration.
|
||||||
|
You can for example make running with three subprocesses
|
||||||
|
your default like this::
|
||||||
|
|
||||||
|
[pytest]
|
||||||
|
addopts = -n3
|
||||||
|
|
||||||
|
You can also add default environments like this::
|
||||||
|
|
||||||
|
[pytest]
|
||||||
|
addopts = --tx ssh=myhost//python=python2.5 --tx ssh=myhost//python=python2.6
|
||||||
|
|
||||||
|
and then just type::
|
||||||
|
|
||||||
|
py.test --dist=each
|
||||||
|
|
||||||
|
to run tests in each of the environments.
|
||||||
|
|
||||||
|
Specifying "rsync" dirs in an ini-file
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
In a ``tox.ini`` or ``setup.cfg`` file in your root project directory
|
||||||
|
you may specify directories to include or to exclude in synchronisation::
|
||||||
|
|
||||||
|
[pytest]
|
||||||
|
rsyncdirs = . mypkg helperpkg
|
||||||
|
rsyncignore = .hg
|
||||||
|
|
||||||
|
These directory specifications are relative to the directory
|
||||||
|
where the configuration file was found.
|
||||||
|
|
||||||
|
.. _`pytest-xdist`: http://pypi.python.org/pypi/pytest-xdist
|
||||||
|
.. _`pytest-xdist repository`: http://bitbucket.org/hpk42/pytest-xdist
|
||||||
|
.. _`pytest`: http://pytest.org
|
||||||
|
|
Loading…
Reference in New Issue