diff --git a/doc/check_sphinx.py b/doc/check_sphinx.py new file mode 100644 index 000000000..0f536ffa6 --- /dev/null +++ b/doc/check_sphinx.py @@ -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)]) + + diff --git a/doc/example/attic.txt b/doc/example/attic.txt new file mode 100644 index 000000000..ef732d374 --- /dev/null +++ b/doc/example/attic.txt @@ -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 diff --git a/doc/xdist.txt b/doc/xdist.txt new file mode 100644 index 000000000..ecd1b0fd0 --- /dev/null +++ b/doc/xdist.txt @@ -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 +