Compare commits

...

559 Commits
1.0.2 ... 1.3.2

Author SHA1 Message Date
holger krekel
caf5bdbf89 re-add exclude pattern
--HG--
branch : trunk
2010-07-08 17:20:52 +02:00
holger krekel
6ea944a350 don't run too-long-filename test
--HG--
branch : trunk
2010-07-08 15:54:51 +02:00
holger krekel
9d47521cf0 finalizing docs
--HG--
branch : trunk
2010-07-08 15:28:54 +02:00
holger krekel
86440b1853 ship distribute_setup.py version 0.6.13
--HG--
branch : trunk
2010-07-08 13:40:19 +02:00
holger krekel
e98b15eb67 fix windows homedir detection
--HG--
branch : trunk
2010-07-08 12:35:43 +02:00
holger krekel
1ffe0e7b82 using improved versioing
--HG--
branch : trunk
2010-07-07 18:08:16 +02:00
holger krekel
3c069544fc bold summary line
--HG--
branch : trunk
2010-07-07 16:41:28 +02:00
holger krekel
4d4344212f fixing a doc reference, removing development dependency
--HG--
branch : trunk
2010-07-07 16:37:28 +02:00
holger krekel
eddd16d9fd progressing towards 1.3.2, adding announcement, regen docs
--HG--
branch : trunk
2010-07-07 15:41:28 +02:00
holger krekel
37a2898f18 reintroduce --junit - i think it is actually useful
--HG--
branch : trunk
2010-07-07 14:43:31 +02:00
holger krekel
af5e18e26c small fix
--HG--
branch : trunk
2010-07-07 13:07:34 +02:00
holger krekel
320835d43f split out pytest-xdist related reporting to the plugin
--HG--
branch : trunk
2010-07-07 12:41:15 +02:00
holger krekel
2664230fad fix test for python2.7
--HG--
branch : trunk
2010-07-06 13:29:32 +02:00
holger krekel
48d818742c adjust tox.ini
--HG--
branch : trunk
2010-07-06 12:04:22 +02:00
holger krekel
2b13836efa use the new sdistfile option
--HG--
branch : trunk
2010-07-05 18:40:49 +02:00
holger krekel
195d066ff8 skip sdist on hudson
--HG--
branch : trunk
2010-07-05 17:14:20 +02:00
holger krekel
1e8b59e39f updating tox.ini to new format
--HG--
branch : trunk
2010-07-05 15:55:21 +02:00
holger krekel
b28c439494 some minor compatibility issues wrt to the just released python2.7
--HG--
branch : trunk
2010-07-04 22:13:12 +02:00
holger krekel
223a04be27 fix doc env
--HG--
branch : trunk
2010-07-04 19:16:49 +02:00
holger krekel
3aefaff44f improve testing of docs
--HG--
branch : trunk
2010-07-04 18:25:22 +02:00
holger krekel
f9c5b00ffa refine and extend custom error reporting particularly for collection-related errors
--HG--
branch : trunk
2010-07-04 17:06:50 +02:00
holger krekel
e533e63bbf enable some more tests
--HG--
branch : trunk
2010-07-04 13:56:03 +02:00
holger krekel
be582b5f53 don't use dist-testing with jython to uncomplicate the testing matter
--HG--
branch : trunk
2010-07-03 14:54:48 +02:00
holger krekel
4a489af0ff remove the --junitxmlprefix feature - it's kind of YAGNI i guess -
i introduced it after 1.3.1 but don't need it anymore and thus
it's not going to be there for 1.3.2.

--HG--
branch : trunk
2010-07-03 14:44:47 +02:00
holger krekel
c19f51a3d7 refine header message
--HG--
branch : trunk
2010-07-03 14:35:27 +02:00
holger krekel
ca9b320c9c update again
--HG--
branch : trunk
2010-07-03 14:30:47 +02:00
holger krekel
ace2f975ea update tox.ini according to tox progress
--HG--
branch : trunk
2010-07-03 14:29:43 +02:00
holger krekel
e3250f4846 another correction
--HG--
branch : trunk
2010-07-02 15:33:36 +02:00
holger krekel
29217a47f4 updated tox.ini
--HG--
branch : trunk
2010-07-02 15:26:03 +02:00
holger krekel
5f9876d54e apply patch from Jakub wrt fixing resultlog/xdist combo
--HG--
branch : trunk
2010-07-02 13:01:21 +02:00
holger krekel
8c0dfb525d use the new envbindir subst
--HG--
branch : trunk
2010-07-02 10:15:30 +02:00
holger krekel
aa4308883c py.test-1.3.1 does not provide py.test proper for jython, only py.test-jython
(py.test-1.3.2 will provide py.test even for jython installs)

--HG--
branch : trunk
2010-07-01 19:54:28 +02:00
holger krekel
381b81b0e1 actually run only "testing" tests
--HG--
branch : trunk
2010-07-01 19:46:22 +02:00
holger krekel
7335c4d06d add jython env
--HG--
branch : trunk
2010-07-01 19:43:46 +02:00
holger krekel
f554fa03ae make initial conftest finding ignore "--" arguments
--HG--
branch : trunk
2010-07-01 19:27:40 +02:00
holger krekel
6fa58fd8c9 (ARGH) of windows/hudson/multi-config combo produces too long filenames, so use the global temp dir
--HG--
branch : trunk
2010-07-01 18:39:25 +02:00
holger krekel
c57a24774d use confcutdir
--HG--
branch : trunk
2010-07-01 18:12:38 +02:00
holger krekel
d51000b15d add a tox.ini file
--HG--
branch : trunk
2010-07-01 17:59:35 +02:00
holger krekel
b8db15a94f refine bestrelpath to return "." for X.bestrelpath(X) and refine its docstring
--HG--
branch : trunk
2010-06-28 16:32:43 +02:00
holger krekel
2f50ed3e99 install plain py.test script also for jython
--HG--
branch : trunk
2010-06-28 11:59:12 +02:00
holger krekel
da52304a6e adjust changelog, add fixed issue92
--HG--
branch : trunk
2010-06-28 11:26:19 +02:00
Benjamin Peterson
f8d3a80af5 name CollectOnlyReporter's output attribute "_tw" for consistency with TerminalReporter
This fixes #92.

--HG--
branch : trunk
2010-06-27 18:17:47 -05:00
Benjamin Peterson
df744e9182 merge heads
--HG--
branch : trunk
2010-06-25 12:25:44 -05:00
Benjamin Peterson
d82d65d95e remove uneeded exec
--HG--
branch : trunk
2010-06-25 12:24:51 -05:00
holger krekel
f856db29dc refine py.process.cmdexec handling wrt unicode on all python versions
--HG--
branch : trunk
2010-06-25 10:30:15 +02:00
Benjamin Peterson
4d75c703a0 correct expected message
--HG--
branch : trunk
2010-06-18 22:55:06 -05:00
holger krekel
3a8d13599e a fix from maciej who claims this fixes issues on some systems.
passes all tests so i just apply it.

--HG--
branch : trunk
2010-06-17 18:04:36 +02:00
holger krekel
504e42a62e remove tox.ini for now
--HG--
branch : trunk
2010-06-17 13:25:28 +02:00
holger krekel
149f9e1042 refine reporting with --pdb some more
--HG--
branch : trunk
2010-06-17 12:53:29 +02:00
holger krekel
3f1efe1b57 fix --pdb to not drop interactive on xfailed tests
--HG--
branch : trunk
2010-06-16 12:35:08 +02:00
holger krekel
72de7d94fd adding a link to Floris' new post
--HG--
branch : trunk
2010-06-14 15:45:31 +02:00
Benjamin Peterson
c3233b9c15 improve comment
--HG--
branch : trunk
2010-06-10 14:05:40 -05:00
Benjamin Peterson
2995d65720 fix assertion interpretation when the operator is **
--HG--
branch : trunk
2010-06-10 13:50:07 -05:00
holger krekel
77a7d576ec defer a number of other compiles to frame.eval (patch from Amaury on trunk/pypy fork, thanks)
--HG--
branch : trunk
2010-06-10 10:56:14 +02:00
holger krekel
3b30c5b67a defer compilation to frame.eval (pypy overrides frame.eval and has its own compilation
of source code to bytecode)

--HG--
branch : trunk
2010-06-10 09:53:40 +02:00
Benjamin Peterson
610cde6f85 Interpret assignments while examining asserts corrects
fixes #105

--HG--
branch : trunk
2010-06-09 14:53:11 -05:00
holger krekel
add518e6b6 use new --junitprefix option for tox reporting
--HG--
branch : trunk
2010-06-09 16:35:50 +02:00
holger krekel
bc6ead1a3c introduce a new --junitprefix option to influence xml reporting.
also internally avoid some redundant code.

--HG--
branch : trunk
2010-06-09 16:18:47 +02:00
holger krekel
0c04577f9f fix issue104 properly xml-escape names in junitxml files
--HG--
branch : trunk
2010-06-09 15:27:45 +02:00
holger krekel
523704f890 make py.test.raises as-VAR be an ExceptionInfo object
but only initialize it after the block is finished.

--HG--
branch : trunk
2010-06-09 14:45:41 +02:00
holger krekel
6951da7da0 merge Ronny's changes, add some documentation and changelog entries
--HG--
branch : trunk
2010-06-09 14:26:08 +02:00
holger krekel
d83bf93154 less imports at function level, add a CHANGELOG entry - i guess
there are not many win32/python2.4 users anymore these days.

--HG--
branch : trunk
2010-06-09 12:07:12 +02:00
holger krekel
4437ecb385 make terminal tests pass on win32/python2.4 and update tox.ini
--HG--
branch : trunk
2010-06-09 12:01:13 +02:00
Ronny Pfannschmidt
d1c8209875 support using py.test.raises in context manager style
--HG--
branch : trunk
2010-06-09 10:50:00 +02:00
holger krekel
6231bb0da3 capture a concrete idea for easing platform-specific testing.
--HG--
branch : trunk
2010-06-08 12:29:15 +02:00
holger krekel
64388832d9 introduce a new request.applymarker() function and refactor
internally to allow for dynamically adding keywords to test
items.

--HG--
branch : trunk
2010-06-08 02:34:51 +02:00
holger krekel
d00b62e0f4 fix tox.ini
--HG--
branch : trunk
2010-06-07 23:23:24 +02:00
holger krekel
804dcd3521 some adjustments to make py.test --basetemp=XYZ work where
XYZ is a subdir the checkout which contains a conftest.py

--HG--
branch : trunk
2010-06-07 21:02:26 +02:00
holger krekel
c1d0fc9aaf add ignore_errors to local.remove()
--HG--
branch : trunk
2010-06-07 20:48:36 +02:00
Ronny Pfannschmidt
8ece058256 remove py._path.gateway.* - its weird and unused
--HG--
branch : trunk
2010-06-07 15:13:28 +02:00
holger krekel
10b8de060a fix py.code.compile to generate unique filenames
--HG--
branch : trunk
2010-06-06 19:08:22 +02:00
holger krekel
10baa7f8af fix python3 failure by making a relative import work
--HG--
branch : trunk
2010-06-05 16:10:17 +02:00
holger krekel
740a668f52 adding a tox file and a note in changelog
--HG--
branch : trunk
2010-06-05 15:59:11 +02:00
holger krekel
c56f4f9444 don't depend on (and don't actually use anymore) testing/__init__.py
--HG--
branch : trunk
2010-06-04 00:39:58 +02:00
holger krekel
bdd1006e06 don't print empty lines with junitxml file printing
--HG--
branch : trunk
2010-06-04 00:39:18 +02:00
holger krekel
46f72d9350 add a CHANGELOG entry for ronny's changes
--HG--
branch : trunk
2010-06-03 15:51:59 +02:00
Ronny Pfannschmidt
f8404be1b2 add a rootdir param to py.path.local.mkdtemp
--HG--
branch : trunk
2010-06-03 11:14:32 +02:00
Ronny Pfannschmidt
2e82ca5fde use tempdir.mkdtmp instead of mktmp + repeated tries for making tmpdirs
--HG--
branch : trunk
2010-06-03 10:59:24 +02:00
Ronny Pfannschmidt
a07e494554 add kwarg support to py.errpr.checked_call
--HG--
branch : trunk
2010-06-03 10:21:48 +02:00
holger krekel
75d80ca183 fix pyimport() bug on directories
--HG--
branch : trunk
2010-05-31 17:06:46 +02:00
holger krekel
395bee4bc0 fix name of fedora package, thanks thm
--HG--
branch : trunk
2010-05-29 09:15:50 +02:00
holger krekel
b66b5e2715 fix issue 57 - make --looponfail work with xpassing tests
--HG--
branch : trunk
2010-05-26 18:55:50 +02:00
holger krekel
73d9900844 add Meme's pytest-cov plugin to the plugin index page
--HG--
branch : trunk
2010-05-26 14:48:27 +02:00
holger krekel
6cc89c9fcf Added tag 1.3.1 for changeset 8b8e7c25a13c
--HG--
branch : trunk
2010-05-25 21:09:21 +02:00
holger krekel
2e36e2619f update plugin docs, restructure release announcement a bit
--HG--
branch : trunk
2010-05-25 21:01:43 +02:00
holger krekel
3042d1442a Added tag 1.3.1 for changeset d5eacf390af7
--HG--
branch : trunk
2010-05-25 20:47:00 +02:00
holger krekel
312238c023 update release announcement
--HG--
branch : trunk
2010-05-25 20:46:51 +02:00
holger krekel
ff2b893d31 fix for py3 exception printing logic
--HG--
branch : trunk
2010-05-25 17:24:24 +02:00
holger krekel
c953c7d313 fix issue102 by introducing a --maxfailures=NUM option
also print an informative line about "stopped/interrupted" test runs
near the end.

--HG--
branch : trunk
2010-05-25 16:52:09 +02:00
holger krekel
fbcf9ec543 merge changes
--HG--
branch : trunk
2010-05-25 16:55:30 +02:00
holger krekel
9173b60677 internal test runs: do inline_run() without io-capturing
as this nested capturing can leave open FDs which breaks
larger test runs.  also introduce an internal option "--lsof"
for checking the number of file descriptors

--HG--
branch : trunk
2010-05-25 12:24:51 +02:00
holger krekel
7fc7b4307b adding xfail example
--HG--
branch : trunk
2010-05-22 17:22:31 +02:00
holger krekel
545aab85f2 py-1.3.1 release prep and version bumping
--HG--
branch : trunk
2010-05-22 17:11:30 +02:00
holger krekel
fa074da5a9 when --runxfail is supplied also show tracebacks when running a test that
calls py.test.xfail

--HG--
branch : trunk
2010-05-22 17:08:49 +02:00
holger krekel
29a5b7452e * improve and test --tb=short reporting
* show --tb=short tracebacks for importing test modules

--HG--
branch : trunk
2010-05-22 16:18:24 +02:00
holger krekel
94ce5b0a5a refine and structure CHANGELOG
--HG--
branch : trunk
2010-05-22 14:13:01 +02:00
holger krekel
93712a3ce6 terser reporting header
--HG--
branch : trunk
2010-05-22 13:59:01 +02:00
holger krekel
6f697294b2 fix for python3 - class.__dict__ is now a dict_proxy which doesn't have setdefault() anymore.
--HG--
branch : trunk
2010-05-22 10:12:57 +02:00
holger krekel
7cba3a07af update docs: mention that py.test.xfail is there
--HG--
branch : trunk
2010-05-21 18:16:16 +02:00
holger krekel
4f7ef0b63f fix issue89 - allow py.test.mark decorators to be used with classes
(if you are using >=python2.6)
also allow to have multiple markers applied at class level
and test and fix a bug with chained skip/xfail decorators:
if any of the conditions is true a test will be skipped/xfailed
with a explanation which condition evaluated to true.

--HG--
branch : trunk
2010-05-21 18:11:47 +02:00
holger krekel
67ec87e7f9 note that issue99 is also fixed
--HG--
branch : trunk
2010-05-21 16:51:15 +02:00
holger krekel
578cba20d4 fix issue94 make reporting more robust against bogus source code
(and internally be more careful when presenting unexpected byte sequences)
also make py.code.Source accept a list of lines directly.

--HG--
branch : trunk
2010-05-21 16:42:46 +02:00
holger krekel
93f91c9607 unify handling of reportcharacters across resultlog/junitxml plugins
--HG--
branch : trunk
2010-05-20 14:35:13 +02:00
holger krekel
925f75088d fix issue91 introduce new py.test.xfail(reason) helper
to imperatively mark a test as expected to fail. Can
be used from within setup and test functions. This is
useful especially for parametrized tests when certain
configurations are expected-to-fail.  In this case the
declarative approach with the @py.test.mark.xfail cannot
be used as it would mark all configurations as xfail.

--HG--
branch : trunk
2010-05-20 13:29:51 +02:00
holger krekel
eac0345689 fix wrong test invocation
--HG--
branch : trunk
2010-05-19 17:05:13 +02:00
holger krekel
20424a9c76 fix and test "-rP" option to show xpass-test ids
--HG--
branch : trunk
2010-05-19 16:52:03 +02:00
holger krekel
2229d2d947 revert 1735 - fix issue95 differently: just shift the offending zlib
import (and others) to happen when they are actually needed

--HG--
branch : trunk
2010-05-19 16:42:22 +02:00
holger krekel
c3bd29b490 fix issue95 - treat a failing pytest_genscript import
as non-critical, give a hint.

--HG--
branch : trunk
2010-05-19 16:22:23 +02:00
holger krekel
f552749de6 a crucial close() to prevent too-many-open-files
--HG--
branch : trunk
2010-05-18 21:25:20 +02:00
holger krekel
cf255cd643 some special handling of stdin capturing, unification, un-xfail the win32 test
--HG--
branch : trunk
2010-05-18 12:12:34 -07:00
holger krekel
10296faff1 for now don't test close(0) on windows - it hangs there
--HG--
branch : trunk
2010-05-18 11:43:22 -07:00
holger krekel
9f5e6f9761 simplify and unify FDCapture API and usage:
* FDCapture now takes care through the 'patchsys' option to
  also set sys.stdin/out/err - setfiles/unsetfiles methods removed -
  i doubt anybody uses this outside of py.test's own old usage.
* stdin also goes through FDCapture now.

--HG--
branch : trunk
2010-05-18 20:03:44 +02:00
holger krekel
c790288a5f fix issue98 - xdist documentation wrongly told to set pytest_option_X
where it is only option_X that is correct.

--HG--
branch : trunk
2010-05-18 18:45:12 +02:00
holger krekel
da097c9d67 deal gracefully with invalid file descriptors - don't capture the particular stream
--HG--
branch : trunk
2010-05-18 16:52:56 +02:00
holger krekel
4f5d7948f7 - try to fix the nightly failures by refining internal capturing mechanism
and adding tests, including a "lsof" test for making sure the number of
  open file descriptors does not increase.
- also move a py.io related logging test to testing/io

--HG--
branch : trunk
2010-05-18 16:01:58 +02:00
holger krekel
1a97c59439 fix test to account for earlier capfd skipping (on jython)
--HG--
branch : trunk
2010-05-18 09:54:04 +02:00
holger krekel
e71685736e fix issue96 - make capturing more resilient against KeyboardInterrupt
--HG--
branch : trunk
2010-05-17 19:00:39 +02:00
holger krekel
5876736890 tentative fix to py3's dependency on a filename->module->__loader__ chain
for executing inspect.findsource ...

--HG--
branch : trunk
2010-05-14 23:26:27 +02:00
holger krekel
f97e082543 fix test to work on jython and cpy
--HG--
branch : trunk
2010-05-14 15:25:24 +02:00
holger krekel
91880ffc19 adding three x-failing tests for issue88, issue93 and related issues
--HG--
branch : trunk
2010-05-14 12:02:43 +02:00
holger krekel
169d8d1e54 fix test to account for jython python file ending
--HG--
branch : trunk
2010-05-12 14:12:07 +02:00
holger krekel
11bf293972 merging again - seems i am using mercurial wrong or in some confused way ...
--HG--
branch : trunk
2010-05-12 14:14:05 +02:00
holger krekel
9cc6b602b9 remove duplicate and done issues
--HG--
branch : trunk
2010-05-12 11:23:31 +02:00
holger krekel
3d70917758 merge with issue-commits
--HG--
branch : trunk
2010-05-12 10:56:37 +02:00
holger krekel
0cebee2d24 bump version to 1.3.1a1 for now
--HG--
branch : trunk
2010-05-12 10:30:34 +02:00
holger krekel
379390a8aa remove code.new() function and store lines directly into linecache.cache instead.
This avoids the need for custom code objects, improving compatibility for jython
and pypy-c.

--HG--
branch : trunk
2010-05-11 22:54:04 +02:00
holger krekel
8ba2a98e11 allow to run py.test.cmdline.main() multiple times.
--HG--
branch : trunk
2010-05-11 19:56:22 +02:00
holger krekel
0f5ed3abc7 avoid helper functions showing up in py.test tracebacks
--HG--
branch : trunk
2010-05-11 17:43:56 +02:00
holger krekel
74b8fdf28a add an issue about py.test.config deprecation
--HG--
branch : trunk
2010-05-10 18:54:17 +02:00
holger krekel
f266c8f92f fix init-check to work also on pypy-c (armin around)
--HG--
branch : trunk
2010-05-09 12:27:04 +02:00
holger krekel
afdb928b12 update ISSUES
--HG--
branch : trunk
2010-05-09 08:43:28 +02:00
holger krekel
1706947edd fix some ReST issues
--HG--
branch : trunk
2010-05-05 22:04:53 +02:00
holger krekel
54afd26c7e fix typo
--HG--
branch : trunk
2010-05-05 21:53:36 +02:00
holger krekel
05ab5ad6d5 Added tag 1.3.0 for changeset eafd3c256e87
--HG--
branch : trunk
2010-05-05 21:35:24 +02:00
holger krekel
a127767da6 fix interpreter compat
--HG--
branch : trunk
2010-05-05 21:03:43 +02:00
holger krekel
a7d646c5e7 updating docs
--HG--
branch : trunk
2010-05-05 21:01:54 +02:00
holger krekel
87fcea7eb7 update release announcement
--HG--
branch : trunk
2010-05-05 20:19:02 +02:00
holger krekel
ee036223ce deprecate --report option in favour of a new shorter and easier to remember -r option: this takes a string argument consisting of any combination of 'xsfX'
Those letters basically correspond to the letters you see during terminal reporting.

--HG--
branch : trunk
2010-05-05 19:50:59 +02:00
holger krekel
325cb0aa49 add python3 classifier
--HG--
branch : trunk
2010-05-05 14:24:02 +02:00
holger krekel
c933ada7fb new --runxfail option to ignore xfail markers on functions
--HG--
branch : trunk
2010-05-04 13:02:27 +02:00
holger krekel
28150c7486 add unit-tests for xfail and refine xfail handling and reporting
--HG--
branch : trunk
2010-05-04 12:37:56 +02:00
holger krekel
dd7fd97810 add a terminalreporter.testid method
--HG--
branch : trunk
2010-05-04 12:37:52 +02:00
holger krekel
1a8b2838fa add new parameters:
xfail(run=False) will not run expected-to-fail tests
xfail(reason=True) will report the specified reason

--HG--
branch : trunk
2010-05-02 22:13:16 +02:00
holger krekel
82d4aae571 some internal fixes regarding the new required hook-finding prefix
--HG--
branch : trunk
2010-05-02 17:10:38 +02:00
holger krekel
fd473d4002 refine and test new hook registration, now it is called "pytest_addhooks"
similar to pytest_addoption and raises on bogus input.

--HG--
branch : trunk
2010-05-02 16:36:53 +02:00
holger krekel
45e10f4c48 rename pytest_ignore_collect_path to pytest_ignore_collect before release
--HG--
branch : trunk
2010-05-02 15:24:02 +02:00
holger krekel
3efb8028fb update changelog, install info and bum version to 1.3.0
rather than 1.2.2 because of the added features

--HG--
branch : trunk
2010-05-02 15:06:20 +02:00
holger krekel
b8247bc91e update implementation ISSUES, add one for session/refinements/a collection crash
--HG--
branch : trunk
2010-04-30 20:03:57 +02:00
holger krekel
2630a452b4 fixing and adding to CHANGELOG
--HG--
branch : trunk
2010-04-30 09:53:26 +02:00
Ronny Pfannschmidt
b3ce06bbf9 add close method to DontReadFromInput so multiprocessing can close it
--HG--
branch : trunk
2010-04-29 19:46:43 +02:00
holger krekel
962d0fe2be introduce new pytest_pycollect_makemodule(path, parent) hook for
allowing customization of the Module collection object for a matching test module.

--HG--
branch : trunk
2010-04-29 16:53:29 +02:00
holger krekel
811408959f introduce a new pytest_ignore_collect_path(path, config) hook -
returning a true value will prevent considering the path for collection
The hook is called for both files and directory paths.

--HG--
branch : trunk
2010-04-29 16:20:55 +02:00
holger krekel
25ed74a77a refine to allow more characters for instance reprs like it was before
--HG--
branch : trunk
2010-04-29 15:52:59 +02:00
holger krekel
5ece3858e4 introduce new py.io.saferepr for printing the 'repr' of an object safely
and without consuming too much space

--HG--
branch : trunk
2010-04-29 14:17:07 +02:00
holger krekel
1c1623885f fix a py3k related skip - py.io.TextIO on py3k should probably
not allow to write bytes to it.

--HG--
branch : trunk
2010-04-29 10:50:20 +02:00
holger krekel
5dc66bb4ca make py.io.ansi_print and py.io.get_terminal_width() directly available.
--HG--
branch : trunk
2010-04-29 10:49:50 +02:00
holger krekel
030548bc73 expose py.code._reinterpret functions so that pypy and internal
uses don't need to go through internal implementation imports

--HG--
branch : trunk
2010-04-29 01:20:56 +02:00
Benjamin Peterson
78d67c007b be more robust about bad std stream encodings
--HG--
branch : trunk
2010-04-28 17:19:49 -05:00
Benjamin Peterson
d93016d85f remove the unused return value of fnmatch_lines
--HG--
branch : trunk
2010-04-28 17:12:38 -05:00
Benjamin Peterson
f2be437daa some py3 encoding fixes
Also return True if fnmatch succeeds.

--HG--
branch : trunk
2010-04-28 16:51:36 -05:00
holger krekel
22a50a5b88 * various jython related fixes.
* more care for print-errors including unicode-encoding related errors.

--HG--
branch : trunk
2010-04-28 15:24:38 +02:00
holger krekel
37cdf17e0e fix some py3 issues, particularly for 3.1.2 which has truncate(0) not change the file position
so that a seek(0) is needed in addition.

--HG--
branch : trunk
2010-04-28 13:22:05 +02:00
holger krekel
78d33a2f28 * rather expose internal exceptions under py.test.ACTION.Exception
with ACTION being skip, fail, exit, raises.
* move and refine test_outcome.py tests into runner tests

--HG--
branch : trunk
2010-04-28 08:42:56 +02:00
holger krekel
d5e463605e * properly expose and document runtest-protocol related Exceptions
and move all definitions to the runner plugin for now.

* also move EXIT codes to session.py, obsoleting outcome.py alltogether.

--HG--
branch : trunk
2010-04-27 21:13:09 +02:00
holger krekel
0d0a7b7fec strike unused (buggy) keyword param
--HG--
branch : trunk
2010-04-27 17:53:07 +02:00
holger krekel
f691292aaa refining changelog + draft release announcement
--HG--
branch : trunk
2010-04-27 16:37:30 +02:00
holger krekel
ed7a2d2da3 refine/fix isimportable-logic and ensure that 'tmpdir' has a python-importable name
--HG--
branch : trunk
2010-04-27 16:10:25 +02:00
holger krekel
8131f5bdc0 (fixes issue83) don't try to import conftest from an invalid package path, refine path.pyimport() logic
--HG--
branch : trunk
2010-04-27 15:49:13 +02:00
holger krekel
c8d78177b9 (fixes issue85) correctly write non-ascii test output to junitxml files, refine some internal methods for it
--HG--
branch : trunk
2010-04-27 15:15:43 +02:00
holger krekel
f6a04b92d2 fix unicode issues (port of pypy/py repo changeset r72526 by Armin)
--HG--
branch : trunk
2010-04-27 12:23:13 +02:00
holger krekel
7084313408 factor out session main loop so that distribute testing can make use of it
--HG--
branch : trunk
2010-04-26 17:56:39 +02:00
Benjamin Peterson
7629b8fda7 make test source syntax valid
--HG--
branch : trunk
2010-04-23 20:49:00 -05:00
Benjamin Peterson
1771cb0af8 fetch code object compatibly
--HG--
branch : trunk
2010-04-23 20:43:49 -05:00
Benjamin Peterson
d1b45ef3d4 add a helper to get a function's code
--HG--
branch : trunk
2010-04-23 20:39:40 -05:00
Benjamin Peterson
f16d54f9a8 merge main
--HG--
branch : trunk
2010-04-23 20:28:32 -05:00
Benjamin Peterson
d909aead4e provide encoding to dupfile() for py3
--HG--
branch : trunk
2010-04-23 20:27:34 -05:00
holger krekel
0b24a70279 this should test and fix the same issue that was committed in
the pypy svn-repo as r72534

--HG--
branch : trunk
2010-04-23 19:28:41 +02:00
holger krekel
b3a05b545e another couple of checks on jython, still some problems
--HG--
branch : trunk
2010-04-23 19:05:22 +02:00
holger krekel
221ac3e466 a couple of more mostly jython-related fixes
--HG--
branch : trunk
2010-04-23 13:29:28 +02:00
holger krekel
2ee6653ff7 update distribute
--HG--
branch : trunk
2010-04-23 12:31:11 +02:00
hpk@tannit.openend.se
4337702a6a fixes for testrun on jython
--HG--
branch : trunk
2010-04-23 12:05:29 +02:00
holger krekel
ff90b1b4fb fix version numbers
--HG--
branch : trunk
2010-04-22 16:51:42 +02:00
holger krekel
85d35f7418 introduce an experimental approach for allowing dynamic addition of hooks from plugin. Plugins may register new hooks by implementing the new
pytest_registerhooks(pluginmanager)

and call

    pluginmanager.registerhooks(module)

with the referenced 'module' object containing the hooks.

The new pytest_registerhooks is called after pytest_addoption
and before pytest_configure.

--HG--
branch : trunk
2010-04-22 11:57:57 +02:00
holger krekel
cbb4c0dadc use taskkill cmdline for jython/win32 but skip test on jython because it does not return a subprocess PID
--HG--
branch : trunk
2010-04-21 06:23:19 -07:00
holger krekel
c10f0c2c36 merge in fixes
--HG--
branch : trunk
2010-04-21 14:49:38 +02:00
holger krekel
6e84b487ca robustify a check to not randomly fail
--HG--
branch : trunk
2010-04-21 14:47:44 +02:00
holger krekel
061f4c1515 robustify check
--HG--
branch : trunk
2010-04-21 14:46:41 +02:00
holger krekel
fe34a8a15a a couple of more fixes/refinements for getting py.test to run better on jython/win32
--HG--
branch : trunk
2010-04-21 03:50:03 -07:00
holger krekel
5715bbd6f5 refining the win32 checks some further
--HG--
branch : trunk
2010-04-20 20:08:52 +02:00
holger krekel
10f6c3a432 fix check to work when there is no jython
--HG--
branch : trunk
2010-04-20 10:48:49 -07:00
holger krekel
536252cb2e refine win32 checks to also work on top of jython/win32
--HG--
branch : trunk
2010-04-20 10:45:41 -07:00
holger krekel
7cd899fd3c add capturelog generated plugin text
--HG--
branch : trunk
2010-04-19 14:44:11 +02:00
holger krekel
e45cd7e35e fix issue86 - point to pytest-xdist plugin for looponfailing feature.
--HG--
branch : trunk
2010-04-14 15:05:39 +02:00
holger krekel
75a6bf2395 fix issue78 - strike superflous "import sys" that cause unbound
local var errors.

--HG--
branch : trunk
2010-04-14 13:30:12 +02:00
holger krekel
1d28dcf140 add links to new plugins
--HG--
branch : trunk
2010-04-12 16:08:12 +02:00
Benjamin Peterson
d994c51ccd actually skip doc tests if pygments is not available
--HG--
branch : trunk
2010-03-09 16:18:27 -06:00
Benjamin Peterson
fe95ad0aa6 fix typo
--HG--
branch : trunk
2010-03-03 15:54:39 -06:00
holger krekel
c75d0faa6f remove cover and xmlresult plugins as they are not easily installable
and lead to frustration (thanks again to prologic for getting back on it)

--HG--
branch : trunk
2010-02-10 16:11:19 +01:00
holger krekel
3608d722fa fix docs to not point to a downloadable plugin if the
plugin is external (thanks to prologic for feedbacking
on this confusion)

--HG--
branch : trunk
2010-02-10 14:21:49 +01:00
holger krekel
18b5ddc4dd note down two issues after having helped prologic - also related to
earlier discussions with ronny and others.

--HG--
branch : trunk
2010-02-09 18:32:17 +01:00
holger krekel
a2fbe31a26 Added tag 1.2.1 for changeset c143a8c8840a
--HG--
branch : trunk
2010-02-08 17:39:55 +01:00
holger krekel
222a08ec03 going for the 1.2.1 release
--HG--
branch : trunk
2010-02-08 16:39:29 +01:00
holger krekel
c7326f1949 fix a pdb problem when dropping to a "raises" related failure
--HG--
branch : trunk
2010-02-08 14:17:01 +01:00
holger krekel
3bca6be46d add some issues
--HG--
branch : trunk
2010-02-07 02:55:50 +01:00
holger krekel
13488dd540 if a funcarg is misspelled/missing, hint at using "--funcargs"
--HG--
branch : trunk
2010-02-07 02:15:47 +01:00
holger krekel
ac1eed545c nice-ify --funcarg reporting, show paths instead of useless python reprs
--HG--
branch : trunk
2010-02-07 02:09:14 +01:00
holger krekel
e09e7148a3 fix docstring
--HG--
branch : trunk
2010-02-07 01:56:43 +01:00
holger krekel
d163d92b33 actually look into all non-dot subdirs for conftest.py files - recursive walk would be too heavy for large source trees but first-level subdirs are fine IMO. Note that prior to py.test 1.0 doing this "look-ahead" was not easily doable because it was hard to avoid global state in conftest.py, this is not true anymore - so i feel ok telling people to cleanup their conftest files if they get problems (you can imagine people doing all kinds of things at global conftest.py module scope, can't you?)
--HG--
branch : trunk
2010-02-06 22:37:04 +01:00
holger krekel
105ed6dcaa fix this test
--HG--
branch : trunk
2010-02-05 22:57:46 +01:00
holger krekel
a3d15b2c60 refined usage and options for "py.cleanup":
py.cleanup     # remove "*.pyc" and "*$py.class" (jython) files
    py.cleanup -e .swp -e .cache # also remove files with these extensions
    py.cleanup -s  # remove "build" and "dist" directory next to setup.py files
    py.cleanup -d  # also remove empty directories
    py.cleanup -a  # synonym for "-s -d -e 'pip-log.txt'"
    py.cleanup -n  # dry run, only show what would be removed

--HG--
branch : trunk
2010-02-05 22:50:41 +01:00
holger krekel
3234e6e978 add a --funcargs option showing available funcargs
--HG--
branch : trunk
2010-02-04 23:45:07 +01:00
holger krekel
02c129df7a fix a test
--HG--
branch : trunk
2010-02-04 16:13:30 +01:00
holger krekel
f95877a09b show a short and nice traceback for funcarg lookup errors
--HG--
branch : trunk
2010-02-04 16:01:02 +01:00
holger krekel
7bd60b5abb check and load test*/conftest.py early from anchors -
this makes it a bit more convenient to have command line options
available from a root directory of a project that does not
directly contain a conftest.py

--HG--
branch : trunk
2010-02-04 12:26:53 +01:00
holger krekel
33d78f41b2 fix title to not mention distributed programming which
is separated out into execnet.

--HG--
branch : trunk
2010-02-02 11:32:21 +01:00
holger krekel
9d64d7e27a refine setup ordering some more - test and avoid a problem with funcarg setups where the
surrounding setup_module would fail, but the funcarg setup still be called (which might
assume that setup_module has been called so would raise a confusing error)

--HG--
branch : trunk
2010-01-28 15:36:27 +01:00
holger krekel
a2af204687 again addresses issue78 : we now call teardown also if setup raised a Skipped exception.
I also made sure, setup_module/class will only be called once - before they'd be call again
and again if they raise an error or a skip - for each test in their scope.

--HG--
branch : trunk
2010-01-28 14:20:58 +01:00
holger krekel
4d5ea7be43 install pygments for tests
--HG--
branch : trunk
2010-01-27 13:02:02 +01:00
holger krekel
98608611af closes #67 new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
--HG--
branch : trunk
2010-01-27 12:52:19 +01:00
holger krekel
b18ab6e03b fix issue78 - now python-level teardown functions are now called even if the setup failed.
Important detail: if the setup raises a Skipped exception, teardown will not be called.  This helps
to avoid breaking setup_module/class that performs a skip - it would otherwise internally
be considered as a "successful" setup in order to have teardown called later.  I guess
it also makes sense to treat Skip specially because it is unlikely a teardown should be
called if a Skip was raised on setup.

In any case, failing setups and teardowns will be reported separately.

--HG--
branch : trunk
2010-01-27 12:09:30 +01:00
holger krekel
17bd875444 fail doc generation if pygments is not installed
--HG--
branch : trunk
2010-01-21 23:24:33 +01:00
holger krekel
aa6d2a37e6 upgrade apipkg.py to fix a potential recursive import issue
--HG--
branch : trunk
2010-01-21 20:06:50 +01:00
holger krekel
14feeb9ca1 fix doc links, bump to dev version
--HG--
branch : trunk
2010-01-21 19:34:42 +01:00
holger krekel
f7c562e492 better default for bogus terminal getdimensions() call, fixes issue63
--HG--
branch : trunk
2010-01-19 10:34:41 +01:00
holger krekel
53fc3204fb Added tag 1.2.0 for changeset 4fc5212f7626
--HG--
branch : trunk
2010-01-18 17:04:52 +01:00
holger krekel
6756416d69 add report_header_info to release announce
and remove some ignores/excludes from MANIFEST.in for
a less verbose installation experience

--HG--
branch : trunk
2010-01-18 17:00:22 +01:00
holger krekel
d3c0ff3a1f make sure we get an absolute path when writing the genscript file
--HG--
branch : trunk
2010-01-18 16:48:20 +01:00
holger krekel
30b756a1a2 add terminal plugin to overview page again
--HG--
branch : trunk
2010-01-18 16:26:26 +01:00
holger krekel
49f7972d48 some finalizing docs bit, regen plugin docs
--HG--
branch : trunk
2010-01-18 16:18:59 +01:00
holger krekel
1e76202b65 turn this into a black-box test
--HG--
branch : trunk
2010-01-18 13:16:58 +01:00
holger krekel
55fcc5a219 always directly use basename for tracebacks, independently from code.path
fixes issue77 although i guess it was already fixed before.

--HG--
branch : trunk
2010-01-18 12:12:18 +01:00
holger krekel
866255e1f5 pushing towards 1.2.0
--HG--
branch : trunk
2010-01-18 11:19:59 +01:00
holger krekel
0149771997 refine excludepath handling to treat entries with no path as matching
--HG--
branch : trunk
2010-01-18 03:04:20 +01:00
holger krekel
89068d9471 fix python2.4 issue
--HG--
branch : trunk
2010-01-18 02:01:16 +01:00
holger krekel
d483f18374 move rsync reporting out
--HG--
branch : trunk
2010-01-18 00:41:22 +01:00
holger krekel
95de17b652 refine tests and refine code to deal with new xdist semantics.
--HG--
branch : trunk
2010-01-17 23:23:02 +01:00
holger krekel
f5e9d91f7b fix deprecation warnings
--HG--
branch : trunk
2010-01-17 10:54:36 +01:00
holger krekel
09671eb6fc rename logxml plugin to junitxml
--HG--
branch : trunk
2010-01-16 23:33:26 +01:00
holger krekel
6f0db1d193 kill unused code
--HG--
branch : trunk
2010-01-16 19:41:05 +01:00
holger krekel
76e49b57bf fix test_importall to not stop on skipped plugins and fix the uncovered failure of genscript: standalone.py template is now safely importable
--HG--
branch : trunk
2010-01-15 18:45:06 +01:00
holger krekel
4a568f43fe get rid of the funccollector node, which nice-ifies names of funcarg-generated tests nodes, also test and fix one anomaly wrt to funcarg setups and instance uniqueness
--HG--
branch : trunk
2010-01-15 17:50:02 +01:00
holger krekel
ee2f292efa remove superflous building of a dict, preserve order for nodes that have identical file:lineno
--HG--
branch : trunk
2010-01-15 17:38:09 +01:00
holger krekel
1ff37207a2 another wish
--HG--
branch : trunk
2010-01-13 18:20:38 +01:00
holger krekel
7747655905 some issue soritng related to the 1.2 series
--HG--
branch : trunk
2010-01-13 18:17:24 +01:00
holger krekel
030986dcc4 reduce usage of the global py.test.config which maybe should die or become less global at some point (along with py.test.ensuretemp)
--HG--
branch : trunk
2010-01-13 18:04:58 +01:00
holger krekel
9da1ba40ed move down py/impl/XYZ to py/_XYZ
--HG--
branch : trunk
2010-01-13 17:15:54 +01:00
holger krekel
5c27076d32 flatten test directory hierarchy and merge smaller into larger files
--HG--
branch : trunk
2010-01-13 16:17:50 +01:00
holger krekel
40f41496d8 remove dist-testing and looponfail code from core. there remain some (pytest_runner particularly) tests that test both plain and dist modes which cannot be easily dis-entangled. food for thought.
--HG--
branch : trunk
2010-01-13 16:00:33 +01:00
holger krekel
d4f5073076 remove figleaf which now lives "outside"
--HG--
branch : trunk
2010-01-13 00:47:20 +01:00
holger krekel
59f3adb46b fix reqs2 to point to released execnet
--HG--
branch : trunk
2010-01-12 21:57:26 +01:00
holger krekel
d53572a710 introduce a new pytest_report_header(hook) hook to add additional test-run relevant information to the header of a test report.
--HG--
branch : trunk
2010-01-12 21:43:25 +01:00
Ronny Pfannschmidt
676081b87a remove the PickleChannel dependency for looponfail
--HG--
branch : trunk
2010-01-12 17:35:06 +01:00
holger krekel
a9fe84d9b9 adding a second requirements file which uses execnet-1.0.2
--HG--
branch : trunk
2010-01-12 16:15:07 +01:00
holger krekel
1b0d6296dd test and fix looponfailing wrt to a bug introduced with the cmdline/session startup cleanup.
--HG--
branch : trunk
2010-01-12 16:08:48 +01:00
holger krekel
8d9e0712be refine classname normalization for junit-xml
--HG--
branch : trunk
2010-01-12 01:35:50 +01:00
holger krekel
3296939eda fix sessionstart/sessionfinish handling at the slave side, set "session.nodeid" to id of the slave and make sure "final" teardown failures are reported nicely. fixes issue66.
--HG--
branch : trunk
2010-01-11 17:09:07 +01:00
holger krekel
b6909e61a0 fix rest syntax error (thanks fijal)
--HG--
branch : trunk
2010-01-11 14:33:18 +01:00
holger krekel
ba1451330e refine rsyncing and internal dir/transferal handling: don't transfer roots in a popen- no-chdir situation and only use one py._pydir everywhere
--HG--
branch : trunk
2010-01-11 14:30:50 +01:00
holger krekel
352e305431 fix and test bug: dist-testing now works again without execnet/pylib installed remotely. fixes issue65.
--HG--
branch : trunk
2010-01-10 23:52:23 +01:00
holger krekel
3a23baf484 add to changelog, remove docstring
--HG--
branch : trunk
2010-01-10 22:10:45 +01:00
holger krekel
99301a0dae (experimental) allow cmdline arguments to deep-point to a test, also remove virtually redundant session.getinitialitems() calls
--HG--
branch : trunk
2010-01-10 21:29:36 +01:00
holger krekel
3029aa6558 fix some "import py" test issues, and prevent "genscript" script from having dist-options
--HG--
branch : trunk
2010-01-10 20:45:37 +01:00
holger krekel
45c1517580 porting latest apipkg
--HG--
branch : trunk
2010-01-10 13:54:55 +01:00
holger krekel
3239bd250b avoid dependency on directory ordering
--HG--
branch : trunk
2010-01-03 18:19:52 +01:00
holger krekel
ff5c1b6611 add potential feature from py-dev discussion
--HG--
branch : trunk
2010-01-03 14:52:26 +01:00
holger krekel
018254a907 update issues, version numbers
--HG--
branch : trunk
2010-01-03 14:33:10 +01:00
holger krekel
9fcd108091 relax a test to pass on jython and fix install docs to include genscript standalone usage.
--HG--
branch : trunk
2010-01-03 14:19:31 +01:00
holger krekel
27aa14c20f fix python3 issues, add missing plugin docs
--HG--
branch : trunk
2010-01-03 13:27:06 +01:00
holger krekel
d541713dca re-arrange "py.test -h" command line option grouping and update some plugin docs.
--HG--
branch : trunk
2010-01-03 12:41:29 +01:00
holger krekel
0b2d9a5520 bumping version number: 1.2.0a1
--HG--
branch : trunk
2010-01-03 11:42:26 +01:00
holger krekel
c6c7d041b7 disable default inclusion of figleaf plugin because it caused test
failures wrt to capturing/logging interaction.  pytest_figleaf should
anyway better become its own externally living plugin.

--HG--
branch : trunk
2010-01-03 11:22:32 +01:00
holger krekel
1b34492108 vastly simplify and cleanup collection initialization by internally
introducing a RootCollector. Note that the internal node
methods _fromtrail and _totrail are shifted to the still internal
config._rootcol.fromtrail/totrail

--HG--
branch : trunk
2010-01-03 01:02:44 +01:00
holger krekel
eebeb1b257 enable doctest plugin by default, add a --doctest-glob option and some documentation, regen plugin docs.
--HG--
branch : trunk
2010-01-02 23:30:46 +01:00
holger krekel
56a936993c enhance figleaf setup, enabled by default now (requires --figleaf). Generalize internal ability to show "hints" at the end of "-h".
--HG--
branch : trunk
2010-01-02 22:48:53 +01:00
holger krekel
1b6391d814 higher timeout to accomodate slower execution environments
--HG--
branch : trunk
2010-01-02 18:32:11 +01:00
holger krekel
f3e62e38aa streamlined plugin loading: order is now setuptools, ENV, commandline
and setuptools entry point names are turned to canonical namees ("pytest_*")

--HG--
branch : trunk
2010-01-02 17:17:13 +01:00
holger krekel
a20e60aeae slightly refine invocation of py.test: use the py lib that we got invoked with,
does away with the need to not-chdir some tests

--HG--
branch : trunk
2010-01-02 11:57:42 +01:00
holger krekel
fd76cd8f41 remove/refine some doc strings. create popen-files with absolute paths.
--HG--
branch : trunk
2010-01-01 23:05:00 +01:00
holger krekel
e0dd171e45 fix standalone script generation on windows, make tests not do a chdir() so that distributed testing discovers the transferred lib
--HG--
branch : trunk
2010-01-01 21:54:27 +01:00
holger krekel
47df1e16b6 fix some failures introduced by the last commit, document new "pytestconfig" funcarg
--HG--
branch : trunk
2010-01-01 21:03:33 +01:00
holger krekel
f8b5951103 run py.* tools through "-c import py ; py.cmdline.py*" by default
and introduce --tools-on-path to force discovery of tools from PATH

--HG--
branch : trunk
2010-01-01 20:36:58 +01:00
holger krekel
b62978a88f internal: always use scripts found in the environment
--HG--
branch : trunk
2009-12-31 16:15:11 +01:00
holger krekel
2752168a58 introduce --confcutdir option to early-inhibit lookup of conftest files above a certain directory.
--HG--
branch : trunk
2009-12-31 15:10:32 +01:00
holger krekel
eb4249322e fix xml generation for skipped collections of tests
--HG--
branch : trunk
2009-12-31 11:50:01 +01:00
holger krekel
9fa6ca885a fixing invocation
--HG--
branch : trunk
2009-12-31 11:33:27 +01:00
holger krekel
587951966f adding a logxml plugin and a --xml=path option generating a junit-xml style result log. The xml result log can be parsed nicely by hudson.
Initial code was based on Ross Lawley's pytest_xmlresult plugin.

--HG--
branch : trunk
2009-12-31 11:25:07 +01:00
holger krekel
fa0c7b18bf move standalone script to become a plugin offering "--genscript",
adjust paths accordingly and add CHANGELOG entry.

--HG--
branch : trunk
2009-12-30 19:10:49 +01:00
Ralf Schmitt
1103f2ad62 make inspect.getsource work for standalone py.test by implementing a get_source method on our DictImporter.
--HG--
branch : trunk
2009-12-30 19:01:46 +01:00
holger krekel
a42d9eb9f6 fix some standalone-script running issues:
* standalone can run standalone tests
* exception handling is more careful with assuming valid filenames
* bits here and there

--HG--
branch : trunk
2009-12-30 18:11:00 +01:00
holger krekel
6495007aba refine tests to cache single-script and make standalone work with distributed testing.
--HG--
branch : trunk
2009-12-30 17:40:50 +01:00
holger krekel
94bc770786 fix accidentally broken pylib's own conftest.py
--HG--
branch : trunk
2009-12-30 17:11:48 +01:00
holger krekel
77667c11d2 a first go at testing schmir's generate_standalone_pytest script and
making it work on python2.4-3.1 + jython.

--HG--
branch : trunk
2009-12-30 17:08:45 +01:00
holger krekel
f5ea19858c deprecate direct definition of Directory, Module, ... in conftest.py's,
add some pytest collect related tests + some refinements.

--HG--
branch : trunk
2009-12-30 16:18:59 +01:00
holger krekel
d3b20e8d24 refine deprecations, move some over to test_deprecated_api
--HG--
branch : trunk
2009-12-30 14:07:20 +01:00
holger krekel
30bbf3b042 fix aimed at passing jstests functional tests: allow to have _fillfuncargs() called even for non-pycollect-object test-items.
--HG--
branch : trunk
2009-12-30 14:05:41 +01:00
holger krekel
89f178bf4d streamline svn test setup a bit, clear caches on setup-restore, hopefully will erase random failures with test_export.
--HG--
branch : trunk
2009-12-30 13:05:08 +01:00
holger krekel
4656bc4c97 deprecate use of 'disabled'
--HG--
branch : trunk
2009-12-30 12:13:38 +01:00
holger krekel
f02b84d528 update ISSUES some more, introduce duration to RunResult and a failing dist-testing termination test.
--HG--
branch : trunk
2009-12-30 11:37:46 +01:00
holger krekel
a15afb5e48 skip tests using 'capfd' funcarg but not having os.dup. cleanup issues and regen plugin docs.
--HG--
branch : trunk
2009-12-30 11:16:20 +01:00
holger krekel
ae63605ac0 generalize hook calling from collection nodes but stop short
of allowing general hooks in python test modules. It'd be
easily possible (a 1-line change) but considering it i refrained
from it because the collector API is a bit too low level.

pytest_generate_tests and funcarg factories have a limited
directly useful interface and are thus less confusing - those
are taking advantage of hook discovery in python test modules.

--HG--
branch : trunk
2009-12-30 10:42:01 +01:00
holger krekel
631dfe9f13 only consider matching conftest plugins for discovering hooks related to collection nodes.
--HG--
branch : trunk
2009-12-30 02:36:58 +01:00
holger krekel
9d01975c78 fix capturing to be more careful during teardown when a setup never happened (due to e.g. an error in user-provided runtest_setup code)
--HG--
branch : trunk
2009-12-30 00:11:27 +01:00
holger krekel
77b640d1b7 streamline some tests and overall reduce py.test.ensuretemp usage, note down issue about deprecation .
--HG--
branch : trunk
2009-12-29 22:26:03 +01:00
holger krekel
9be7d78fb1 some debug info aimed at helping to find out about a randomly failing test_export
test setup issue

--HG--
branch : trunk
2009-12-29 21:18:17 +01:00
holger krekel
c348cec481 make looponfailing a bit more robust against relative imports and changed directories - needs more work, probably.
--HG--
branch : trunk
2009-12-29 18:41:24 +01:00
holger krekel
79af98fc29 some testing hygene: move _reparse testing functionality to actual test support code, un-xfail a now passing test, reduce direct py.test.config usage aiming for deprecation.
--HG--
branch : trunk
2009-12-29 18:02:54 +01:00
holger krekel
7780e74016 fixup funcargs docs
--HG--
branch : trunk
2009-12-29 16:57:56 +01:00
holger krekel
db21cac694 cleanup py.test.* namespace, docstrings for improved pydoc and interactive usage.
use new apipkg __onfirstaccess__ feature to initialize the py.test namespace with the default plugins.  This, besides other good implications, means that you can now type:  pydoc py.test   or help(py.test)

--HG--
branch : trunk
2009-12-29 16:29:48 +01:00
holger krekel
080fd2880e simplify Config initialization
--HG--
branch : trunk
2009-12-29 14:13:12 +01:00
holger krekel
71e332c9c4 robustiy some randomly failing tests
--HG--
branch : trunk
2009-12-29 12:36:45 +01:00
holger krekel
425e4849f3 remove/reduce internal global state: py._com.registry is now fully contained and always instantiated from the py.test PluginManager class.
--HG--
branch : trunk
2009-12-29 12:36:17 +01:00
holger krekel
8737254a74 simplify pluginmanager, move plugin validation code to plugin, remove unused code
--HG--
branch : trunk
2009-12-29 10:59:01 +01:00
holger krekel
0361b73d75 remove defaultconfest.py and make PluginManager directly do early initialization of default plugins.
--HG--
branch : trunk
2009-12-29 10:26:51 +01:00
holger krekel
27bcd2dbda always import defaultconftest by python import path. strike some redundant code.
--HG--
branch : trunk
2009-12-28 17:49:46 +01:00
Ralf Schmitt
cc82f1601c add script to generate standalone py.test
--HG--
branch : trunk
2009-12-27 23:03:04 +01:00
holger krekel
9239d2dd06 another fix for windows
--HG--
branch : trunk
2009-12-25 02:16:29 -08:00
holger krekel
0bfd3819c8 fix typo
--HG--
branch : trunk
2009-12-25 10:56:03 +01:00
holger krekel
abb05d9384 fixing windows32 svn-testing issues
--HG--
branch : trunk
2009-12-25 01:47:43 -08:00
holger krekel
516cee2a94 windows fixes and print funcargs for keyboardinterrupt traces
--HG--
branch : trunk
2009-12-25 09:53:36 +01:00
holger krekel
d28838bbb6 try to fix windows path issue
--HG--
branch : trunk
2009-12-25 00:31:51 +01:00
holger krekel
88e61467f1 fixing and cleaning up some tests
--HG--
branch : trunk
2009-12-25 00:24:58 +01:00
holger krekel
6d46efa87a introduce --ignore option to ignore paths during collection
--HG--
branch : trunk
2009-12-24 22:23:45 +01:00
holger krekel
cd96e52144 temporarily adding files for playing with hudson
--HG--
branch : trunk
2009-12-24 21:47:01 +01:00
holger krekel
7864f6a4fd rather use newest execnet always
--HG--
branch : trunk
2009-12-24 20:35:18 +01:00
holger krekel
51a684f488 adding pip requirements file
--HG--
branch : trunk
2009-12-24 20:22:19 +01:00
holger krekel
f254b6f7c1 fixes to various tests, related to execnet automatic ID generation and other bits.
also lowering the version as "1.1.1post1" for now.  1.1.2 is still a bit off.

--HG--
branch : trunk
2009-12-24 19:43:14 +01:00
Benjamin Peterson
98863d1d01 capitialize I
--HG--
branch : trunk
2009-12-24 09:06:23 -06:00
holger krekel
8a5c3c0c69 cleanup bin-script creation, fix docs, add FAQ entry about py.test --version
--HG--
branch : trunk
2009-12-24 12:27:15 +01:00
holger krekel
1580b2c8da create version/interpreter differentiated py.test$VER for cpython, jython, pypy-c's, prepare 1.1.2 release
--HG--
branch : trunk
2009-12-23 19:58:52 +01:00
holger krekel
4b1db63b35 add some issues
--HG--
branch : trunk
2009-12-20 22:11:36 +01:00
holger krekel
ee1064b13c adding a link to the tutorial page
--HG--
branch : trunk
2009-12-20 22:10:44 +01:00
holger krekel
2ca39443a3 some doc fixes
--HG--
branch : trunk
2009-12-17 09:33:41 +01:00
holger krekel
7637a6ecda fix links, partially thanks to fijal
--HG--
branch : trunk
2009-12-11 14:19:18 +01:00
holger krekel
15ed79cb08 add note related to issue64
--HG--
branch : trunk
2009-12-08 00:06:50 +01:00
holger krekel
1f45edf121 note down dist-testing/execnet issue
--HG--
branch : trunk
2009-12-07 23:54:22 +01:00
holger krekel
213c9fa119 another issue
--HG--
branch : trunk
2009-12-07 13:27:24 +01:00
holger krekel
b44e04f28d adding a warning note, see also issue64.
--HG--
branch : trunk
2009-12-07 10:23:04 +01:00
holger krekel
f93c7e0cc4 update some small issues
--HG--
branch : trunk
2009-12-06 19:18:53 +01:00
holger krekel
90306e0089 skip tests properly
--HG--
branch : trunk
2009-12-06 19:18:44 +01:00
Benjamin Peterson
ec96ab5286 2.7's TextIO requires unicode
--HG--
branch : trunk
2009-12-06 11:47:41 -06:00
holger krekel
56c1391a16 fix keyword calling
--HG--
branch : trunk
2009-11-27 20:32:21 +01:00
holger krekel
bb755ae009 starting an ISSUES.txt with a conftest issue
--HG--
branch : trunk
2009-11-25 19:50:39 +01:00
holger krekel
31bba4e087 Added tag 1.1.1 for changeset 319187fcda66
--HG--
branch : trunk
2009-11-24 18:02:02 +01:00
holger krekel
9d5b313aad adjustments and fixes to test run, distribution files. thanks thm.
--HG--
branch : trunk
2009-11-24 15:16:58 +01:00
holger krekel
8c6593cc08 by default flush log writes to files
--HG--
branch : trunk
2009-11-24 02:48:13 -08:00
holger krekel
9652be0ac1 don't consider setuptools plugins if it is not installed.
--HG--
branch : trunk
2009-11-24 10:49:04 +01:00
holger krekel
79a9a99d1e small refinements/precision regarding execnet checks
--HG--
branch : trunk
2009-11-23 17:25:46 +01:00
holger krekel
ed03eef81b introduce plugin discovery through setuptools "pytest11" entrypoints
and refine execnet dependency handling.  Prepare 1.1 release

--HG--
branch : trunk
2009-11-23 17:20:36 +01:00
holger krekel
0e03ae1ee8 some forgotten doc fixes
--HG--
branch : trunk
2009-11-23 12:23:40 +01:00
holger krekel
8292ff7d0f fixing docs, adding draft announcement
--HG--
branch : trunk
2009-11-20 10:17:49 +01:00
holger krekel
bcede77e45 fix a flaky test
--HG--
branch : trunk
2009-11-20 10:04:40 +01:00
holger krekel
ecb19b751a add % as allowed char, condense CHANGELOG
--HG--
branch : trunk
2009-11-20 09:19:29 +01:00
holger krekel
d1dcf0fa92 be a bit more helpful by default regarding --report settings
--HG--
branch : trunk
2009-11-20 09:11:04 +01:00
holger krekel
0060869e79 move CHANGELOG back to root level, add entries
--HG--
branch : trunk
2009-11-20 00:12:39 +01:00
holger krekel
452ce50d7d fix compatibility issue with svnwc.update and put CHANGELOG to rootlevel
--HG--
branch : trunk
2009-11-20 00:12:06 +01:00
holger krekel
6d9e3ac686 adapt to new execnet.Group code (since execnet-1.0.0b4), strike superflous code
--HG--
branch : trunk
2009-11-19 23:13:29 +01:00
holger krekel
3adf6687c9 reintroduce py.test.cmdline.main() (alias for py.cmdline.pytest())
resolves issue #61

--HG--
branch : trunk
2009-11-19 23:13:28 +01:00
holger krekel
41a572ee1e a bit of padding under the logo
--HG--
branch : trunk
2009-11-17 13:45:27 +01:00
holger krekel
1a86d09da4 a few internal test related fixes as to run on a osx/no-execnet situation
--HG--
branch : trunk
2009-11-12 21:15:59 +01:00
holger krekel
f4ec2d1ecd improve deprecation, start changelog
--HG--
branch : trunk
2009-11-12 13:10:30 +01:00
holger krekel
a4a652af85 fix a bug with svnwc.listdir() not accepting a checker(versioned=...)
--HG--
branch : trunk
2009-11-12 13:09:27 +01:00
holger krekel
e6f2258409 Added tag 1.1.0 for changeset 60c44bdbf093
--HG--
branch : trunk
2009-11-05 17:51:35 +01:00
holger krekel
e0bca8fe51 fix up install docs and plugin docs for the final release
have CHANGELOG be a file containing links instead of a symlink
beause it causes issues with pip-install on some systems.

--HG--
branch : trunk
2009-11-05 17:46:14 +01:00
holger krekel
a5a94c4e8f largely improve and reshuffle docs, heading strongly towards a 1.1.0
--HG--
branch : trunk
2009-11-05 03:18:55 +01:00
holger krekel
b04a04cabd make py lib a self-contained directory again
- move and merge _py/ bits back to py/
- fixes all around

--HG--
branch : trunk
2009-11-04 21:34:07 +01:00
holger krekel
4dd6c7679d adding more alternatives as asked for by bluebird75
--HG--
branch : trunk
2009-11-02 14:52:54 +01:00
holger krekel
e584892c12 update and fix docs for installation
- rework installation
- add a new FAQ entry related to issue58 Windows/setuptools/multiprocess
- strike api/source references

--HG--
branch : trunk
2009-11-02 13:00:48 +01:00
holger krekel
6a82cdb37f fix jython issue, flexibilize sysexec params
--HG--
branch : trunk
2009-10-29 23:46:14 +01:00
holger krekel
609776bf26 trying a bit harder to get a realpath for the py lib because
execnet-rsync does not support working with links

--HG--
branch : trunk
2009-10-29 20:30:09 +01:00
holger krekel
30710a9cd6 fix windows32 issues, introduce a simplistic path.samefile for it, fix tests
--HG--
branch : trunk
2009-10-29 20:10:05 +01:00
holger krekel
c02719f44c rewrite nose-optional-call check, fixes python2.4 compat
--HG--
branch : trunk
2009-10-29 18:08:05 +01:00
holger krekel
7aee121bd7 move examples to doc directory
--HG--
branch : trunk
2009-10-29 17:54:37 +01:00
holger krekel
270ac2bc0d some release preps and cleanups
- update setup.py for release
- use distributes_setup on python3
- remove unncessary package_data
- remove execnet example

--HG--
branch : trunk
2009-10-29 12:45:12 +01:00
holger krekel
92d482069c moving py/bin to rootlevel bin/ and fixing tests
--HG--
branch : trunk
2009-10-29 16:53:02 +01:00
holger krekel
cc15685015 remove pyrest and _py/rest before first 1.1. release
--HG--
branch : trunk
2009-10-29 12:25:47 +01:00
holger krekel
455b0afdfe use new apipkg version
--HG--
branch : trunk
2009-10-29 11:47:12 +01:00
holger krekel
690ccaedc1 remove unnecessary builtin directory in favour of a single file
--HG--
branch : trunk
2009-10-28 22:00:38 +01:00
holger krekel
58e1693af0 fix a test-import issue occuring when there is a second 'testing' directory in PYTHONPATH or so.
--HG--
branch : trunk
2009-10-28 21:33:26 +01:00
holger krekel
69dd2d7a78 fix three python3 issues
--HG--
branch : trunk
2009-10-28 20:39:44 +01:00
holger krekel
86fc12dd15 resolves issue #59
resolves issue #48

Have the path.pyimport() helper raise an EnvironmentError if an
import of a given file returns a module that does not appear to
be coming from the actual path.  E.g. for a directory layout like this:

    a / test_whatever.py
    b / test_whatever.py

calling py.path.local("b/test_whatever.py").pyimport() will
fail if the other globally scoped test_whatever module was
loaded already.

--HG--
branch : trunk
2009-10-28 19:51:20 +01:00
Benjamin Peterson
1f01fafec7 can't use .format() on jython :(
--HG--
branch : trunk
2009-10-27 16:45:51 -05:00
Benjamin Peterson
92cab2bae7 merge trunk
--HG--
branch : trunk
2009-10-27 16:23:39 -05:00
Benjamin Peterson
37295dff0a hack around Jython's incorrect AST heriachy
--HG--
branch : trunk
2009-10-27 16:22:46 -05:00
holger krekel
84efdacfc0 enabling assertions with jython, fixing one .format occurence
to provide the setting for http://paste.pocoo.org/show/147361/

--HG--
branch : trunk
2009-10-27 21:51:05 +01:00
holger krekel
d2e6cd0523 first round of fixing jython compatibility issues, marking some tests as xfail-on-jython
--HG--
branch : trunk
2009-10-27 21:34:11 +01:00
holger krekel
33bd39053f using apipkg 1.0b2 snapshot version - adjusting/cleaning up some impl-detail accesses
--HG--
branch : trunk
2009-10-27 21:31:42 +01:00
holger krekel
cc3404b832 merged ronny's nose-compatibility hacks, i.e. nosestyle
setup_module() and setup() functions are supported.
added a few notes to changelog and documentation about it

--HG--
branch : trunk
2009-10-27 16:49:38 +01:00
holger krekel
2b1505c0f3 fix "py.cleanup -d" - add test and check to only remove empty dirs (!)
--HG--
branch : trunk
2009-10-27 16:03:14 +01:00
holger krekel
09ba42a1bb fix bug: a false xfail expression would erranonously report XPASS on failures
--HG--
branch : trunk
2009-10-27 12:02:40 +01:00
holger krekel
a161a865c8 remove deprecated parser.addgroup usage in favour of getgroup
--HG--
branch : trunk
2009-10-27 10:03:11 +01:00
holger krekel
fb159b0d40 removing some py.execnet references and moving scripts to execnet repo
--HG--
branch : trunk
2009-10-27 09:19:23 +01:00
Ronny Pfannschmidt
6f80c985fb support nose style argument-free setup/teardown functions
--HG--
branch : trunk
2009-10-23 16:17:06 +02:00
Ronny Pfannschmidt
5f3bdf2d0b nose plugin wont call setup functions that arent made for it
--HG--
branch : trunk
2009-10-23 16:16:28 +02:00
Ronny Pfannschmidt
8e5efa7d6d better tests for the nose plugin, support module level teardown
--HG--
branch : trunk
2009-10-23 15:27:59 +02:00
Ronny Pfannschmidt
82caacd633 nosetest plugin now supports fallback to module level setup
--HG--
branch : trunk
2009-10-23 15:11:53 +02:00
holger krekel
6c2b1c4363 refine naming, API and docs for py.test.mark mechanism - now contained in pytest_mark plugin
--HG--
branch : trunk
2009-10-22 20:57:21 +02:00
holger krekel
861f34fe90 use new marking idioms, simplify generalized skipping implementation
--HG--
branch : trunk
2009-10-22 18:37:24 +02:00
holger krekel
4a76c096da extend and refine test marking
- allow to mark tests via a "pytestmark" name at class/module level.
- make combined positional args of marker calls available via an _args argument

--HG--
branch : trunk
2009-10-22 15:21:58 +02:00
holger krekel
9ac4faf3af don't visit '_' attributes on python objects for calling hooks
--HG--
branch : trunk
2009-10-21 18:44:12 +02:00
holger krekel
118eebb190 cleanup: move creation of python colitems to a default pytest_pycollect_makeitem hook impl
--HG--
branch : trunk
2009-10-21 18:42:40 +02:00
holger krekel
9910db2ca6 player nicer for missing parent Module objects for a collected function (bug triggered by oejskit)
--HG--
branch : trunk
2009-10-20 16:38:12 +02:00
Ronny Pfannschmidt
fabd967595 flush looponfail output to get around line-buffering
--HG--
branch : trunk
2009-10-18 22:30:18 +02:00
holger krekel
c38bb72205 reshuffle/refine option grouping, introduce "terminal reporting options"
--HG--
branch : trunk
2009-10-17 17:43:59 +02:00
holger krekel
80f3e33e41 deprecate addgroup / allow ordering of option groups
--HG--
branch : trunk
2009-10-17 17:43:33 +02:00
holger krekel
3795b08e95 add --report cmdline option, shift refined xfailed and skipped reporting to skipping plugin
--HG--
branch : trunk
2009-10-17 17:42:40 +02:00
holger krekel
eab7e039eb streamline pluginmanager api and test/beautify printing of plugins with --trace
--HG--
branch : trunk
2009-10-17 12:56:59 +02:00
holger krekel
6f5918f03b fix formatting of session log output
--HG--
branch : trunk
2009-10-15 23:14:51 +02:00
holger krekel
d8b9b5f1c8 - make importorskip static at py.test.importorskip because it's
used for conditional plugin loading
- fix case where xfail is defined at module/class level
- fixes and improvements to docs, correct links to plugins
- use new skip facilities here and there

--HG--
branch : trunk
2009-10-15 20:10:06 +02:00
holger krekel
3ca770b420 generalize skipping
- rename pytest_xfail to pytest_skip
- dynamic "skipif" and "xfail" decorators
- move most skipping code to the plugin

also coming with this commit:
- extend mark keyword to accept positional args + docs
- fix a few documentation related issues
- leave version as "trunk" for now

--HG--
branch : trunk
2009-10-15 16:18:57 +02:00
holger krekel
5e21e39125 resolve issue 54
triggered by @haypo's issue and patch the
process.cmdexec function now always uses
subprocess under the hood. Also fixed
some 3k related encoding issues.

--HG--
branch : trunk
2009-10-14 23:54:01 +02:00
holger krekel
df8aedba47 adding the console-runtest helper as discussed on py-dev
--HG--
branch : trunk
2009-10-12 11:28:47 +02:00
holger krekel
1bdc0896ca introduce "-d" to py.cleanup
--HG--
branch : trunk
2009-10-12 11:24:41 +02:00
holger krekel
90f39426b4 fix some tests after the py/_py split
--HG--
branch : trunk
2009-10-09 15:26:46 +02:00
holger krekel
f10bfbb7e5 resolves #59 - robustify unittest collection
--HG--
branch : trunk
2009-10-09 15:09:26 +02:00
holger krekel
a603021757 ignore more dirs and files
--HG--
branch : trunk
2009-10-08 13:38:31 +02:00
holger krekel
c15a1b698c forgot to commit the verbatim copy of apipkg in _py/apipkg.py
--HG--
branch : trunk
2009-10-05 02:22:48 +02:00
holger krekel
6e11f8cd2a * remove unused py._thread namespace, rewrite the one usage
* remove unused py/test/web directory

--HG--
branch : trunk
2009-10-03 19:57:48 +02:00
holger krekel
5791c06bf2 rewrote the initpkg mechanism and moved py lib implementation files to
_py/...  with py/__init__.py containing pointers into them

The new apipkg is only around 70 lines of code and allows
us to get rid of the infamous "py.__." by regular non-magical
"_py." imports. It is also available as a separately installable
package, see http://bitbucket.org/hpk42/apipkg

--HG--
branch : trunk
2009-10-03 01:47:39 +02:00
holger krekel
db1ff48996 * use the MIT license for the py lib
* bump version to prospective 1.1.0b1
* strike some unused code from initpkg

--HG--
branch : trunk
2009-10-03 01:11:04 +02:00
holger krekel
1f29529a24 * don't add distributed command line options when 'execnet' is not
installed, report a nice message.

* fix tests and code to work with non-existing execnet

* point execnet doc to the new package

--HG--
branch : trunk
2009-10-02 22:29:22 +02:00
holger krekel
ab9f6a75ad remove py.execnet, substitute py.execnet usages with "execnet" ones.
--HG--
branch : trunk
2009-10-02 16:58:57 +02:00
holger krekel
496e3b1138 adding internal repr for debugging
adding an example for generating multi-args/multi python tests

--HG--
branch : trunk
2009-09-30 18:36:04 +02:00
holger krekel
aed66120a2 fix typo, add ronny to authors, normalize email addresses
--HG--
branch : trunk
2009-09-30 17:59:03 +02:00
holger krekel
5914277f92 internally rename "provider" to "factory" to be consistent
with documentation.

--HG--
branch : trunk
2009-09-30 12:59:47 +02:00
holger krekel
98b2300266 fix cached_setup to deal properly for test_functions
with multiple args.  closes #50

--HG--
branch : trunk
2009-09-30 12:52:40 +02:00
Ronny Pfannschmidt
2986c5dc74 simplify serializer tests
* use generate_tests to generate the simple non-string checks
* get rid of the TestSerializer class

--HG--
branch : trunk
2009-09-28 23:43:38 +02:00
Benjamin Peterson
7466516673 the check_sequence name is more specific
--HG--
branch : trunk
2009-09-28 15:55:09 -05:00
Ronny Pfannschmidt
2c523cd0d6 enhance the serializer tests
* use generate_tests hook to generate the serialize deserialize combinations
* add dump/load funcargs to simplify the tests

--HG--
branch : trunk
2009-09-28 22:46:32 +02:00
Ronny Pfannschmidt
40e91dcd85 add separate test for the serializer bigint fail
--HG--
branch : trunk
2009-09-28 22:42:36 +02:00
Benjamin Peterson
3d2975f38e support floats
--HG--
branch : trunk
2009-09-26 18:26:32 -05:00
Benjamin Peterson
c3fd7f0247 don't need to import py
--HG--
branch : trunk
2009-09-26 14:22:01 -05:00
Benjamin Peterson
cb5bd868d9 use default argument
--HG--
branch : trunk
2009-09-26 14:21:36 -05:00
Benjamin Peterson
0f96be372d clean up unused compatibility code
--HG--
branch : trunk
2009-09-26 14:20:36 -05:00
Benjamin Peterson
4d598370b4 test cross version serialization by launching subprocesses; much cleaner!
--HG--
branch : trunk
2009-09-26 12:35:24 -05:00
holger krekel
8f69d23f18 merging jarko'S fixes, resolves issue #45, resolves issue #46
--HG--
branch : trunk
2009-09-23 19:43:43 +02:00
Benjamin Peterson
1e71a5c392 Add a simple (hopefully) cross-python marshaller
Will rewrite the tests soon...

--HG--
branch : trunk
2009-09-22 21:08:40 -05:00
Benjamin Peterson
b3ca12d435 update docstring
--HG--
branch : trunk
2009-09-22 21:07:50 -05:00
Benjamin Peterson
d80f37f14a add changelog entry for last commit
--HG--
branch : trunk
2009-09-22 21:07:07 -05:00
Benjamin Peterson
8af3ede092 allow a path to explicity given for py.lookup
--HG--
branch : trunk
2009-09-22 21:04:25 -05:00
holger krekel
6ddea4a1bc visit() now returns paths in depth-first order. fixes issue #47
--HG--
branch : trunk
2009-09-22 19:13:33 +02:00
holger krekel
e3b34c9da3 * allowing arbitrary keys for xspecs but adding some sanity checks to xspec-parsing and makegateway.
* fixing a python3 IO issue - we need to retain sys.stdout/stdin
  references to keep the underlying byte stream open.

--HG--
branch : trunk
2009-09-22 18:40:20 +02:00
Samuele Pedroni
1b97d06a09 (micke, pedronis)
teach the resultlog plugin about the xfail tweaked outcomes

--HG--
branch : trunk
2009-09-17 15:31:35 +02:00
Jurko
9fd1367845 Corrected the constructed system path value (broken by the env.cmd, env.sh & env.py file move in 4abc620bb044).
--HG--
branch : trunk
2009-09-12 00:35:57 +02:00
Jurko
62a4cf68e8 Fixed a typo in error.py causing it to fail on Windows.
--HG--
branch : trunk
2009-09-12 00:16:13 +02:00
Benjamin Peterson
81062c5e2f compiling AST to code is new in python 2.6
--HG--
branch : trunk
2009-09-11 15:24:43 -05:00
holger krekel
47bad98c07 * various cleanups and detailed doc string for gateway_base module
* remove old multi-file-send mechanism/tests now that
  only gateway_base is send to the other side.
* adding some (c) notices where i am pretty sure about them.

--HG--
branch : trunk
2009-09-11 16:26:19 +02:00
holger krekel
d4d0226058 added another funcarg example i had lying around
--HG--
branch : trunk
2009-09-11 12:05:06 +02:00
holger krekel
22c1ad9f7b fix a bug with funcarg setup and remove XXX comment because "scope=module" now would work but leaving it as session for now.
--HG--
branch : trunk
2009-09-09 23:07:42 +02:00
holger krekel
6d84da39e4 some doc about the experiemntal pytest_gwmanage_newgateway hook.
and use process-scope for execnet test funcargs because
of weird setup/teardown issues when running distributedly itself.

--HG--
branch : trunk
2009-09-09 20:45:51 +02:00
holger krekel
5df58c619d * move gateway management code to py/test/dist because it's not clear
how generally useful it is.
* provide pytest_dist_makegateway(txspec) hook so that plugins
  can add their own interpretation/keywords.

--HG--
branch : trunk
2009-09-09 20:12:03 +02:00
holger krekel
8ea2364039 ups, forgot to add a neccessary file.
--HG--
branch : trunk
2009-09-09 15:36:53 +02:00
holger krekel
b70c7a209d * moving execnet tests to funcarg-style, some cleanup
* slight refinement to FAQ license topic

--HG--
branch : trunk
2009-09-08 10:10:36 +02:00
holger krekel
f9eadc6440 relicense to LGPL, add an FAQ entry reasoning about it.
--HG--
branch : trunk
2009-09-08 09:57:19 +02:00
holger krekel
0f29b503ef monkeypatch, doc, apiwarn, deprecation fixes
--HG--
branch : trunk
2009-09-07 17:53:50 +02:00
holger krekel
29d437489d some fixes to support Jython better
--HG--
branch : trunk
2009-09-07 14:59:26 +02:00
holger krekel
3c3002ccd5 regen setup.py and docs so that "python3 setup.py build" maybe works if setuptools does
--HG--
branch : trunk
2009-09-06 17:17:37 +02:00
holger krekel
c8119d89b6 move test files out of py lib proper
* separate all tests from plugins
* simplify implicit inclusion of plugins under test
* have test_initpkg perform direct checks instead of yielding tests
* fix example tests for 3k

--HG--
branch : trunk
2009-09-06 16:59:39 +02:00
holger krekel
5cf27098cf execnet cleanup/refinements: avoid creating a shell for each subprocess
* introduce HostNotFound, raised for Socket and SshGateways
* factored out basic tests, cleaned up existing tests
* removed sshgateway identity argument which was deprecated in 1.0

--HG--
branch : trunk
2009-09-06 13:38:21 +02:00
holger krekel
734a40eb28 seems like compile is way slower than just parser.suite so
we try to see if it's available (only jython doesn't have it)

--HG--
branch : trunk
2009-09-06 12:35:52 +02:00
holger krekel
518194537e * refactor some setup/teardown/ensuretemp usages to use funcargs
* introduce monkeypatch.syspath_prepend for safe monkey patching of module import path
* fix monkeypatch naming

--HG--
branch : trunk
2009-09-05 23:21:58 +02:00
holger krekel
783c714a2c get py.test to run at least basically on top of jython
* allow and document calling of monkeypatch.undo() from a test
* default to 'sys' on platforms there no 'os.dup' is available
* use "compile" to perform "tryparsing" checks

--HG--
branch : trunk
2009-09-05 16:54:52 +02:00
holger krekel
7ab98c1b25 * delete or text files to hacking/ directory.
* split license file into authors and license file, minor fixes.
* minor unicode fixes

--HG--
branch : trunk
2009-09-05 16:09:44 +02:00
holger krekel
bde56a8246 * fixing lots of remaining 3k compatibility issues, mostly with py.test itself.
* removing very old import-tests that IIRC relate to a time when there
  was a custom import hook in use.

* basically py.test internal tests pass now except py3/py2 distributed
  testing tests

--HG--
branch : trunk
2009-09-04 21:47:49 +02:00
holger krekel
1e51844519 introduce py.builtin._tryimport to try importing modules in a row, fix a few places
--HG--
branch : trunk
2009-09-04 19:08:10 +02:00
holger krekel
32e2bf7d08 make xmlgen a single file + a single file test instead of a whole directory
--HG--
branch : trunk
2009-09-04 18:30:48 +02:00
holger krekel
a0d7ab2244 reviewing, refactoring, porting xml/html object/tree generation to work with 3k
--HG--
branch : trunk
2009-09-04 18:16:10 +02:00
holger krekel
6823fa634b various 3k related fixes and cleanups
removal of virtually unused py/rest/rst.py helpers

--HG--
branch : trunk
2009-09-04 18:15:41 +02:00
holger krekel
5851471009 fix remaining execnet 3k issues until all tests pass
--HG--
branch : trunk
2009-09-04 16:51:29 +02:00
holger krekel
45b98d4915 remove so-far superflous _getcode and pickle from builtins, some streamlining
--HG--
branch : trunk
2009-09-04 16:32:49 +02:00
Benjamin Peterson
99af33b26d I think this is supposed to be immutable
--HG--
branch : trunk
2009-09-03 17:14:12 -05:00
Benjamin Peterson
1c9760d123 fix xfail
--HG--
branch : trunk
2009-09-03 16:47:04 -05:00
Benjamin Peterson
86da34b874 add a helper to get a function's dictionary
--HG--
branch : trunk
2009-09-03 16:45:28 -05:00
Benjamin Peterson
499a982860 give code objects a filename in the replacement execfile
--HG--
branch : trunk
2009-09-03 16:38:15 -05:00
holger krekel
c7f11745cd * fix various remaining 3k issues until test_gateway.py passes with python3 py/bin/py.test
* we now wait on gateway initialization until we got a byte back after
  we sent the bootstrap

--HG--
branch : trunk
2009-09-02 21:05:08 +02:00
holger krekel
6c3e961bc5 * simplify stdout/stderr handling and modules and for now remove support
for directly stdout/stderr directly on remote_exec

--HG--
branch : trunk
2009-09-02 19:39:24 +02:00
holger krekel
73fc2f01f2 filter out and test exception printing
--HG--
branch : trunk
2009-09-02 19:05:34 +02:00
holger krekel
e30aeed876 * more tests and fixes for cross-python compatibility
* use byte-buffer files if available for io
* shift receivelock to gateway object
* kill dead code

--HG--
branch : trunk
2009-09-02 18:56:43 +02:00
holger krekel
5d2504df0a * simplify lock acquiration for received messages, review code
* try to fix seldomly occuring race condition with setcallback/receive and closing of channel

--HG--
branch : trunk
2009-09-02 15:45:59 +02:00
holger krekel
f636ed8ced * make Gateway interface more asymetric: remote_* methods
and  cleanup/atexit handling now live exclusively with the "InitiatingGateway"

* fix some cross-python io related handling

--HG--
branch : trunk
2009-09-02 14:31:48 +02:00
holger krekel
c1fcf9c4d8 * use py.builtin._getimself instead of getattr(..., '*self*') everywhere
* fix logging to work with 3k, implement buffering manually
* fix unicode capturing issue - re-introduce EncodedFile for <3K file writes

--HG--
branch : trunk
2009-09-01 16:10:21 +02:00
holger krekel
43b8bd7df7 * refactor gateway code and tests to live in fewer files, remove some lock usage
* move text files to a new "hacking" directory

--HG--
branch : trunk
2009-09-01 11:39:27 +02:00
holger krekel
54709bcae1 enable assertion reinterpretation on 3k
--HG--
branch : trunk
2009-08-31 20:06:55 +02:00
holger krekel
c791610998 * simplify and refactor path tests to use funcargs instead of the layered xunit-setup mess
* port py/path to pass 3.11
* added py.builtin._totext, _tobytes, _isbytes, _istext helpers

--HG--
branch : trunk
2009-08-31 19:51:25 +02:00
Benjamin Peterson
e336683cdb add test for conversion to string
--HG--
branch : trunk
2009-08-30 08:25:48 -05:00
Benjamin Peterson
749bfa46c4 convert argument to string
--HG--
branch : trunk
2009-08-30 08:25:40 -05:00
Ronny Pfannschmidt
318a935b89 fix module name reuse in execnet
--HG--
branch : trunk
2009-08-30 15:00:26 +02:00
Benjamin Peterson
04dd0810c3 no unbound methods in py3
--HG--
branch : trunk
2009-08-29 16:22:34 -05:00
Benjamin Peterson
ee17858cce get rid of usage of the new module
--HG--
branch : trunk
2009-08-29 16:12:06 -05:00
Benjamin Peterson
ee86950af4 use correct attribute to find the instance of a bound method
--HG--
branch : trunk
2009-08-29 16:07:48 -05:00
Benjamin Peterson
a051eb1a05 only use cmp() in 2.x
--HG--
branch : trunk
2009-08-29 16:02:59 -05:00
Benjamin Peterson
ad0c2edfd2 fix generators on python 3
--HG--
branch : trunk
2009-08-29 16:00:24 -05:00
Benjamin Peterson
e63abd631f add py.builtin.callable
--HG--
branch : trunk
2009-08-29 15:46:50 -05:00
Benjamin Peterson
1781347999 use py.builtin.execfile()
--HG--
branch : trunk
2009-08-29 15:36:27 -05:00
Benjamin Peterson
01848ca821 add py.builtin.execfile to __init__.py
--HG--
branch : trunk
2009-08-29 15:36:14 -05:00
Benjamin Peterson
39eac1be28 add a py.builtin.execfile helper
--HG--
branch : trunk
2009-08-29 15:34:24 -05:00
Benjamin Peterson
c95504e738 use py.builtin.builtins instead of import test
--HG--
branch : trunk
2009-08-29 15:18:21 -05:00
Benjamin Peterson
59892b8532 remove usage of the new module
--HG--
branch : trunk
2009-08-29 15:14:18 -05:00
Benjamin Peterson
b3e8b2f6ab handle Queue renaming
--HG--
branch : trunk
2009-08-29 15:10:40 -05:00
Benjamin Peterson
7a4bd92e33 DeprecationWarning is in the builtin namespace
--HG--
branch : trunk
2009-08-29 15:08:34 -05:00
Benjamin Peterson
711552e84c use print function
--HG--
branch : trunk
2009-08-29 15:08:26 -05:00
Benjamin Peterson
9af223e6cb fix typos in converting test_oldmagic
--HG--
branch : trunk
2009-08-29 14:54:15 -05:00
Benjamin Peterson
8a6a3183ae guard against tests trying to import this
--HG--
branch : trunk
2009-08-29 14:50:44 -05:00
Benjamin Peterson
9018fe40e3 fix syntax for py3
--HG--
branch : trunk
2009-08-29 14:50:29 -05:00
Benjamin Peterson
4369c65790 fix some broken things from syntax conversion
--HG--
branch : trunk
2009-08-29 14:39:55 -05:00
Benjamin Peterson
fb365e47dc make print write each argument individually
--HG--
branch : trunk
2009-08-29 14:39:37 -05:00
Benjamin Peterson
45a9aa536f fix need for py import
--HG--
branch : trunk
2009-08-29 14:16:54 -05:00
Benjamin Peterson
ee1747fcb4 make all syntax compatible with 3.1 and 2.5
--HG--
branch : trunk
2009-08-29 13:04:48 -05:00
Benjamin Peterson
6f4c6d36a4 allow file to be compiled on 2.5
--HG--
branch : trunk
2009-08-29 11:36:08 -05:00
Benjamin Peterson
78d0d4656b add a test which checks the syntax of the pylib on various python versions
--HG--
branch : trunk
2009-08-29 11:31:42 -05:00
holger krekel
b930565d56 * fix some syntax and 3k issues for py/path and py/process, tests only partially working
* have py.process.cmdexec return unicode/text (for now)
* rename py.builtin.basestring to _basestring

--HG--
branch : trunk
2009-08-29 16:40:03 +02:00
Benjamin Peterson
0f7a9e2da2 fix the rest of py/code tests on python 3
--HG--
branch : trunk
2009-08-29 09:37:56 -05:00
Benjamin Peterson
96ec12902d fix tests involving Queue
--HG--
branch : trunk
2009-08-29 09:02:20 -05:00
holger krekel
1dafcc6b37 fix py/io classes and tests to pass 3.1
introduce py.builtin._totext helper to make a 2k=unicode / 3k=str object, allow a string as data

--HG--
branch : trunk
2009-08-29 15:51:49 +02:00
holger krekel
d75f7b2dd7 merge the benjamins and my changes, accidentally caused a new remote head
--HG--
branch : trunk
2009-08-29 14:10:06 +02:00
Benjamin Peterson
c2d0c52086 replace iteritems() with items()
--HG--
branch : trunk
2009-08-29 07:03:19 -05:00
Benjamin Peterson
0014e65c1d fix interpreting is/is not/in/not in
--HG--
branch : trunk
2009-08-29 06:58:54 -05:00
holger krekel
fc3178a394 fixing builtin tests and print_ builtin
--HG--
branch : trunk
2009-08-29 13:47:10 +02:00
Benjamin Peterson
ac934bb2b6 only test View on 2.x
--HG--
branch : trunk
2009-08-28 20:28:09 -05:00
Benjamin Peterson
695c8038e0 new except syntax
--HG--
branch : trunk
2009-08-28 20:17:46 -05:00
Benjamin Peterson
e596d9df13 move the old assertion reinterpreting implementation to _assertionold.py
Also, seperate out some common code from the two.

--HG--
branch : trunk
2009-08-28 20:13:49 -05:00
Benjamin Peterson
130046d245 remove magic directories from install
--HG--
branch : trunk
2009-08-28 18:51:14 -05:00
Benjamin Peterson
e0e9953be2 implement assert debugging with builtin AST
--HG--
branch : trunk
2009-08-28 18:44:20 -05:00
Benjamin Peterson
3bdbb29c6f make the patched compile() work with AST
--HG--
branch : trunk
2009-08-28 18:39:51 -05:00
Benjamin Peterson
c23cc3656c fix location of magic AssertionError
--HG--
branch : trunk
2009-08-28 18:07:28 -05:00
holger krekel
783e6aeb4d temporary checking towards 3.1 compatibility
introduced some helpers to py.builtin namespace which need some review
after things begin to work more nicely

--HG--
branch : trunk
2009-08-28 19:16:15 +02:00
holger krekel
5e95feaf90 * add print_, exec_ and _reraise helpers for 2-3 compatible code
* consolidate builtins implementation to be compatible with >=2.3

--HG--
branch : trunk
2009-08-28 16:25:29 +02:00
holger krekel
91f90d27ee simplify broken-repr test for python2.4
--HG--
branch : trunk
2009-08-28 13:00:36 +02:00
holger krekel
d1932a30ed deprecate py.compat.doctest|subprocess|textwrap|...
(and for now pass through Python stdlib provided modules).

--HG--
branch : trunk
2009-08-27 21:12:55 +02:00
holger krekel
681d344eac deprecate py.magic.autopath() and finally remove py/magic directory.
--HG--
branch : trunk
2009-08-27 18:46:42 +02:00
holger krekel
13932b7f4b * deprecate py.magic.invoke/revoke in favour of
the new py.code.patch_builtins, py.code.unpatch_builtins

* deprecate py.magic.patch/revert

* deprecate py.magic.AssertionError in favour of py.code._AssertionError

* introduced pytest_assertion plugin.

--HG--
branch : trunk
2009-08-27 17:26:02 +02:00
holger krekel
e391662cff merge 1.0.x branch to trunk, fix doc link
--HG--
branch : trunk
2009-08-27 12:10:42 +02:00
holger krekel
47d56e41ba fix tests to not fail if pyc-file-writing is disabled
--HG--
branch : 1.0.x
2009-08-27 12:05:12 +02:00
holger krekel
c981ead40e switching release branch back to 1.0.x versioning
--HG--
branch : 1.0.x
2009-08-27 11:50:17 +02:00
holger krekel
e7b86d808f Added tag 1.0.2 for changeset 4816e8b80602
--HG--
branch : 1.0.x
2009-08-27 11:43:52 +02:00
holger krekel
81f7891539 merging 1.0.x branch
--HG--
branch : trunk
2009-08-26 22:57:06 +02:00
holger krekel
8ee7bef638 consolidate py/code files into code.py, simplify SafeRepr code and docs.
--HG--
branch : trunk
2009-08-25 20:24:43 +02:00
holger krekel
94aef0b771 move and rename html rest helper to rest directory - finally remove py/misc completely
--HG--
branch : trunk
2009-08-25 16:15:17 +02:00
holger krekel
e810e1774d simplify caching class
--HG--
branch : trunk
2009-08-25 16:14:20 +02:00
holger krekel
d43d69e3db death to "misc" directories. moved most files out of py/misc, either to a
private attic or to other places in the lib.

--HG--
branch : trunk
2009-08-25 16:14:15 +02:00
holger krekel
739edc26b4 simplifying errno error class creation and introduce a py.error.checked_call helper
that creates a proper errno-specific exception instead of OSErrors.  use it from
py.path.local.

--HG--
branch : trunk
2009-08-25 09:38:19 +02:00
holger krekel
58a9e71e81 add delattr/delenv/delitem methods and tests, enhance terminalwriter tests
--HG--
branch : trunk
2009-08-22 12:45:58 +02:00
holger krekel
27c08ac235 consolidate py/log into fewer files, remove one old approach, sketch simplified API
--HG--
branch : trunk
2009-08-22 09:42:12 +02:00
holger krekel
2b8f489d60 moved laura's utestconvert script to a more visible place
--HG--
branch : trunk
2009-08-21 12:56:43 +02:00
holger krekel
1fcd373bd5 * introduce py.io.TextIO and py.io.StringIO to help with 3k transition and to clarify
intentions when doing "in-memory" files. Replace most usages of StringIO.

* consolidate py.io's files and tests into fewer files, make files 3k-importable

--HG--
branch : trunk
2009-08-20 20:47:39 +02:00
holger krekel
046ac957ab fix autopath bug introduced with path refactoring
--HG--
branch : trunk
2009-08-21 12:09:23 +02:00
holger krekel
5118821c10 consolidate svn path implementations and tests into files named after the package namespaces.
--HG--
branch : trunk
2009-08-20 20:35:35 +02:00
holger krekel
f3fcb5e6d3 - strike lots of basically unused code around local path implementation.
and tweak things a bit to make py.path.local at least importable on 3k

- also strike unused somewhat related code in initpkg.py

--HG--
branch : trunk
2009-08-20 19:43:13 +02:00
holger krekel
561fdca3a2 move localpath implementation to a single file, simplify unix/posix difference and fix a bit
--HG--
branch : trunk
2009-08-20 17:37:06 +02:00
holger krekel
079a2327ec kill/replace some execnet debug code
bump version to "trunk" on trunk
add "py" to rsyncdirs

--HG--
branch : trunk
2009-08-20 16:41:44 +02:00
holger krekel
e051c9a4b8 remerge from 1.0.x after changelog addition change
--HG--
branch : trunk
2009-08-19 21:07:37 +02:00
holger krekel
9c6d5080e3 also merging the tag from 1.0.x branch
--HG--
branch : trunk
2009-08-19 19:42:33 +02:00
holger krekel
523380432a merging 1.0.1 branch
--HG--
branch : trunk
2009-08-19 18:25:46 +02:00
holger krekel
58d7f236a7 merge 1.0.x changes back to trunk
--HG--
branch : trunk
2009-08-14 18:08:48 +02:00
holger krekel
58db35e70c merging 1.0 branch
--HG--
branch : trunk
2009-08-09 19:06:36 +02:00
holger krekel
cb9b8e4632 merge 1.0.x branch
--HG--
branch : trunk
2009-08-04 12:09:11 +02:00
holger krekel
cd5a89bec9 merge 1.0.x branch
--HG--
branch : trunk
2009-07-31 15:47:08 +02:00
holger krekel
03970e0c4a merge 1.0.x branch
--HG--
branch : trunk
2009-07-22 16:10:25 +02:00
holger krekel
8336df9929 merge 1.0.x branch
--HG--
branch : trunk
2009-07-20 18:56:33 +02:00
holger krekel
4cf46c2723 merge 1.0.x changes
--HG--
branch : trunk
2009-07-14 21:37:54 +02:00
539 changed files with 22299 additions and 37083 deletions

View File

@@ -11,6 +11,14 @@ syntax:glob
*.pyo
*.swp
*.html
*.class
*.orig
*~
build/
dist/
py.egg-info
issue/
env/
3rdparty/
.tox

View File

@@ -17,3 +17,12 @@ e2a60653cb490aeed81bbbd83c070b99401c211c 1.0.0b9
5ea0cdf7854c3d4278d36eda94a2b68483a0e211 1.0.0
7acde360d94b6a2690ce3d03ff39301da84c0a2b 1.0.0
6bd221981ac99103002c1cb94fede400d23a96a1 1.0.1
4816e8b80602a3fd3a0a120333ad85fbe7d8bab4 1.0.2
60c44bdbf093285dc69d5462d4dbb4acad325ca6 1.1.0
319187fcda66714c5eb1353492babeec3d3c826f 1.1.1
4fc5212f7626a56b9eb6437b5c673f56dd7eb942 1.2.0
c143a8c8840a1c68570890c8ac6165bbf92fd3c6 1.2.1
eafd3c256e8732dfb0a4d49d051b5b4339858926 1.3.0
d5eacf390af74553227122b85e20345d47b2f9e6 1.3.1
d5eacf390af74553227122b85e20345d47b2f9e6 1.3.1
8b8e7c25a13cf863f01b2dd955978285ae9daf6a 1.3.1

23
AUTHORS Normal file
View File

@@ -0,0 +1,23 @@
Holger Krekel, holger at merlinux eu
Benjamin Peterson, benjamin at python org
Ronny Pfannschmidt, Ronny.Pfannschmidt at gmx de
Guido Wesdorp, johnny at johnnydebris net
Samuele Pedroni, pedronis at openend se
Carl Friedrich Bolz, cfbolz at gmx de
Armin Rigo, arigo at tunes org
Maciek Fijalkowski, fijal at genesilico pl
Brian Dorsey, briandorsey at gmail com
merlinux GmbH, Germany, office at merlinux eu
Contributors include::
Ross Lawley
Ralf Schmitt
Chris Lamb
Harald Armin Massa
Martijn Faassen
Ian Bicking
Jan Balster
Grig Gheorghiu
Bob Ippolito
Christian Tismer

View File

@@ -1 +0,0 @@
doc/changelog.txt

702
CHANGELOG Normal file
View File

@@ -0,0 +1,702 @@
Changes between 1.3.1 and 1.3.2
==================================================
New features
++++++++++++++++++
- fix issue103: introduce py.test.raises as context manager, examples::
with py.test.raises(ZeroDivisionError):
x = 0
1 / x
with py.test.raises(RuntimeError) as excinfo:
call_something()
# you may do extra checks on excinfo.value|type|traceback here
(thanks Ronny Pfannschmidt)
- Funcarg factories can now dynamically apply a marker to a
test invocation. This is for example useful if a factory
provides parameters to a test which are expected-to-fail::
def pytest_funcarg__arg(request):
request.applymarker(py.test.mark.xfail(reason="flaky config"))
...
def test_function(arg):
...
- improved error reporting on collection and import errors. This makes
use of a more general mechanism, namely that for custom test item/collect
nodes ``node.repr_failure(excinfo)`` is now uniformly called so that you can
override it to return a string error representation of your choice
which is going to be reported as a (red) string.
- introduce '--junitprefix=STR' option to prepend a prefix
to all reports in the junitxml file.
Bug fixes / Maintenance
++++++++++++++++++++++++++
- make tests and the ``pytest_recwarn`` plugin in particular fully compatible
to Python2.7 (if you use the ``recwarn`` funcarg warnings will be enabled so that
you can properly check for their existence in a cross-python manner).
- refine --pdb: ignore xfailed tests, unify its TB-reporting and
don't display failures again at the end.
- fix assertion interpretation with the ** operator (thanks Benjamin Peterson)
- fix issue105 assignment on the same line as a failing assertion (thanks Benjamin Peterson)
- fix issue104 proper escaping for test names in junitxml plugin (thanks anonymous)
- fix issue57 -f|--looponfail to work with xpassing tests (thanks Ronny)
- fix issue92 collectonly reporter and --pastebin (thanks Benjamin Peterson)
- fix py.code.compile(source) to generate unique filenames
- fix assertion re-interp problems on PyPy, by defering code
compilation to the (overridable) Frame.eval class. (thanks Amaury Forgeot)
- fix py.path.local.pyimport() to work with directories
- streamline py.path.local.mkdtemp implementation and usage
- don't print empty lines when showing junitxml-filename
- add optional boolean ignore_errors parameter to py.path.local.remove
- fix terminal writing on win32/python2.4
- py.process.cmdexec() now tries harder to return properly encoded unicode objects
on all python versions
- install plain py.test/py.which scripts also for Jython, this helps to
get canonical script paths in virtualenv situations
- make path.bestrelpath(path) return ".", note that when calling
X.bestrelpath the assumption is that X is a directory.
- make initial conftest discovery ignore "--" prefixed arguments
- fix resultlog plugin when used in an multicpu/multihost xdist situation
(thanks Jakub Gustak)
- perform distributed testing related reporting in the xdist-plugin
rather than having dist-related code in the generic py.test
distribution
- fix homedir detection on Windows
- ship distribute_setup.py version 0.6.13
Changes between 1.3.0 and 1.3.1
==================================================
New features
++++++++++++++++++
- issue91: introduce new py.test.xfail(reason) helper
to imperatively mark a test as expected to fail. Can
be used from within setup and test functions. This is
useful especially for parametrized tests when certain
configurations are expected-to-fail. In this case the
declarative approach with the @py.test.mark.xfail cannot
be used as it would mark all configurations as xfail.
- issue102: introduce new --maxfail=NUM option to stop
test runs after NUM failures. This is a generalization
of the '-x' or '--exitfirst' option which is now equivalent
to '--maxfail=1'. Both '-x' and '--maxfail' will
now also print a line near the end indicating the Interruption.
- issue89: allow py.test.mark decorators to be used on classes
(class decorators were introduced with python2.6) and
also allow to have multiple markers applied at class/module level
by specifying a list.
- improve and refine letter reporting in the progress bar:
. pass
f failed test
s skipped tests (reminder: use for dependency/platform mismatch only)
x xfailed test (test that was expected to fail)
X xpassed test (test that was expected to fail but passed)
You can use any combination of 'fsxX' with the '-r' extended
reporting option. The xfail/xpass results will show up as
skipped tests in the junitxml output - which also fixes
issue99.
- make py.test.cmdline.main() return the exitstatus instead of raising
SystemExit and also allow it to be called multiple times. This of
course requires that your application and tests are properly teared
down and don't have global state.
Fixes / Maintenance
++++++++++++++++++++++
- improved traceback presentation:
- improved and unified reporting for "--tb=short" option
- Errors during test module imports are much shorter, (using --tb=short style)
- raises shows shorter more relevant tracebacks
- --fulltrace now more systematically makes traces longer / inhibits cutting
- improve support for raises and other dynamically compiled code by
manipulating python's linecache.cache instead of the previous
rather hacky way of creating custom code objects. This makes
it seemlessly work on Jython and PyPy where it previously didn't.
- fix issue96: make capturing more resilient against Control-C
interruptions (involved somewhat substantial refactoring
to the underlying capturing functionality to avoid race
conditions).
- fix chaining of conditional skipif/xfail decorators - so it works now
as expected to use multiple @py.test.mark.skipif(condition) decorators,
including specific reporting which of the conditions lead to skipping.
- fix issue95: late-import zlib so that it's not required
for general py.test startup.
- fix issue94: make reporting more robust against bogus source code
(and internally be more careful when presenting unexpected byte sequences)
Changes between 1.2.1 and 1.3.0
==================================================
- deprecate --report option in favour of a new shorter and easier to
remember -r option: it takes a string argument consisting of any
combination of 'xfsX' characters. They relate to the single chars
you see during the dotted progress printing and will print an extra line
per test at the end of the test run. This extra line indicates the exact
position or test ID that you directly paste to the py.test cmdline in order
to re-run a particular test.
- allow external plugins to register new hooks via the new
pytest_addhooks(pluginmanager) hook. The new release of
the pytest-xdist plugin for distributed and looponfailing
testing requires this feature.
- add a new pytest_ignore_collect(path, config) hook to allow projects and
plugins to define exclusion behaviour for their directory structure -
for example you may define in a conftest.py this method::
def pytest_ignore_collect(path):
return path.check(link=1)
to prevent even a collection try of any tests in symlinked dirs.
- new pytest_pycollect_makemodule(path, parent) hook for
allowing customization of the Module collection object for a
matching test module.
- extend and refine xfail mechanism:
``@py.test.mark.xfail(run=False)`` do not run the decorated test
``@py.test.mark.xfail(reason="...")`` prints the reason string in xfail summaries
specifiying ``--runxfail`` on command line virtually ignores xfail markers
- expose (previously internal) commonly useful methods:
py.io.get_terminal_with() -> return terminal width
py.io.ansi_print(...) -> print colored/bold text on linux/win32
py.io.saferepr(obj) -> return limited representation string
- expose test outcome related exceptions as py.test.skip.Exception,
py.test.raises.Exception etc., useful mostly for plugins
doing special outcome interpretation/tweaking
- (issue85) fix junitxml plugin to handle tests with non-ascii output
- fix/refine python3 compatibility (thanks Benjamin Peterson)
- fixes for making the jython/win32 combination work, note however:
jython2.5.1/win32 does not provide a command line launcher, see
http://bugs.jython.org/issue1491 . See pylib install documentation
for how to work around.
- fixes for handling of unicode exception values and unprintable objects
- (issue87) fix unboundlocal error in assertionold code
- (issue86) improve documentation for looponfailing
- refine IO capturing: stdin-redirect pseudo-file now has a NOP close() method
- ship distribute_setup.py version 0.6.10
- added links to the new capturelog and coverage plugins
Changes between 1.2.1 and 1.2.0
=====================================
- refined usage and options for "py.cleanup"::
py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
py.cleanup -e .swp -e .cache # also remove files with these extensions
py.cleanup -s # remove "build" and "dist" directory next to setup.py files
py.cleanup -d # also remove empty directories
py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
py.cleanup -n # dry run, only show what would be removed
- add a new option "py.test --funcargs" which shows available funcargs
and their help strings (docstrings on their respective factory function)
for a given test path
- display a short and concise traceback if a funcarg lookup fails
- early-load "conftest.py" files in non-dot first-level sub directories.
allows to conveniently keep and access test-related options in a ``test``
subdir and still add command line options.
- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
- fix issue78: always call python-level teardown functions even if the
according setup failed. This includes refinements for calling setup_module/class functions
which will now only be called once instead of the previous behaviour where they'd be called
multiple times if they raise an exception (including a Skipped exception). Any exception
will be re-corded and associated with all tests in the according module/class scope.
- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
- fix pdb debugging to be in the correct frame on raises-related errors
- update apipkg.py to fix an issue where recursive imports might
unnecessarily break importing
- fix plugin links
Changes between 1.2 and 1.1.1
=====================================
- moved dist/looponfailing from py.test core into a new
separately released pytest-xdist plugin.
- new junitxml plugin: --junitxml=path will generate a junit style xml file
which is processable e.g. by the Hudson CI system.
- new option: --genscript=path will generate a standalone py.test script
which will not need any libraries installed. thanks to Ralf Schmitt.
- new option: --ignore will prevent specified path from collection.
Can be specified multiple times.
- new option: --confcutdir=dir will make py.test only consider conftest
files that are relative to the specified dir.
- new funcarg: "pytestconfig" is the pytest config object for access
to command line args and can now be easily used in a test.
- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
disambiguate between Python3, python2.X, Jython and PyPy installed versions.
- new "pytestconfig" funcarg allows access to test config object
- new "pytest_report_header" hook can return additional lines
to be displayed at the header of a test run.
- (experimental) allow "py.test path::name1::name2::..." for pointing
to a test within a test collection directly. This might eventually
evolve as a full substitute to "-k" specifications.
- streamlined plugin loading: order is now as documented in
customize.html: setuptools, ENV, commandline, conftest.
also setuptools entry point names are turned to canonical namees ("pytest_*")
- automatically skip tests that need 'capfd' but have no os.dup
- allow pytest_generate_tests to be defined in classes as well
- deprecate usage of 'disabled' attribute in favour of pytestmark
- deprecate definition of Directory, Module, Class and Function nodes
in conftest.py files. Use pytest collect hooks instead.
- collection/item node specific runtest/collect hooks are only called exactly
on matching conftest.py files, i.e. ones which are exactly below
the filesystem path of an item
- change: the first pytest_collect_directory hook to return something
will now prevent further hooks to be called.
- change: figleaf plugin now requires --figleaf to run. Also
change its long command line options to be a bit shorter (see py.test -h).
- change: pytest doctest plugin is now enabled by default and has a
new option --doctest-glob to set a pattern for file matches.
- change: remove internal py._* helper vars, only keep py._pydir
- robustify capturing to survive if custom pytest_runtest_setup
code failed and prevented the capturing setup code from running.
- make py.test.* helpers provided by default plugins visible early -
works transparently both for pydoc and for interactive sessions
which will regularly see e.g. py.test.mark and py.test.importorskip.
- simplify internal plugin manager machinery
- simplify internal collection tree by introducing a RootCollector node
- fix assert reinterpreation that sees a call containing "keyword=..."
- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
hooks on slaves during dist-testing, report module/session teardown
hooks correctly.
- fix issue65: properly handle dist-testing if no
execnet/py lib installed remotely.
- skip some install-tests if no execnet is available
- fix docs, fix internal bin/ script generation
Changes between 1.1.1 and 1.1.0
=====================================
- introduce automatic plugin registration via 'pytest11'
entrypoints via setuptools' pkg_resources.iter_entry_points
- fix py.test dist-testing to work with execnet >= 1.0.0b4
- re-introduce py.test.cmdline.main() for better backward compatibility
- svn paths: fix a bug with path.check(versioned=True) for svn paths,
allow '%' in svn paths, make svnwc.update() default to interactive mode
like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
- refine distributed tarball to contain test and no pyc files
- try harder to have deprecation warnings for py.compat.* accesses
report a correct location
Changes between 1.1.0 and 1.0.2
=====================================
* adjust and improve docs
* remove py.rest tool and internal namespace - it was
never really advertised and can still be used with
the old release if needed. If there is interest
it could be revived into its own tool i guess.
* fix issue48 and issue59: raise an Error if the module
from an imported test file does not seem to come from
the filepath - avoids "same-name" confusion that has
been reported repeatedly
* merged Ronny's nose-compatibility hacks: now
nose-style setup_module() and setup() functions are
supported
* introduce generalized py.test.mark function marking
* reshuffle / refine command line grouping
* deprecate parser.addgroup in favour of getgroup which creates option group
* add --report command line option that allows to control showing of skipped/xfailed sections
* generalized skipping: a new way to mark python functions with skipif or xfail
at function, class and modules level based on platform or sys-module attributes.
* extend py.test.mark decorator to allow for positional args
* introduce and test "py.cleanup -d" to remove empty directories
* fix issue #59 - robustify unittest test collection
* make bpython/help interaction work by adding an __all__ attribute
to ApiModule, cleanup initpkg
* use MIT license for pylib, add some contributors
* remove py.execnet code and substitute all usages with 'execnet' proper
* fix issue50 - cached_setup now caches more to expectations
for test functions with multiple arguments.
* merge Jarko's fixes, issue #45 and #46
* add the ability to specify a path for py.lookup to search in
* fix a funcarg cached_setup bug probably only occuring
in distributed testing and "module" scope with teardown.
* many fixes and changes for making the code base python3 compatible,
many thanks to Benjamin Peterson for helping with this.
* consolidate builtins implementation to be compatible with >=2.3,
add helpers to ease keeping 2 and 3k compatible code
* deprecate py.compat.doctest|subprocess|textwrap|optparse
* deprecate py.magic.autopath, remove py/magic directory
* move pytest assertion handling to py/code and a pytest_assertion
plugin, add "--no-assert" option, deprecate py.magic namespaces
in favour of (less) py.code ones.
* consolidate and cleanup py/code classes and files
* cleanup py/misc, move tests to bin-for-dist
* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
* consolidate py.log implementation, remove old approach.
* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
text/unicode and byte-streams (uses underlying standard lib io.*
if available)
* make py.unittest_convert helper script available which converts "unittest.py"
style files into the simpler assert/direct-test-classes py.test/nosetests
style. The script was written by Laura Creighton.
* simplified internal localpath implementation
Changes between 1.0.1 and 1.0.2
=====================================
* fixing packaging issues, triggered by fedora redhat packaging,
also added doc, examples and contrib dirs to the tarball.
* added a documentation link to the new django plugin.
Changes between 1.0.0 and 1.0.1
=====================================
* added a 'pytest_nose' plugin which handles nose.SkipTest,
nose-style function/method/generator setup/teardown and
tries to report functions correctly.
* capturing of unicode writes or encoded strings to sys.stdout/err
work better, also terminalwriting was adapted and somewhat
unified between windows and linux.
* improved documentation layout and content a lot
* added a "--help-config" option to show conftest.py / ENV-var names for
all longopt cmdline options, and some special conftest.py variables.
renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
* fix issue #27: better reporting on non-collectable items given on commandline
(e.g. pyc files)
* fix issue #33: added --version flag (thanks Benjamin Peterson)
* fix issue #32: adding support for "incomplete" paths to wcpath.status()
* "Test" prefixed classes are *not* collected by default anymore if they
have an __init__ method
* monkeypatch setenv() now accepts a "prepend" parameter
* improved reporting of collection error tracebacks
* simplified multicall mechanism and plugin architecture,
renamed some internal methods and argnames
Changes between 1.0.0b9 and 1.0.0
=====================================
* more terse reporting try to show filesystem path relatively to current dir
* improve xfail output a bit
Changes between 1.0.0b8 and 1.0.0b9
=====================================
* cleanly handle and report final teardown of test setup
* fix svn-1.6 compat issue with py.path.svnwc().versioned()
(thanks Wouter Vanden Hove)
* setup/teardown or collection problems now show as ERRORs
or with big "E"'s in the progress lines. they are reported
and counted separately.
* dist-testing: properly handle test items that get locally
collected but cannot be collected on the remote side - often
due to platform/dependency reasons
* simplified py.test.mark API - see keyword plugin documentation
* integrate better with logging: capturing now by default captures
test functions and their immediate setup/teardown in a single stream
* capsys and capfd funcargs now have a readouterr() and a close() method
(underlyingly py.io.StdCapture/FD objects are used which grew a
readouterr() method as well to return snapshots of captured out/err)
* make assert-reinterpretation work better with comparisons not
returning bools (reported with numpy from thanks maciej fijalkowski)
* reworked per-test output capturing into the pytest_iocapture.py plugin
and thus removed capturing code from config object
* item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr)
Changes between 1.0.0b7 and 1.0.0b8
=====================================
* pytest_unittest-plugin is now enabled by default
* introduced pytest_keyboardinterrupt hook and
refined pytest_sessionfinish hooked, added tests.
* workaround a buggy logging module interaction ("closing already closed
files"). Thanks to Sridhar Ratnakumar for triggering.
* if plugins use "py.test.importorskip" for importing
a dependency only a warning will be issued instead
of exiting the testing process.
* many improvements to docs:
- refined funcargs doc , use the term "factory" instead of "provider"
- added a new talk/tutorial doc page
- better download page
- better plugin docstrings
- added new plugins page and automatic doc generation script
* fixed teardown problem related to partially failing funcarg setups
(thanks MrTopf for reporting), "pytest_runtest_teardown" is now
always invoked even if the "pytest_runtest_setup" failed.
* tweaked doctest output for docstrings in py modules,
thanks Radomir.
Changes between 1.0.0b3 and 1.0.0b7
=============================================
* renamed py.test.xfail back to py.test.mark.xfail to avoid
two ways to decorate for xfail
* re-added py.test.mark decorator for setting keywords on functions
(it was actually documented so removing it was not nice)
* remove scope-argument from request.addfinalizer() because
request.cached_setup has the scope arg. TOOWTDI.
* perform setup finalization before reporting failures
* apply modified patches from Andreas Kloeckner to allow
test functions to have no func_code (#22) and to make
"-k" and function keywords work (#20)
* apply patch from Daniel Peolzleithner (issue #23)
* resolve issue #18, multiprocessing.Manager() and
redirection clash
* make __name__ == "__channelexec__" for remote_exec code
Changes between 1.0.0b1 and 1.0.0b3
=============================================
* plugin classes are removed: one now defines
hooks directly in conftest.py or global pytest_*.py
files.
* added new pytest_namespace(config) hook that allows
to inject helpers directly to the py.test.* namespace.
* documented and refined many hooks
* added new style of generative tests via
pytest_generate_tests hook that integrates
well with function arguments.
Changes between 0.9.2 and 1.0.0b1
=============================================
* introduced new "funcarg" setup method,
see doc/test/funcarg.txt
* introduced plugin architecuture and many
new py.test plugins, see
doc/test/plugins.txt
* teardown_method is now guaranteed to get
called after a test method has run.
* new method: py.test.importorskip(mod,minversion)
will either import or call py.test.skip()
* completely revised internal py.test architecture
* new py.process.ForkedFunc object allowing to
fork execution of a function to a sub process
and getting a result back.
XXX lots of things missing here XXX
Changes between 0.9.1 and 0.9.2
===============================
* refined installation and metadata, created new setup.py,
now based on setuptools/ez_setup (thanks to Ralf Schmitt
for his support).
* improved the way of making py.* scripts available in
windows environments, they are now added to the
Scripts directory as ".cmd" files.
* py.path.svnwc.status() now is more complete and
uses xml output from the 'svn' command if available
(Guido Wesdorp)
* fix for py.path.svn* to work with svn 1.5
(Chris Lamb)
* fix path.relto(otherpath) method on windows to
use normcase for checking if a path is relative.
* py.test's traceback is better parseable from editors
(follows the filenames:LINENO: MSG convention)
(thanks to Osmo Salomaa)
* fix to javascript-generation, "py.test --runbrowser"
should work more reliably now
* removed previously accidentally added
py.test.broken and py.test.notimplemented helpers.
* there now is a py.__version__ attribute
Changes between 0.9.0 and 0.9.1
===============================
This is a fairly complete list of changes between 0.9 and 0.9.1, which can
serve as a reference for developers.
* allowing + signs in py.path.svn urls [39106]
* fixed support for Failed exceptions without excinfo in py.test [39340]
* added support for killing processes for Windows (as well as platforms that
support os.kill) in py.misc.killproc [39655]
* added setup/teardown for generative tests to py.test [40702]
* added detection of FAILED TO LOAD MODULE to py.test [40703, 40738, 40739]
* fixed problem with calling .remove() on wcpaths of non-versioned files in
py.path [44248]
* fixed some import and inheritance issues in py.test [41480, 44648, 44655]
* fail to run greenlet tests when pypy is available, but without stackless
[45294]
* small fixes in rsession tests [45295]
* fixed issue with 2.5 type representations in py.test [45483, 45484]
* made that internal reporting issues displaying is done atomically in py.test
[45518]
* made that non-existing files are igored by the py.lookup script [45519]
* improved exception name creation in py.test [45535]
* made that less threads are used in execnet [merge in 45539]
* removed lock required for atomical reporting issue displaying in py.test
[45545]
* removed globals from execnet [45541, 45547]
* refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit
get called in 2.5 (py.execnet) [45548]
* fixed bug in joining threads in py.execnet's servemain [45549]
* refactored py.test.rsession tests to not rely on exact output format anymore
[45646]
* using repr() on test outcome [45647]
* added 'Reason' classes for py.test.skip() [45648, 45649]
* killed some unnecessary sanity check in py.test.collect [45655]
* avoid using os.tmpfile() in py.io.fdcapture because on Windows it's only
usable by Administrators [45901]
* added support for locking and non-recursive commits to py.path.svnwc [45994]
* locking files in py.execnet to prevent CPython from segfaulting [46010]
* added export() method to py.path.svnurl
* fixed -d -x in py.test [47277]
* fixed argument concatenation problem in py.path.svnwc [49423]
* restore py.test behaviour that it exits with code 1 when there are failures
[49974]
* don't fail on html files that don't have an accompanying .txt file [50606]
* fixed 'utestconvert.py < input' [50645]
* small fix for code indentation in py.code.source [50755]
* fix _docgen.py documentation building [51285]
* improved checks for source representation of code blocks in py.test [51292]
* added support for passing authentication to py.path.svn* objects [52000,
52001]
* removed sorted() call for py.apigen tests in favour of [].sort() to support
Python 2.3 [52481]

195
ISSUES.txt Normal file
View File

@@ -0,0 +1,195 @@
refine session initialization / fix custom collect crash
---------------------------------------------------------------
tags: bug 1.4 core xdist
When calling "py.test path/X" py.test can crash if the collection
of that directory is skipped. Calling "py.test path" will give
proper output. The reason is that for the very first colitems
getinitialnodes() and a collection is done before the fully
controlled session and pytest_make_collect_report protocol takes over.
Try to remove the redundant getinitialnodes related logic and amend
the session collect logic to care for this "initial" case as well.
Apart from simplification a side effect the dsession's session
and the core session probably converge some more.
introduce py.test.mark.nocollect
-------------------------------------------------------
tags: feature 1.4
for not considering a function for test collection at all.
maybe also introduce a py.test.mark.test to explicitely
mark a function to become a tested one. Lookup JUnit
ways of tagging tests.
introduce py.test.mark.platform
-------------------------------------------------------
tags: feature 1.4
Introduce nice-to-spell platform-skipping, examples:
@py.test.mark.platform("python3")
@py.test.mark.platform("not python3")
@py.test.mark.platform("win32 and not python3")
@py.test.mark.platform("darwin")
@py.test.mark.platform("not (jython and win32)")
@py.test.mark.platform("not (jython and win32)", xfail=True)
etc. Idea is to allow Python expressions which can operate
on common spellings for operating systems and python
interpreter versions.
introduce py.test.mark registration
-----------------------------------------
tags: feature 1.3
introduce a hook that allows to register a named mark decorator
with documentation and add "py.test --marks" to get
a list of available marks. Deprecate "dynamic" mark
definitions.
do early-teardown of test modules
-----------------------------------------
tags: feature 1.3
currently teardowns are called when the next tests is setup
except for the function/method level where interally
"teardown_exact" tears down immediately. Generalize
this to perform the "neccessary" teardown compared to
the "next" test item during teardown - this should
get rid of some irritations because otherwise e.g.
prints of teardown-code appear in the setup of the next test.
do recursive walk of conftest.py files?
-----------------------------------------
tags: feature 1.3
it maybe makes sense to generally do a recursive search of conftest.py
files before command line parsing - this would help to offer the
full list of options as applicable to a given test project.
consider introducing py.test.mark.skip_[not]win32/jython/pyXY
-------------------------------------------------------------
tags: feature 1.3
conveniently introduce markers for platforms to
have a shorter form for skipping.
generalize parametrized testing to generate combinations
-------------------------------------------------------------
tags: feature 1.3
think about extending metafunc.addcall or add a new method to allow to
generate tests with combinations of all generated versions - what to do
about "id" and "param" in such combinations though?
introduce py.test.mark.multi
-----------------------------------------
tags: feature 1.3
introduce py.test.mark.multi to specify a number
of values for a given function argument.
have imported module mismatch honour relative paths
--------------------------------------------------------
tags: bug 1.4
With 1.1.1 py.test fails at least on windows if an import
is relative and compared against an absolute conftest.py
path. Normalize.
make node._checkcollectable more robust
-------------------------------------------------
tags: bug 1.4
currently node._checkcollectable() can raise
exceptions for all kinds of reasons ('conftest.py' loading
problems, missing rsync-dirs, platform-skip-at-import-level
issues, ...). It should just return True/False and cause
a good error message.
call termination with small timeout
-------------------------------------------------
tags: feature 1.4
test: testing/pytest/dist/test_dsession.py - test_terminate_on_hanging_node
Call gateway group termination with a small timeout if available.
Should make dist-testing less likely to leave lost processes.
consider globals: py.test.ensuretemp and config
--------------------------------------------------------------
tags: experimental-wish 1.4
consider deprecating py.test.ensuretemp and py.test.config
to further reduce py.test globality. Also consider
having py.test.config and ensuretemp coming from
a plugin rather than being there from the start.
consider allowing funcargs to setup methods
--------------------------------------------------------------
tags: experimental-wish 1.4
Users have expressed the wish to have funcargs available to setup
functions. Experiment with allowing funcargs there - it might
also help to make the py.test.ensuretemp and config deprecation.
For filling funcargs for setup methods, we could call funcarg
factories with a request object that not have a cls/function
attributes. However, how to handle parametrized test functions
and funcargs?
consider pytest_addsyspath hook
-----------------------------------------
tags: 1.4
py.test could call a new pytest_addsyspath() in order to systematically
allow manipulation of sys.path and to inhibit it via --no-addsyspath
in order to more easily run against installed packages.
Alternatively it could also be done via the config object
and pytest_configure.
relax requirement to have tests/testing contain an __init__
----------------------------------------------------------------
tags: feature 1.4
bb: http://bitbucket.org/hpk42/py-trunk/issue/64
A local test run of a "tests" directory may work
but a remote one fail because the tests directory
does not contain an "__init__.py". Either give
an error or make it work without the __init__.py
show plugin information in test header
----------------------------------------------------------------
tags: feature 1.4
Now that external plugins are becoming more numerous
it would be useful to have external plugins along with
their versions displayed as a header line.
generate/refine plugin doc generation
----------------------------------------------------------------
tags: feature 1.4
review and prepare docs for 1.4.0 release. Probably
have docs living with the plugin and require them to
be available on doc generation time, at least when
the target is the website? Or rather go for interactive help?
deprecate global py.test.config usage
----------------------------------------------------------------
tags: feature 1.4
py.test.ensuretemp and py.test.config are probably the last
objects containing global state. Often using them is not
neccessary. This is about trying to get rid of them, i.e.
deprecating them and checking with PyPy's usages as well
as others.
remove deprecated bits in collect.py
-------------------------------------------------------------------
tags: feature 1.4
In an effort to further simplify code, review and remove deprecated bits
in collect.py. Probably good:
- inline consider_file/dir methods, no need to have them
subclass-overridable because of hooks

View File

@@ -1 +0,0 @@
py/LICENSE

19
LICENSE Normal file
View File

@@ -0,0 +1,19 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,17 +1,19 @@
include CHANGELOG
include README.txt
include setup.py
include distribute_setup.py
include LICENSE
include py/LICENSE
include py/path/svn/testing/repotest.dump
include py/rest/rest.sty.template
exclude *.orig
exclude *.rej
prune .svn
prune .hg
include conftest.py
graft doc
graft contrib
graft example
graft py/bin
graft py/rest/testing/data
graft py/misc/testing/data
graft bin
graft testing
#exclude *.orig
#exclude *.orig
exclude *.rej
exclude .hginore
exclude *.pyc
#recursive-exclude testing *.pyc *.orig *.rej *$py.class
#prune .pyc
#prune .svn
#prune .hg

View File

@@ -2,7 +2,6 @@ The py lib is a Python development support library featuring
the following tools and modules:
* py.test: tool for distributed automated testing
* py.execnet: ad-hoc distributed execution
* py.code: dynamic code generation and introspection
* py.path: uniform local and svn path objects

4
bin-for-dist/all-plat.sh Normal file → Executable file
View File

@@ -1,6 +1,6 @@
py.test --dist=each $* \
--tx 'popen//python=python2.6' \
--tx 'ssh=noco//python=/usr/local/bin/python2.4//chdir=/tmp/pytest-python2.4' \
--tx 'socket=192.168.1.106:8888'
#--tx 'popen//python=python2.6' \
#--tx 'ssh=noco//python=/usr/local/bin/python2.4//chdir=/tmp/pytest-python2.4' \

View File

@@ -1,6 +1,6 @@
from _findpy import py
import py
bindir = py.magic.autopath().dirpath().dirpath("py").join("bin")
bindir = py.path.local(__file__).dirpath().dirpath("bin")
assert bindir.check(), bindir
def getbasename(name):
@@ -31,5 +31,3 @@ if __name__ == "__main__":
if name[0] != "_":
genscript_unix(name)
genscript_windows(name)

View File

@@ -3,7 +3,7 @@ import sys
sys.path.insert(0, sys.argv[1])
import py
toolpath = py.magic.autopath()
toolpath = py.path.local(__file__)
binpath = py.path.local(py.__file__).dirpath('bin')
def error(msg):
@@ -27,14 +27,14 @@ class SetupWriter(object):
def getallpath(self, basedir):
contrib = self.basedir.join("contrib")
allpath = []
lines = py.process.cmdexec("hg st -mcan").split("\n")
for path in lines:
p = basedir.join(path)
assert p.check(), p
allpath = []
lines = py.process.cmdexec("hg st -mcan").split("\n")
for path in lines:
p = basedir.join(path)
assert p.check(), p
if not p.relto(contrib) and p != contrib and not self.isexcluded(p):
allpath.append(p)
return allpath
allpath.append(p)
return allpath
def append(self, string):
lines = string.split("\n")
@@ -70,37 +70,19 @@ class SetupWriter(object):
)
for line in output.split("\n"):
info.append("%s %s" %(indent, line.strip()))
return "\n".join(info)
return "\n".join(info)
finally:
old.chdir()
def setup_header(self):
#tooltime = "%s %s" %(py.std.time.asctime(), py.std.time.tzname[0])
toolname = toolpath.basename
#toolrevision = py.path.svnwc(toolpath).info().rev
toolname = toolpath.basename
#toolrevision = py.path.svnwc(toolpath).info().rev
pkgname = self.pkg.__name__
info = self.tip_info()
self.append('''
"""
py lib / py.test setup.py file, autogenerated by %(toolname)s
''' % locals())
#self.append(info)
self.append('''
"""
import os, sys
''')
if self.setuptools:
#import ez_setup
#ez_setup.use_setuptools()
self.append("""
from setuptools import setup
""")
else:
self.append("""
from distutils.core import setup
""")
self.append('"""py lib / py.test setup.py file"""')
self.append('import os, sys')
self.append("from setuptools import setup")
def setup_trailer(self):
self.append('''
@@ -111,10 +93,6 @@ class SetupWriter(object):
def setup_function(self):
params = self.__dict__.copy()
params.update(self.meta.__dict__)
#params['url'] = self.wcinfo.url
#params['rev'] = self.wcinfo.rev
#params['long_description'] = reformat(params['long_description'])
#print py.std.pprint.pprint(params)
self.append('long_description = """')
for line in params['long_description'].split('\n'):
self.append(line)
@@ -128,31 +106,26 @@ class SetupWriter(object):
setup(
name=%(name)r,
description=%(description)r,
long_description = long_description,
version= trunk or %(version)r,
url=%(url)r,
long_description = long_description,
version= trunk or %(version)r,
url=%(url)r,
license=%(license)r,
platforms=%(platforms)r,
platforms=%(platforms)r,
author=%(author)r,
author_email=%(author_email)r,
''' % params)
indent = " " * 8
#self.append_pprint(indent, py_modules=['_findpy',]),
#self.append_pprint(indent, scripts=self.getscripts())
self.append_pprint(indent, entry_points={'console_scripts':self.getconsolescripts()})
self.append_pprint(indent, classifiers=self.meta.classifiers)
self.append_pprint(indent, packages=self.getpackages())
#self.append_pprint(indent, data_files=self.getdatafiles())
self.append_pprint(indent, package_data=self.getpackagedata())
#self.append_pprint(indent, package_dir={'py': 'py'})
#self.append_pprint(indent, packages=self.getpackages())
if self.setuptools:
self.append_pprint(indent, zip_safe=False)
self.append_pprint(indent, zip_safe=True)
self.append_pprint(indent, install_requires=['apipkg'])
self.lines.append(indent[4:] + ")\n")
def setup_scripts(self):
# XXX this was used for a different approach
not used
not used
self.append("""
def getscripts():
if sys.platform == "win32":
@@ -164,7 +137,7 @@ class SetupWriter(object):
l = []
for name in %r:
l.append(base + name + ext)
return l
return l
""" % ([script.basename for script in binpath.listdir("py.*")]))
def append_pprint(self, indent, append=",", **kw):
@@ -187,10 +160,10 @@ class SetupWriter(object):
if p.dirpath() == bindir:
if p.basename.startswith('py.'):
shortname = "py" + p.basename[3:]
scripts.append("%s = py.cmdline:%s" %
scripts.append("%s = py.cmdline:%s" %
(p.basename, shortname))
return scripts
def getscripts(self):
bindir = self.basedir.join('py', 'bin')
scripts = []
@@ -202,7 +175,7 @@ class SetupWriter(object):
def getpackages(self):
packages = []
for p in self.allpaths: # contains no directories!
for p in self.allpaths: # contains no directories!
#if p.basename == "py":
# continue
if p.dirpath('__init__.py').check():
@@ -224,7 +197,7 @@ class SetupWriter(object):
datafiles = []
pkgbase = self.basedir.join(self.pkg.__name__)
for p in self.allpaths:
if p.check(file=1) and (not p.dirpath("__init__.py").check()
if p.check(file=1) and (not p.dirpath("__init__.py").check()
or p.ext != ".py"):
if p.dirpath() != self.basedir:
x = p.relto(pkgbase)
@@ -244,7 +217,7 @@ class SetupWriter(object):
import winpath
self.append(py.std.inspect.getsource(winpath))
self.append("""
from distutils.command.install import install
from distutils.command.install import install
class my_install(install):
def finalize_other(self):
install.finalize_other(self)
@@ -281,7 +254,7 @@ class SetupWriter(object):
else:
cmdclass = {}
''')
def write_setup(self):
self.setup_header()
self.setup_function()

26
bin-for-dist/hudson.py Normal file
View File

@@ -0,0 +1,26 @@
import os, sys, subprocess, urllib
BUILDNAME=os.environ.get('BUILD_NUMBER', "1")
def call(*args):
ret = subprocess.call(list(args))
assert ret == 0
def bincall(*args):
args = list(args)
args[0] = os.path.join(BIN, args[0])
call(*args)
call("virtualenv", os.path.abspath(BUILDNAME), '--no-site-packages')
BIN=os.path.abspath(os.path.join(BUILDNAME, 'bin'))
if not os.path.exists(BIN):
BIN=os.path.abspath(os.path.join(BUILDNAME, 'Scripts'))
assert os.path.exists(BIN)
PYTHON=os.path.join(BIN, 'python')
bincall("python", "setup.py", "develop", "-q")
bincall("pip", "install", "-r", "testing/pip-reqs1.txt",
"-q", "--download-cache=download")
bincall("py.test", "--ignore", BUILDNAME,
"--xml=junit.xml",
"--report=skipped", "--runslowtest", *sys.argv[1:])

View File

@@ -1,31 +1,34 @@
import py
import sys
import os, sys
WIDTH = 75
plugins = [
('plugins for Python test functions',
'xfail figleaf monkeypatch capture recwarn',),
('plugins for other testing styles and languages',
'oejskit unittest nose django doctest restdoc'),
('plugins for generic reporting and failure logging',
'pastebin resultlog terminal',),
('plugins for generic reporting and failure logging',
'pastebin resultlog terminal',),
('misc plugins / core functionality',
'helpconfig pdb keyword hooklog')
('advanced python testing',
'skipping mark pdb figleaf '
'monkeypatch coverage cov capture capturelog recwarn tmpdir',),
('distributed testing, CI and deployment',
'xdist pastebin junitxml resultlog genscript',),
('testing domains and conventions codecheckers',
'oejskit django unittest nose doctest restdoc'),
('internal, debugging, help functionality',
'helpconfig terminal hooklog')
#('internal plugins / core functionality',
# #'pdb keyword hooklog runner execnetcleanup # pytester',
# 'pdb keyword hooklog runner execnetcleanup' # pytester',
# #'runner execnetcleanup # pytester',
# 'runner execnetcleanup' # pytester',
#)
]
externals = {
'oejskit': 'run javascript tests in real life browsers',
'django': 'support for testing django applications',
'oejskit': "run javascript tests in real life browsers",
'xdist': None,
'figleaf': None,
'capturelog': None,
'coverage': None,
'cov': None,
'codecheckers': None,
'django': "for testing django applications",
}
def warn(*args):
msg = " ".join(map(str, args))
print >>sys.stderr, "WARN:", msg
@@ -123,10 +126,10 @@ class RestWriter:
self.out.close()
print "wrote", self.target
del self.out
class PluginOverview(RestWriter):
def makerest(self, config):
plugindir = py.path.local(py.__file__).dirpath("test", "plugin")
plugindir = py._pydir.join('plugin')
for cat, specs in plugins:
pluginlist = specs.split()
self.h1(cat)
@@ -135,29 +138,31 @@ class PluginOverview(RestWriter):
docpath = self.target.dirpath(name).new(ext=".txt")
if oneliner is not None:
htmlpath = docpath.new(ext='.html')
self.para("%s_ %s" %(name, oneliner))
self.para("%s_ (external) %s" %(name, oneliner))
self.add_internal_link(name, htmlpath)
else:
doc = PluginDoc(docpath)
doc.make(config=config, name=name)
self.add_internal_link(name, doc.target)
self.para("%s_ %s" %(name, doc.oneliner))
if name in externals:
self.para("%s_ (external) %s" %(name, doc.oneliner))
else:
self.para("%s_ %s" %(name, doc.oneliner))
self.Print()
class HookSpec(RestWriter):
def makerest(self, config):
module = config.pluginmanager.hook._hookspecs
source = py.code.Source(module)
self.h1("hook specification sourcecode")
self.sourcecode(source)
for module in config.pluginmanager.hook._hookspecs:
source = py.code.Source(module)
self.h1("hook specification sourcecode")
self.sourcecode(source)
class PluginDoc(RestWriter):
def makerest(self, config, name):
config.pluginmanager.import_plugin(name)
plugin = config.pluginmanager.getplugin(name)
assert plugin is not None, plugin
print plugin
doc = plugin.__doc__.strip()
i = doc.find("\n")
if i == -1:
@@ -167,12 +172,13 @@ class PluginDoc(RestWriter):
oneliner = doc[:i].strip()
moduledoc = doc[i+1:].strip()
self.name = plugin.__name__.split(".")[-1]
self.name = oneliner # plugin.__name__.split(".")[-1]
self.oneliner = oneliner
self.moduledoc = moduledoc
self.h1("%s plugin" % self.name) # : %s" %(self.name, self.oneliner))
self.Print(self.oneliner)
#self.h1("%s plugin" % self.name) # : %s" %(self.name, self.oneliner))
self.h1(oneliner)
#self.Print(self.oneliner)
self.Print()
self.Print(".. contents::")
self.Print(" :local:")
@@ -182,7 +188,8 @@ class PluginDoc(RestWriter):
self.emit_funcargs(plugin)
self.emit_options(plugin)
self.emit_source(plugin, config.hg_changeset)
if name not in externals:
self.emit_source(plugin, config.hg_changeset)
#self.sourcelink = (purename,
# "http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/" +
# purename + ".py")
@@ -212,12 +219,12 @@ class PluginDoc(RestWriter):
# "py/test/plugin/%s" %(hg_changeset, basename)))
self.links.append((basename,
"http://bitbucket.org/hpk42/py-trunk/raw/%s/"
"py/test/plugin/%s" %(pyversion, basename)))
"py/_plugin/%s" %(pyversion, basename)))
self.links.append(('customize', '../customize.html'))
self.links.append(('plugins', 'index.html'))
self.links.append(('get in contact', '../../contact.html'))
self.links.append(('checkout the py.test development version',
'../../download.html#checkout'))
'../../install.html#checkout'))
if 0: # this breaks the page layout and makes large doc files
#self.h2("plugin source code")
@@ -252,7 +259,7 @@ class PluginDoc(RestWriter):
warn("missing docstring", func)
def emit_options(self, plugin):
from py.__.test.parseopt import Parser
from py._test.parseopt import Parser
options = []
parser = Parser(processopt=options.append)
if hasattr(plugin, 'pytest_addoption'):
@@ -261,13 +268,16 @@ class PluginDoc(RestWriter):
return
self.h2("command line options")
self.Print()
formatter = py.compat.optparse.IndentedHelpFormatter()
formatter = py.std.optparse.IndentedHelpFormatter()
for opt in options:
switches = formatter.format_option_strings(opt)
self.Print("``%s``" % switches)
self.Print(opt.help, indent=4)
if __name__ == "__main__":
if os.path.exists("py"):
sys.path.insert(0, os.getcwd())
import py
_config = py.test.config
_config.parse([])
_config.pluginmanager.do_configure(_config)

View File

@@ -1,6 +1,8 @@
import py
import subprocess
import os
import os, sys
execnet = py.test.importorskip("execnet")
#
@@ -64,7 +66,10 @@ class VirtualEnv(object):
return "<VirtualEnv at %r>" %(self.path)
def _cmd(self, name):
return os.path.join(self.path, 'bin', name)
if sys.platform == "win32":
return os.path.join(self.path, 'Scripts', name)
else:
return os.path.join(self.path, 'bin', name)
def ensure(self):
if not os.path.exists(self._cmd('python')):
@@ -78,7 +83,7 @@ class VirtualEnv(object):
def makegateway(self):
python = self._cmd('python')
return py.execnet.makegateway("popen//python=%s" %(python,))
return execnet.makegateway("popen//python=%s" %(python,))
def pcall(self, cmd, *args, **kw):
self.ensure()
@@ -87,6 +92,16 @@ class VirtualEnv(object):
] + list(args),
**kw)
def pytest_getouterr(self, *args):
self.ensure()
args = [self._cmd("py.test")] + list(args)
popen = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, err = popen.communicate()
return out
def setup_develop(self):
self.ensure()
return self.pcall("python", "setup.py", "develop")
def easy_install(self, *packages, **kw):
args = []
@@ -109,3 +124,105 @@ def test_make_sdist_and_run_it(py_setup, venv):
ch = gw.remote_exec("import py ; channel.send(py.__version__)")
version = ch.receive()
assert version == py.__version__
def test_plugin_setuptools_entry_point_integration(py_setup, venv, tmpdir):
sdist = py_setup.make_sdist(venv.path)
venv.easy_install(str(sdist))
# create a sample plugin
basedir = tmpdir.mkdir("testplugin")
basedir.join("setup.py").write("""if 1:
from setuptools import setup
setup(name="testplugin",
entry_points = {'pytest11': ['testplugin=tp1']},
py_modules = ['tp1'],
)
""")
basedir.join("tp1.py").write(py.code.Source("""
def pytest_addoption(parser):
parser.addoption("--testpluginopt", action="store_true")
"""))
basedir.chdir()
print ("created sample plugin in %s" %basedir)
venv.setup_develop()
out = venv.pytest_getouterr("-h")
assert "testpluginopt" in out
def test_cmdline_entrypoints(monkeypatch):
monkeypatch.syspath_prepend(py.path.local(__file__).dirpath().dirpath())
from setup import cmdline_entrypoints
versioned_scripts = ['py.test', 'py.which']
unversioned_scripts = versioned_scripts + [ 'py.cleanup',
'py.convert_unittest', 'py.countloc', 'py.lookup', 'py.svnwcrevert']
for ver in [(2,4,0), (2,5,0), (2,6,0), (2,7,0), (3,0,1), (3,1,1)]:
for platform in ('posix', 'win32'):
points = cmdline_entrypoints(ver, "posix", 'python')
for script in versioned_scripts:
script_ver = script + "-%s.%s" % ver[:2]
assert script_ver in points
for script in unversioned_scripts:
assert script in points
points = cmdline_entrypoints((2,5,1), "java1.6.123", 'jython')
for script in versioned_scripts:
expected = "%s-jython" % script
assert expected in points
for script in unversioned_scripts:
assert script in points
points = cmdline_entrypoints((2,5,1), "xyz", 'pypy-c-XYZ')
for script in versioned_scripts:
expected = "%s-pypy-c-XYZ" % script
assert expected in points
for script in unversioned_scripts:
assert script in points
def test_slave_popen_needs_no_pylib(testdir, venv, pytestconfig):
pytestconfig.pluginmanager.skipifmissing("xdist")
venv.ensure()
#xxx execnet optimizes popen
#ch = venv.makegateway().remote_exec("import execnet")
#py.test.raises(ch.RemoteError, ch.waitclose)
python = venv._cmd("python")
p = testdir.makepyfile("""
import py
def test_func():
pass
""")
result = testdir.runpytest(p, '--rsyncdir=%s' % str(p),
'--dist=each', '--tx=popen//python=%s' % python)
result.stdout.fnmatch_lines([
"*1 passed*"
])
def test_slave_needs_no_execnet(testdir, sshhost, pytestconfig):
pytestconfig.pluginmanager.skipifmissing("xdist")
xspec = "ssh=%s" % sshhost
gw = execnet.makegateway("ssh=%s" % sshhost)
ch = gw.remote_exec("""
import os, subprocess
subprocess.call(["virtualenv", "--no-site-packages", "subdir"])
channel.send(os.path.join(os.path.abspath("subdir"), 'bin', 'python'))
channel.send(os.path.join(os.path.abspath("subdir")))
""")
try:
path = ch.receive()
chdir = ch.receive()
except ch.RemoteError:
e = sys.exc_info()[1]
py.test.skip("could not prepare ssh slave:%s" % str(e))
gw.exit()
newspec = "%s//python=%s//chdir=%s" % (xspec, path, chdir)
gw = execnet.makegateway(newspec)
ch = gw.remote_exec("import execnet")
py.test.raises(ch.RemoteError, ch.waitclose)
gw.exit()
p = testdir.makepyfile("""
import py
def test_func():
pass
""")
result = testdir.runpytest(p, '--rsyncdir=%s' % str(p),
'--dist=each', '--tx=%s' % newspec)
result.stdout.fnmatch_lines([
"*1 passed*"
])

View File

@@ -1,7 +1,9 @@
#!/usr/bin/env python
#
# find and import a version of 'py'
# find and import a version of 'py' that exists in a parent dir
# of the current working directory. fall back to import a
# globally available version
#
import sys
import os
@@ -19,7 +21,7 @@ def searchpy(current):
# if p == current:
# return True
if current != sys.path[0]: # if we are already first, then ok
print >>sys.stderr, "inserting into sys.path:", current
sys.stderr.write("inserting into sys.path: %s\n" % current)
sys.path.insert(0, current)
return True
current = opd(current)
@@ -34,4 +36,4 @@ if not searchpy(abspath(os.curdir)):
import py
if __name__ == '__main__':
print "py lib is at", py.__file__
print ("py lib is at %s" % py.__file__)

View File

@@ -3,7 +3,7 @@
import sys, os, os.path
progpath = sys.argv[0]
packagedir = os.path.abspath(os.path.dirname(progpath))
packagedir = os.path.dirname(os.path.dirname(os.path.abspath(progpath)))
packagename = os.path.basename(packagedir)
bindir = os.path.join(packagedir, 'bin')
if sys.platform == 'win32':
@@ -29,5 +29,5 @@ def setenv(name, value):
assert False, 'Shell not supported.'
return cmd
print prepend_path('PATH', bindir)
print prepend_path('PYTHONPATH', rootdir)
print(prepend_path('PATH', bindir))
print(prepend_path('PYTHONPATH', rootdir))

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env python
from _findpy import py
py.cmdline.pyrest()
py.cmdline.pyconvert_unittest()

View File

@@ -0,0 +1,2 @@
@echo off
python "%~dp0\..\py.convert_unittest" %*

95
conftest.py Normal file
View File

@@ -0,0 +1,95 @@
import py
import sys
pytest_plugins = '_pytest doctest pytester'.split()
collect_ignore = ['build', 'doc/_build']
rsyncdirs = ['conftest.py', 'bin', 'py', 'doc', 'testing']
import os, py
pid = os.getpid()
def pytest_addoption(parser):
group = parser.getgroup("pylib", "py lib testing options")
group.addoption('--sshhost',
action="store", dest="sshhost", default=None,
help=("ssh xspec for ssh functional tests. "))
group.addoption('--runslowtests',
action="store_true", dest="runslowtests", default=False,
help=("run slow tests"))
group.addoption('--lsof',
action="store_true", dest="lsof", default=False,
help=("run FD checks if lsof is available"))
def pytest_configure(config):
if config.getvalue("lsof"):
try:
out = py.process.cmdexec("lsof -p %d" % pid)
except py.process.cmdexec.Error:
pass
else:
config._numfiles = len([x for x in out.split("\n") if "REG" in x])
def pytest_unconfigure(config, __multicall__):
if not hasattr(config, '_numfiles'):
return
__multicall__.execute()
out2 = py.process.cmdexec("lsof -p %d" % pid)
len2 = len([x for x in out2.split("\n") if "REG" in x])
assert len2 < config._numfiles + 7, out2
def pytest_funcarg__sshhost(request):
val = request.config.getvalue("sshhost")
if val:
return val
py.test.skip("need --sshhost option")
def pytest_generate_tests(metafunc):
multi = getattr(metafunc.function, 'multi', None)
if multi is not None:
assert len(multi.kwargs) == 1
for name, l in multi.kwargs.items():
for val in l:
metafunc.addcall(funcargs={name: val})
elif 'anypython' in metafunc.funcargnames:
for name in ('python2.4', 'python2.5', 'python2.6',
'python2.7', 'python3.1', 'pypy-c', 'jython'):
metafunc.addcall(id=name, param=name)
# XXX copied from execnet's conftest.py - needs to be merged
winpymap = {
'python2.7': r'C:\Python27\python.exe',
'python2.6': r'C:\Python26\python.exe',
'python2.5': r'C:\Python25\python.exe',
'python2.4': r'C:\Python24\python.exe',
'python3.1': r'C:\Python31\python.exe',
}
def getexecutable(name, cache={}):
try:
return cache[name]
except KeyError:
executable = py.path.local.sysfind(name)
if executable:
if name == "jython":
import subprocess
popen = subprocess.Popen([str(executable), "--version"],
universal_newlines=True, stderr=subprocess.PIPE)
out, err = popen.communicate()
if not err or "2.5" not in err:
executable = None
cache[name] = executable
return executable
def pytest_funcarg__anypython(request):
name = request.param
executable = getexecutable(name)
if executable is None:
if sys.platform == "win32":
executable = winpymap.get(name, None)
if executable:
executable = py.path.local(executable)
if executable.check():
return executable
py.test.skip("no %s found" % (name,))
return executable

View File

@@ -1,329 +0,0 @@
"""
Tested with coverage 2.85 and pygments 1.0
TODO:
+ 'html-output/*,cover' should be deleted
+ credits for coverage
+ credits for pygments
+ 'Install pygments' after ImportError is to less
+ is the way of determining DIR_CSS_RESOURCE ok?
+ write plugin test
+ '.coverage' still exists in py.test execution dir
"""
import os
import sys
import re
import shutil
from StringIO import StringIO
import py
try:
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter
except ImportError:
print "Install pygments" # XXX
sys.exit(0)
DIR_CUR = str(py.path.local())
REPORT_FILE = os.path.join(DIR_CUR, '.coverage')
DIR_ANNOTATE_OUTPUT = os.path.join(DIR_CUR, '.coverage_annotate')
COVERAGE_MODULES = set()
# coverage output parsing
REG_COVERAGE_SUMMARY = re.compile('([a-z_\.]+) +([0-9]+) +([0-9]+) +([0-9]+%)')
REG_COVERAGE_SUMMARY_TOTAL = re.compile('(TOTAL) +([0-9]+) +([0-9]+) +([0-9]+%)')
DEFAULT_COVERAGE_OUTPUT = '.coverage_annotation'
# HTML output specific
DIR_CSS_RESOURCE = os.path.dirname(__import__('pytest_coverage').__file__)
CSS_RESOURCE_FILES = ['header_bg.jpg', 'links.gif']
COVERAGE_TERM_HEADER = "\nCOVERAGE INFORMATION\n" \
"====================\n"
HTML_INDEX_HEADER = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>py.test - Coverage Index</title>
<style type="text/css">
table {
font-size:0.9em;
font-family: Arial, Helvetica, verdana sans-serif;
background-color:#fff;
border-collapse: collapse;
width: 500px;
}
caption {
font-size: 25px;
color: #1ba6b2;
font-weight: bold;
text-align: left;
background: url(header_bg.jpg) no-repeat top left;
padding: 10px;
margin-bottom: 2px;
}
thead th {
border-right: 1px solid #fff;
color:#fff;
text-align:center;
padding:2px;
text-transform:uppercase;
height:25px;
background-color: #a3c159;
font-weight: normal;
}
tfoot {
color:#1ba6b2;
padding:2px;
text-transform:uppercase;
font-size:1.2em;
font-weigth: bold;
margin-top:6px;
border-top: 6px solid #e9f7f6;
}
tfoot td {
text-align: left;
}
tbody tr {
background-color:#fff;
border-bottom: 1px solid #f0f0f0;
}
tbody td {
color:#414141;
padding:5px;
text-align:left;
}
tbody th {
text-align:left;
padding:2px;
}
tbody td a, tbody th a {
color:#6C8C37;
text-decoration:none;
font-weight:normal;
display:block;
background: transparent url(links.gif) no-repeat 0% 50%;
padding-left:15px;
}
tbody td a:hover, tbody th a:hover {
color:#009193;
text-decoration:none;
}
</style>
</head>
<body
<table >
<caption>Module Coverage</caption>
<tbody>
<thead>
<tr>
<th>Module</th>
<th>Statements</th>
<th>Executed</th>
<th>Coverage</th>
</tr>
</thead>'''
HTML_INDEX_FOOTER = ''' </tbody>
</table>
</body>
</html>'''
class CoverageHtmlFormatter(HtmlFormatter):
"""XXX: doc"""
def __init__(self, *args, **kwargs):
HtmlFormatter.__init__(self,*args, **kwargs)
self.annotation_infos = kwargs.get('annotation_infos')
def _highlight_lines(self, tokensource):
"""
XXX: doc
"""
hls = self.hl_lines
self.annotation_infos = [None] + self.annotation_infos
hls = [l for l, i in enumerate(self.annotation_infos) if i]
for i, (t, value) in enumerate(tokensource):
if t != 1:
yield t, value
if i + 1 in hls: # i + 1 because Python indexes start at 0
if self.annotation_infos[i+1] == "!":
yield 1, '<span style="background-color:#FFE5E5">%s</span>' \
% value
elif self.annotation_infos[i+1] == ">":
yield 1, '<span style="background-color:#CCFFEB">%s</span>' \
% value
else:
raise ValueError("HHAHA: %s" % self.annotation_infos[i+1])
else:
yield 1, value
def _rename_annotation_files(module_list, dir_annotate_output):
for m in module_list:
mod_fpath = os.path.basename(m.__file__)
if mod_fpath.endswith('pyc'):
mod_fpath = mod_fpath[:-1]
old = os.path.join(dir_annotate_output, '%s,cover'% mod_fpath)
new = os.path.join(dir_annotate_output, '%s,cover'% m.__name__)
if os.path.isfile(old):
shutil.move(old, new)
yield new
def _generate_module_coverage(mc_path, anotation_infos, src_lines):
#XXX: doc
code = "".join(src_lines)
mc_path = "%s.html" % mc_path
lexer = get_lexer_by_name("python", stripall=True)
formatter = CoverageHtmlFormatter(linenos=True, noclasses=True,
hl_lines=[1], annotation_infos=anotation_infos)
result = highlight(code, lexer, formatter)
fp = open(mc_path, 'w')
fp.write(result)
fp.close()
def _parse_modulecoverage(mc_fpath):
#XXX: doc
fd = open(mc_fpath, 'r')
anotate_infos = []
src_lines = []
for line in fd.readlines():
anotate_info = line[0:2].strip()
if not anotate_info:
anotate_info = None
src_line = line[2:]
anotate_infos.append(anotate_info)
src_lines.append(src_line)
return mc_fpath, anotate_infos, src_lines
def _parse_coverage_summary(fd):
"""Parses coverage summary output."""
if hasattr(fd, 'readlines'):
fd.seek(0)
for l in fd.readlines():
m = REG_COVERAGE_SUMMARY.match(l)
if m:
# yield name, stmts, execs, cover
yield m.group(1), m.group(2), m.group(3), m.group(4)
else:
m = REG_COVERAGE_SUMMARY_TOTAL.match(l)
if m:
# yield name, stmts, execs, cover
yield m.group(1), m.group(2), m.group(3), m.group(4)
def _get_coverage_index(mod_name, stmts, execs, cover, annotation_dir):
"""
Generates the index page where are all modulare coverage reports are
linked.
"""
if mod_name == 'TOTAL':
return '<tfoot><tr style="text-align: center;font-weigth:bold;font-size:1.2em; "><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr></tfoot>\n' % (mod_name, stmts, execs, cover)
covrep_fpath = os.path.join(annotation_dir, '%s,cover.html' % mod_name)
assert os.path.isfile(covrep_fpath) == True
fname = os.path.basename(covrep_fpath)
modlink = '<a href="%s">%s</a>' % (fname, mod_name)
return '<tr style="text-align: center;"><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n' % (modlink, stmts, execs, cover)
class CoveragePlugin:
def pytest_addoption(self, parser):
group = parser.addgroup('coverage options')
group.addoption('-C', action='store_true', default=False,
dest = 'coverage',
help=('displays coverage information.'))
group.addoption('--coverage-html', action='store', default=False,
dest='coverage_annotation',
help='path to the coverage HTML output dir.')
group.addoption('--coverage-css-resourcesdir', action='store',
default=DIR_CSS_RESOURCE,
dest='coverage_css_ressourcedir',
help='path to dir with css-resources (%s) for '
'being copied to the HTML output dir.' % \
", ".join(CSS_RESOURCE_FILES))
def pytest_configure(self, config):
if config.getvalue('coverage'):
try:
import coverage
except ImportError:
raise config.Error("To run use the coverage option you have to install " \
"Ned Batchelder's coverage: "\
"http://nedbatchelder.com/code/modules/coverage.html")
self.coverage = coverage
self.summary = None
def pytest_terminal_summary(self, terminalreporter):
if hasattr(self, 'coverage'):
self.coverage.stop()
module_list = [sys.modules[mod] for mod in COVERAGE_MODULES]
module_list.sort()
summary_fd = StringIO()
# get coverage reports by module list
self.coverage.report(module_list, file=summary_fd)
summary = COVERAGE_TERM_HEADER + summary_fd.getvalue()
terminalreporter._tw.write(summary)
config = terminalreporter.config
dir_annotate_output = config.getvalue('coverage_annotation')
if dir_annotate_output:
if dir_annotate_output == "":
dir_annotate_output = DIR_ANNOTATE_OUTPUT
# create dir
if os.path.isdir(dir_annotate_output):
shutil.rmtree(dir_annotate_output)
os.mkdir(dir_annotate_output)
# generate annotation text files for later parsing
self.coverage.annotate(module_list, dir_annotate_output)
# generate the separate module coverage reports
for mc_fpath in _rename_annotation_files(module_list, \
dir_annotate_output):
# mc_fpath, anotate_infos, src_lines from _parse_do
_generate_module_coverage(*_parse_modulecoverage(mc_fpath))
# creating contents for the index pagee for coverage report
idxpage_html = StringIO()
idxpage_html.write(HTML_INDEX_HEADER)
total_sum = None
for args in _parse_coverage_summary(summary_fd):
# mod_name, stmts, execs, cover = args
idxpage_html.write(_get_coverage_index(*args, \
**dict(annotation_dir=dir_annotate_output)))
idxpage_html.write(HTML_INDEX_FOOTER)
idx_fpath = os.path.join(dir_annotate_output, 'index.html')
idx_fd = open(idx_fpath, 'w')
idx_fd.write(idxpage_html.getvalue())
idx_fd.close()
dir_css_resource_dir = config.getvalue('coverage_css_ressourcedir')
if dir_annotate_output and dir_css_resource_dir != "":
if not os.path.isdir(dir_css_resource_dir):
raise config.Error("CSS resource dir not found: '%s'" % \
dir_css_resource_dir)
for r in CSS_RESOURCE_FILES:
src = os.path.join(dir_css_resource_dir, r)
if os.path.isfile(src):
dest = os.path.join(dir_annotate_output, r)
shutil.copy(src, dest)
def pytest_collectstart(self, collector):
if isinstance(collector, py.__.test.pycollect.Module):
COVERAGE_MODULES.update(getattr(collector.obj,
'COVERAGE_MODULES', []))
def pytest_testrunstart(self):
print "self.coverage", self.coverage
if hasattr(self, 'coverage'):
print "START coverage"
self.coverage.erase()
self.coverage.start()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 B

20
contrib/runtesthelper.py Normal file
View File

@@ -0,0 +1,20 @@
"""
this little helper allows to run tests multiple times
in the same process. useful for running tests from
a console.
NOTE: since 1.3.1 you can just call py.test.cmdline.main()
multiple times - no special logic needed.
"""
import py, sys
def pytest(argv=None):
if argv is None:
argv = []
try:
sys.argv[1:] = argv
py.cmdline.pytest()
except SystemExit:
pass
# we need to reset the global py.test.config object
py.test.config = py.test.config.__class__()

View File

@@ -1,116 +0,0 @@
#!/usr/bin/env python
"""
small utility for hot-syncing a svn repository through ssh.
uses py.execnet.
"""
import py
import sys, os
def usage():
arg0 = sys.argv[0]
print """%s [user@]remote-host:/repo/location localrepo [identity keyfile]""" % (arg0,)
def main(args):
remote = args[0]
localrepo = py.path.local(args[1])
if not localrepo.check(dir=1):
raise SystemExit("localrepo %s does not exist" %(localrepo,))
if len(args) == 3:
keyfile = py.path.local(args[2])
else:
keyfile = None
remote_host, path = remote.split(':', 1)
print "ssh-connecting to", remote_host
gw = getgateway(remote_host, keyfile)
local_rev = get_svn_youngest(localrepo)
# local protocol
# 1. client sends rev/repo -> server
# 2. server checks for newer revisions and sends dumps
# 3. client receives dumps, updates local repo
# 4. client goes back to step 1
c = gw.remote_exec("""
import py
import os
remote_rev, repopath = channel.receive()
while 1:
rev = py.process.cmdexec('svnlook youngest "%s"' % repopath)
rev = int(rev)
if rev > remote_rev:
revrange = (remote_rev+1, rev)
dumpchannel = channel.gateway.newchannel()
channel.send(revrange)
channel.send(dumpchannel)
f = os.popen(
"svnadmin dump -q --incremental -r %s:%s %s"
% (revrange[0], revrange[1], repopath), 'r')
try:
maxcount = dumpchannel.receive()
count = maxcount
while 1:
s = f.read(8192)
if not s:
raise EOFError
dumpchannel.send(s)
count = count - 1
if count <= 0:
ack = dumpchannel.receive()
count = maxcount
except EOFError:
dumpchannel.close()
remote_rev = rev
else:
# using svn-hook instead would be nice here
py.std.time.sleep(30)
""")
c.send((local_rev, path))
print "checking revisions from %d in %s" %(local_rev, remote)
while 1:
revstart, revend = c.receive()
dumpchannel = c.receive()
print "receiving revisions", revstart, "-", revend, "replaying..."
svn_load(localrepo, dumpchannel)
print "current revision", revend
def svn_load(repo, dumpchannel, maxcount=100):
# every maxcount we will send an ACK to the other
# side in order to synchronise and avoid our side
# growing buffers (py.execnet does not control
# RAM usage or receive queue sizes)
dumpchannel.send(maxcount)
f = os.popen("svnadmin load -q %s" %(repo, ), "w")
count = maxcount
for x in dumpchannel:
sys.stdout.write(".")
sys.stdout.flush()
f.write(x)
count = count - 1
if count <= 0:
dumpchannel.send(maxcount)
count = maxcount
print >>sys.stdout
f.close()
def get_svn_youngest(repo):
rev = py.process.cmdexec('svnlook youngest "%s"' % repo)
return int(rev)
def getgateway(host, keyfile=None):
return py.execnet.SshGateway(host, identity=keyfile)
if __name__ == '__main__':
if len(sys.argv) < 3:
usage()
raise SystemExit(1)
main(sys.argv[1:])

View File

@@ -1,140 +0,0 @@
"""
sysinfo.py [host1] [host2] [options]
obtain system info from remote machine.
"""
import py
import sys
optparse = py.compat.optparse
parser = optparse.OptionParser(usage=__doc__)
parser.add_option("-f", "--sshconfig", action="store", dest="ssh_config", default=None,
help="use given ssh config file, and add info all contained hosts for getting info")
parser.add_option("-i", "--ignore", action="store", dest="ignores", default=None,
help="ignore hosts (useful if the list of hostnames come from a file list)")
def parsehosts(path):
path = py.path.local(path)
l = []
rex = py.std.re.compile(r'Host\s*(\S+)')
for line in path.readlines():
m = rex.match(line)
if m is not None:
sshname, = m.groups()
l.append(sshname)
return l
class RemoteInfo:
def __init__(self, gateway):
self.gw = gateway
self._cache = {}
def exreceive(self, execstring):
if execstring not in self._cache:
channel = self.gw.remote_exec(execstring)
self._cache[execstring] = channel.receive()
return self._cache[execstring]
def getmodattr(self, modpath):
module = modpath.split(".")[0]
return self.exreceive("""
import %s
channel.send(%s)
""" %(module, modpath))
def islinux(self):
return self.getmodattr('sys.platform').find("linux") != -1
def getfqdn(self):
return self.exreceive("""
import socket
channel.send(socket.getfqdn())
""")
def getmemswap(self):
if self.islinux():
return self.exreceive("""
import commands, re
out = commands.getoutput("free")
mem = re.search(r"Mem:\s+(\S*)", out).group(1)
swap = re.search(r"Swap:\s+(\S*)", out).group(1)
channel.send((mem, swap))
""")
def getcpuinfo(self):
if self.islinux():
return self.exreceive("""
# a hyperthreaded cpu core only counts as 1, although it
# is present as 2 in /proc/cpuinfo. Counting it as 2 is
# misleading because it is *by far* not as efficient as
# two independent cores.
cpus = {}
cpuinfo = {}
f = open("/proc/cpuinfo")
lines = f.readlines()
f.close()
for line in lines + ['']:
if line.strip():
key, value = line.split(":", 1)
cpuinfo[key.strip()] = value.strip()
else:
corekey = (cpuinfo.get("physical id"),
cpuinfo.get("core id"))
cpus[corekey] = 1
numcpus = len(cpus)
model = cpuinfo.get("model name")
channel.send((numcpus, model))
""")
def debug(*args):
print >>sys.stderr, " ".join(map(str, args))
def error(*args):
debug("ERROR", args[0] + ":", *args[1:])
def getinfo(sshname, ssh_config=None, loginfo=sys.stdout):
debug("connecting to", sshname)
try:
gw = py.execnet.SshGateway(sshname, ssh_config=ssh_config)
except IOError:
error("could not get sshagteway", sshname)
else:
ri = RemoteInfo(gw)
#print "%s info:" % sshname
prefix = sshname.upper() + " "
print >>loginfo, prefix, "fqdn:", ri.getfqdn()
for attr in (
"sys.platform",
"sys.version_info",
):
loginfo.write("%s %s: " %(prefix, attr,))
loginfo.flush()
value = ri.getmodattr(attr)
loginfo.write(str(value))
loginfo.write("\n")
loginfo.flush()
memswap = ri.getmemswap()
if memswap:
mem,swap = memswap
print >>loginfo, prefix, "Memory:", mem, "Swap:", swap
cpuinfo = ri.getcpuinfo()
if cpuinfo:
numcpu, model = cpuinfo
print >>loginfo, prefix, "number of cpus:", numcpu
print >>loginfo, prefix, "cpu model", model
return ri
if __name__ == '__main__':
options, args = parser.parse_args()
hosts = list(args)
ssh_config = options.ssh_config
if ssh_config:
hosts.extend(parsehosts(ssh_config))
ignores = options.ignores or ()
if ignores:
ignores = ignores.split(",")
for host in hosts:
if host not in ignores:
getinfo(host, ssh_config=ssh_config)

485
distribute_setup.py Normal file
View File

@@ -0,0 +1,485 @@
#!python
"""Bootstrap distribute installation
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
from distribute_setup import use_setuptools
use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import os
import sys
import time
import fnmatch
import tempfile
import tarfile
from distutils import log
try:
from site import USER_SITE
except ImportError:
USER_SITE = None
try:
import subprocess
def _python_cmd(*args):
args = (sys.executable,) + args
return subprocess.call(args) == 0
except ImportError:
# will be used for python 2.3
def _python_cmd(*args):
args = (sys.executable,) + args
# quoting arguments if windows
if sys.platform == 'win32':
def quote(arg):
if ' ' in arg:
return '"%s"' % arg
return arg
args = [quote(arg) for arg in args]
return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
DEFAULT_VERSION = "0.6.13"
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
SETUPTOOLS_FAKED_VERSION = "0.6c11"
SETUPTOOLS_PKG_INFO = """\
Metadata-Version: 1.0
Name: setuptools
Version: %s
Summary: xxxx
Home-page: xxx
Author: xxx
Author-email: xxx
License: xxx
Description: xxx
""" % SETUPTOOLS_FAKED_VERSION
def _install(tarball):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
log.warn('Extracting in %s', tmpdir)
old_wd = os.getcwd()
try:
os.chdir(tmpdir)
tar = tarfile.open(tarball)
_extractall(tar)
tar.close()
# going in the directory
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
os.chdir(subdir)
log.warn('Now working in %s', subdir)
# installing
log.warn('Installing Distribute')
if not _python_cmd('setup.py', 'install'):
log.warn('Something went wrong during the installation.')
log.warn('See the error message above.')
finally:
os.chdir(old_wd)
def _build_egg(egg, tarball, to_dir):
# extracting the tarball
tmpdir = tempfile.mkdtemp()
log.warn('Extracting in %s', tmpdir)
old_wd = os.getcwd()
try:
os.chdir(tmpdir)
tar = tarfile.open(tarball)
_extractall(tar)
tar.close()
# going in the directory
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
os.chdir(subdir)
log.warn('Now working in %s', subdir)
# building an egg
log.warn('Building a Distribute egg in %s', to_dir)
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
finally:
os.chdir(old_wd)
# returning the result
log.warn(egg)
if not os.path.exists(egg):
raise IOError('Could not build the egg.')
def _do_download(version, download_base, to_dir, download_delay):
egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
% (version, sys.version_info[0], sys.version_info[1]))
if not os.path.exists(egg):
tarball = download_setuptools(version, download_base,
to_dir, download_delay)
_build_egg(egg, tarball, to_dir)
sys.path.insert(0, egg)
import setuptools
setuptools.bootstrap_install_from = egg
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, download_delay=15, no_fake=True):
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
was_imported = 'pkg_resources' in sys.modules or \
'setuptools' in sys.modules
try:
try:
import pkg_resources
if not hasattr(pkg_resources, '_distribute'):
if not no_fake:
_fake_setuptools()
raise ImportError
except ImportError:
return _do_download(version, download_base, to_dir, download_delay)
try:
pkg_resources.require("distribute>="+version)
return
except pkg_resources.VersionConflict:
e = sys.exc_info()[1]
if was_imported:
sys.stderr.write(
"The required version of distribute (>=%s) is not available,\n"
"and can't be installed while this script is running. Please\n"
"install a more recent version first, using\n"
"'easy_install -U distribute'."
"\n\n(Currently using %r)\n" % (version, e.args[0]))
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
return _do_download(version, download_base, to_dir,
download_delay)
except pkg_resources.DistributionNotFound:
return _do_download(version, download_base, to_dir,
download_delay)
finally:
if not no_fake:
_create_fake_setuptools_pkg_info(to_dir)
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15):
"""Download distribute from a specified location and return its filename
`version` should be a valid distribute version number that is available
as an egg for download under the `download_base` URL (which should end
with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download
attempt.
"""
# making sure we use the absolute path
to_dir = os.path.abspath(to_dir)
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
tgz_name = "distribute-%s.tar.gz" % version
url = download_base + tgz_name
saveto = os.path.join(to_dir, tgz_name)
src = dst = None
if not os.path.exists(saveto): # Avoid repeated downloads
try:
log.warn("Downloading %s", url)
src = urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = src.read()
dst = open(saveto, "wb")
dst.write(data)
finally:
if src:
src.close()
if dst:
dst.close()
return os.path.realpath(saveto)
def _no_sandbox(function):
def __no_sandbox(*args, **kw):
try:
from setuptools.sandbox import DirectorySandbox
if not hasattr(DirectorySandbox, '_old'):
def violation(*args):
pass
DirectorySandbox._old = DirectorySandbox._violation
DirectorySandbox._violation = violation
patched = True
else:
patched = False
except ImportError:
patched = False
try:
return function(*args, **kw)
finally:
if patched:
DirectorySandbox._violation = DirectorySandbox._old
del DirectorySandbox._old
return __no_sandbox
def _patch_file(path, content):
"""Will backup the file then patch it"""
existing_content = open(path).read()
if existing_content == content:
# already patched
log.warn('Already patched.')
return False
log.warn('Patching...')
_rename_path(path)
f = open(path, 'w')
try:
f.write(content)
finally:
f.close()
return True
_patch_file = _no_sandbox(_patch_file)
def _same_content(path, content):
return open(path).read() == content
def _rename_path(path):
new_name = path + '.OLD.%s' % time.time()
log.warn('Renaming %s into %s', path, new_name)
os.rename(path, new_name)
return new_name
def _remove_flat_installation(placeholder):
if not os.path.isdir(placeholder):
log.warn('Unkown installation at %s', placeholder)
return False
found = False
for file in os.listdir(placeholder):
if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
found = True
break
if not found:
log.warn('Could not locate setuptools*.egg-info')
return
log.warn('Removing elements out of the way...')
pkg_info = os.path.join(placeholder, file)
if os.path.isdir(pkg_info):
patched = _patch_egg_dir(pkg_info)
else:
patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
if not patched:
log.warn('%s already patched.', pkg_info)
return False
# now let's move the files out of the way
for element in ('setuptools', 'pkg_resources.py', 'site.py'):
element = os.path.join(placeholder, element)
if os.path.exists(element):
_rename_path(element)
else:
log.warn('Could not find the %s element of the '
'Setuptools distribution', element)
return True
_remove_flat_installation = _no_sandbox(_remove_flat_installation)
def _after_install(dist):
log.warn('After install bootstrap.')
placeholder = dist.get_command_obj('install').install_purelib
_create_fake_setuptools_pkg_info(placeholder)
def _create_fake_setuptools_pkg_info(placeholder):
if not placeholder or not os.path.exists(placeholder):
log.warn('Could not find the install location')
return
pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
setuptools_file = 'setuptools-%s-py%s.egg-info' % \
(SETUPTOOLS_FAKED_VERSION, pyver)
pkg_info = os.path.join(placeholder, setuptools_file)
if os.path.exists(pkg_info):
log.warn('%s already exists', pkg_info)
return
log.warn('Creating %s', pkg_info)
f = open(pkg_info, 'w')
try:
f.write(SETUPTOOLS_PKG_INFO)
finally:
f.close()
pth_file = os.path.join(placeholder, 'setuptools.pth')
log.warn('Creating %s', pth_file)
f = open(pth_file, 'w')
try:
f.write(os.path.join(os.curdir, setuptools_file))
finally:
f.close()
_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
def _patch_egg_dir(path):
# let's check if it's already patched
pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
if os.path.exists(pkg_info):
if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
log.warn('%s already patched.', pkg_info)
return False
_rename_path(path)
os.mkdir(path)
os.mkdir(os.path.join(path, 'EGG-INFO'))
pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
f = open(pkg_info, 'w')
try:
f.write(SETUPTOOLS_PKG_INFO)
finally:
f.close()
return True
_patch_egg_dir = _no_sandbox(_patch_egg_dir)
def _before_install():
log.warn('Before install bootstrap.')
_fake_setuptools()
def _under_prefix(location):
if 'install' not in sys.argv:
return True
args = sys.argv[sys.argv.index('install')+1:]
for index, arg in enumerate(args):
for option in ('--root', '--prefix'):
if arg.startswith('%s=' % option):
top_dir = arg.split('root=')[-1]
return location.startswith(top_dir)
elif arg == option:
if len(args) > index:
top_dir = args[index+1]
return location.startswith(top_dir)
if arg == '--user' and USER_SITE is not None:
return location.startswith(USER_SITE)
return True
def _fake_setuptools():
log.warn('Scanning installed packages')
try:
import pkg_resources
except ImportError:
# we're cool
log.warn('Setuptools or Distribute does not seem to be installed.')
return
ws = pkg_resources.working_set
try:
setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
replacement=False))
except TypeError:
# old distribute API
setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
if setuptools_dist is None:
log.warn('No setuptools distribution found')
return
# detecting if it was already faked
setuptools_location = setuptools_dist.location
log.warn('Setuptools installation detected at %s', setuptools_location)
# if --root or --preix was provided, and if
# setuptools is not located in them, we don't patch it
if not _under_prefix(setuptools_location):
log.warn('Not patching, --root or --prefix is installing Distribute'
' in another location')
return
# let's see if its an egg
if not setuptools_location.endswith('.egg'):
log.warn('Non-egg installation')
res = _remove_flat_installation(setuptools_location)
if not res:
return
else:
log.warn('Egg installation')
pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
if (os.path.exists(pkg_info) and
_same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
log.warn('Already patched.')
return
log.warn('Patching...')
# let's create a fake egg replacing setuptools one
res = _patch_egg_dir(setuptools_location)
if not res:
return
log.warn('Patched done.')
_relaunch()
def _relaunch():
log.warn('Relaunching...')
# we have to relaunch the process
# pip marker to avoid a relaunch bug
if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
sys.argv[0] = 'setup.py'
args = [sys.executable] + sys.argv
sys.exit(subprocess.call(args))
def _extractall(self, path=".", members=None):
"""Extract all members from the archive to the current working
directory and set owner, modification time and permissions on
directories afterwards. `path' specifies a different directory
to extract to. `members' is optional and must be a subset of the
list returned by getmembers().
"""
import copy
import operator
from tarfile import ExtractError
directories = []
if members is None:
members = self
for tarinfo in members:
if tarinfo.isdir():
# Extract directories with a safe mode.
directories.append(tarinfo)
tarinfo = copy.copy(tarinfo)
tarinfo.mode = 448 # decimal for oct 0700
self.extract(tarinfo, path)
# Reverse sort directories.
if sys.version_info < (2, 4):
def sorter(dir1, dir2):
return cmp(dir1.name, dir2.name)
directories.sort(sorter)
directories.reverse()
else:
directories.sort(key=operator.attrgetter('name'), reverse=True)
# Set correct owner, mtime and filemode on directories.
for tarinfo in directories:
dirpath = os.path.join(path, tarinfo.name)
try:
self.chown(tarinfo, dirpath)
self.utime(tarinfo, dirpath)
self.chmod(tarinfo, dirpath)
except ExtractError:
e = sys.exc_info()[1]
if self.errorlevel > 1:
raise
else:
self._dbg(1, "tarfile: %s" % e)
def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
tarball = download_setuptools()
_install(tarball)
if __name__ == '__main__':
main(sys.argv[1:])

View File

@@ -0,0 +1,115 @@
py.test/pylib 1.1.0: Python3, Jython, advanced skipping, cleanups ...
--------------------------------------------------------------------------------
Features:
* compatible to Python3 (single py2/py3 source), `easy to install`_
* conditional skipping_: skip/xfail based on platform/dependencies
* generalized marking_: mark tests one a whole-class or whole-module basis
Fixes:
* code reduction and "de-magification" (e.g. 23 KLoc -> 11 KLOC)
* distribute testing requires the now separately released execnet_ package
* funcarg-setup/caching, "same-name" test modules now cause an exlicit error
* de-cluttered reporting options, --report for skipped/xfail details
Compatibilities
1.1.0 should allow running test code that already worked well with 1.0.2
plus some more due to improved unittest/nose compatibility.
More information: http://pytest.org
thanks and have fun,
holger (http://twitter.com/hpk42)
.. _execnet: http://codespeak.net/execnet
.. _`easy to install`: ../install.html
.. _marking: ../test/plugin/mark.html
.. _skipping: ../test/plugin/skipping.html
Changelog 1.0.2 -> 1.1.0
-----------------------------------------------------------------------
* remove py.rest tool and internal namespace - it was
never really advertised and can still be used with
the old release if needed. If there is interest
it could be revived into its own tool i guess.
* fix issue48 and issue59: raise an Error if the module
from an imported test file does not seem to come from
the filepath - avoids "same-name" confusion that has
been reported repeatedly
* merged Ronny's nose-compatibility hacks: now
nose-style setup_module() and setup() functions are
supported
* introduce generalized py.test.mark function marking
* reshuffle / refine command line grouping
* deprecate parser.addgroup in favour of getgroup which creates option group
* add --report command line option that allows to control showing of skipped/xfailed sections
* generalized skipping: a new way to mark python functions with skipif or xfail
at function, class and modules level based on platform or sys-module attributes.
* extend py.test.mark decorator to allow for positional args
* introduce and test "py.cleanup -d" to remove empty directories
* fix issue #59 - robustify unittest test collection
* make bpython/help interaction work by adding an __all__ attribute
to ApiModule, cleanup initpkg
* use MIT license for pylib, add some contributors
* remove py.execnet code and substitute all usages with 'execnet' proper
* fix issue50 - cached_setup now caches more to expectations
for test functions with multiple arguments.
* merge Jarko's fixes, issue #45 and #46
* add the ability to specify a path for py.lookup to search in
* fix a funcarg cached_setup bug probably only occuring
in distributed testing and "module" scope with teardown.
* many fixes and changes for making the code base python3 compatible,
many thanks to Benjamin Peterson for helping with this.
* consolidate builtins implementation to be compatible with >=2.3,
add helpers to ease keeping 2 and 3k compatible code
* deprecate py.compat.doctest|subprocess|textwrap|optparse
* deprecate py.magic.autopath, remove py/magic directory
* move pytest assertion handling to py/code and a pytest_assertion
plugin, add "--no-assert" option, deprecate py.magic namespaces
in favour of (less) py.code ones.
* consolidate and cleanup py/code classes and files
* cleanup py/misc, move tests to bin-for-dist
* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
* consolidate py.log implementation, remove old approach.
* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
text/unicode and byte-streams (uses underlying standard lib io.*
if available)
* make py.unittest_convert helper script available which converts "unittest.py"
style files into the simpler assert/direct-test-classes py.test/nosetests
style. The script was written by Laura Creighton.
* simplified internal localpath implementation

View File

@@ -0,0 +1,48 @@
py.test/pylib 1.1.1: bugfix release, setuptools plugin registration
--------------------------------------------------------------------------------
This is a compatibility fixing release of pylib/py.test to work
better with previous 1.0.x test code bases. It also contains fixes
and changes to work with `execnet>=1.0.0`_ to provide distributed
testing and looponfailing testing modes. py-1.1.1 also introduces
a new mechanism for registering plugins via setuptools.
What is pylib/py.test?
-----------------------
py.test is an advanced automated testing tool working with
Python2, Python3 and Jython versions on all major operating
systems. It has an extensive plugin architecture and can run many
existing common Python test suites without modification. Moreover,
it offers some unique features not found in other
testing tools. See http://pytest.org for more info.
The pylib also contains a localpath and svnpath implementation
and some developer-oriented command line tools. See
http://pylib.org for more info.
thanks to all who helped and gave feedback,
have fun,
holger (http://twitter.com/hpk42)
.. _`execnet>=1.0.0`: http://codespeak.net/execnet
Changes between 1.1.1 and 1.1.0
=====================================
- introduce automatic plugin registration via 'pytest11'
entrypoints via setuptools' pkg_resources.iter_entry_points
- fix py.test dist-testing to work with execnet >= 1.0.0b4
- re-introduce py.test.cmdline.main() for better backward compatibility
- svn paths: fix a bug with path.check(versioned=True) for svn paths,
allow '%' in svn paths, make svnwc.update() default to interactive mode
like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
- refine distributed tarball to contain test and no pyc files
- try harder to have deprecation warnings for py.compat.* accesses
report a correct location

View File

@@ -0,0 +1,116 @@
py.test/pylib 1.2.0: junitxml, standalone test scripts, pluginization
--------------------------------------------------------------------------------
py.test is an advanced automated testing tool working with
Python2, Python3 and Jython versions on all major operating
systems. It has a simple plugin architecture and can run many
existing common Python test suites without modification. It offers
some unique features not found in other testing tools.
See http://pytest.org for more info.
py.test 1.2.0 brings many bug fixes and interesting new abilities:
* --junitxml=path will create an XML file for use with CI processing
* --genscript=path creates a standalone py.test-equivalent test-script
* --ignore=path prevents collection of anything below that path
* --confcutdir=path only lookup conftest.py test configs below that path
* a 'pytest_report_header' hook to add info to the terminal report header
* a 'pytestconfig' function argument gives direct access to option values
* 'pytest_generate_tests' can now be put into a class as well
* on CPython py.test additionally installs as "py.test-VERSION", on
Jython as py.test-jython and on PyPy as py.test-pypy-XYZ
Apart from many bug fixes 1.2.0 also has better pluginization:
Distributed testing and looponfailing testing now live in the
separately installable 'pytest-xdist' plugin. The same is true for
'pytest-figleaf' for doing coverage reporting. Those two plugins
can serve well now as blue prints for doing your own.
thanks to all who helped and gave feedback,
have fun,
holger krekel, January 2010
Changes between 1.2.0 and 1.1.1
=====================================
- moved dist/looponfailing from py.test core into a new
separately released pytest-xdist plugin.
- new junitxml plugin: --junitxml=path will generate a junit style xml file
which is processable e.g. by the Hudson CI system.
- new option: --genscript=path will generate a standalone py.test script
which will not need any libraries installed. thanks to Ralf Schmitt.
- new option: --ignore will prevent specified path from collection.
Can be specified multiple times.
- new option: --confcutdir=dir will make py.test only consider conftest
files that are relative to the specified dir.
- new funcarg: "pytestconfig" is the pytest config object for access
to command line args and can now be easily used in a test.
- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
disambiguate between Python3, python2.X, Jython and PyPy installed versions.
- new "pytestconfig" funcarg allows access to test config object
- new "pytest_report_header" hook can return additional lines
to be displayed at the header of a test run.
- (experimental) allow "py.test path::name1::name2::..." for pointing
to a test within a test collection directly. This might eventually
evolve as a full substitute to "-k" specifications.
- streamlined plugin loading: order is now as documented in
customize.html: setuptools, ENV, commandline, conftest.
also setuptools entry point names are turned to canonical namees ("pytest_*")
- automatically skip tests that need 'capfd' but have no os.dup
- allow pytest_generate_tests to be defined in classes as well
- deprecate usage of 'disabled' attribute in favour of pytestmark
- deprecate definition of Directory, Module, Class and Function nodes
in conftest.py files. Use pytest collect hooks instead.
- collection/item node specific runtest/collect hooks are only called exactly
on matching conftest.py files, i.e. ones which are exactly below
the filesystem path of an item
- change: the first pytest_collect_directory hook to return something
will now prevent further hooks to be called.
- change: figleaf plugin now requires --figleaf to run. Also
change its long command line options to be a bit shorter (see py.test -h).
- change: pytest doctest plugin is now enabled by default and has a
new option --doctest-glob to set a pattern for file matches.
- change: remove internal py._* helper vars, only keep py._pydir
- robustify capturing to survive if custom pytest_runtest_setup
code failed and prevented the capturing setup code from running.
- make py.test.* helpers provided by default plugins visible early -
works transparently both for pydoc and for interactive sessions
which will regularly see e.g. py.test.mark and py.test.importorskip.
- simplify internal plugin manager machinery
- simplify internal collection tree by introducing a RootCollector node
- fix assert reinterpreation that sees a call containing "keyword=..."
- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
hooks on slaves during dist-testing, report module/session teardown
hooks correctly.
- fix issue65: properly handle dist-testing if no
execnet/py lib installed remotely.
- skip some install-tests if no execnet is available
- fix docs, fix internal bin/ script generation

View File

@@ -0,0 +1,66 @@
py.test/pylib 1.2.1: little fixes and improvements
--------------------------------------------------------------------------------
py.test is an advanced automated testing tool working with
Python2, Python3 and Jython versions on all major operating
systems. It has a simple plugin architecture and can run many
existing common Python test suites without modification. It offers
some unique features not found in other testing tools.
See http://pytest.org for more info.
py.test 1.2.1 brings bug fixes and some new options and abilities triggered
by user feedback:
* --funcargs [testpath] will show available builtin- and project funcargs.
* display a short and concise traceback if funcarg lookup fails.
* early-load "conftest.py" files in non-dot first-level sub directories.
* --tb=line will print a single line for each failing test (issue67)
* py.cleanup has a number of new options, cleanups up setup.py related files
* fix issue78: always call python-level teardown functions even if the
according setup failed.
For more detailed information see the changelog below.
cheers and have fun,
holger
Changes between 1.2.1 and 1.2.0
=====================================
- refined usage and options for "py.cleanup"::
py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
py.cleanup -e .swp -e .cache # also remove files with these extensions
py.cleanup -s # remove "build" and "dist" directory next to setup.py files
py.cleanup -d # also remove empty directories
py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
py.cleanup -n # dry run, only show what would be removed
- add a new option "py.test --funcargs" which shows available funcargs
and their help strings (docstrings on their respective factory function)
for a given test path
- display a short and concise traceback if a funcarg lookup fails
- early-load "conftest.py" files in non-dot first-level sub directories.
allows to conveniently keep and access test-related options in a ``test``
subdir and still add command line options.
- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
- fix issue78: always call python-level teardown functions even if the
according setup failed. This includes refinements for calling setup_module/class functions
which will now only be called once instead of the previous behaviour where they'd be called
multiple times if they raise an exception (including a Skipped exception). Any exception
will be re-corded and associated with all tests in the according module/class scope.
- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
- fix pdb debugging to be in the correct frame on raises-related errors
- update apipkg.py to fix an issue where recursive imports might
unnecessarily break importing
- fix plugin links

View File

@@ -0,0 +1,580 @@
py.test/pylib 1.3.0: new options, per-plugin hooks, fixes ...
===========================================================================
The 1.3.0 release introduces new options, bug fixes and improved compatibility
with Python3 and Jython-2.5.1 on Windows. If you already use py-1.2 chances
are you can use py-1.3.0. See the below CHANGELOG for more details and
http://pylib.org/install.html for installation instructions.
py.test is an advanced automated testing tool working with Python2,
Python3, Jython and PyPy versions on all major operating systems. It
offers a no-boilerplate testing approach and has inspired other testing
tools and enhancements in the standard Python library for more than five
years. It has a simple and extensive plugin architecture, configurable
reporting and provides unique ways to make it fit to your testing
process and needs.
See http://pytest.org for more info.
cheers and have fun,
holger krekel
Changes between 1.2.1 and 1.3.0
==================================================
- deprecate --report option in favour of a new shorter and easier to
remember -r option: it takes a string argument consisting of any
combination of 'xfsX' characters. They relate to the single chars
you see during the dotted progress printing and will print an extra line
per test at the end of the test run. This extra line indicates the exact
position or test ID that you directly paste to the py.test cmdline in order
to re-run a particular test.
- allow external plugins to register new hooks via the new
pytest_addhooks(pluginmanager) hook. The new release of
the pytest-xdist plugin for distributed and looponfailing
testing requires this feature.
- add a new pytest_ignore_collect(path, config) hook to allow projects and
plugins to define exclusion behaviour for their directory structure -
for example you may define in a conftest.py this method::
def pytest_ignore_collect(path):
return path.check(link=1)
to prevent even collection of any tests in symlinked dirs.
- new pytest_pycollect_makemodule(path, parent) hook for
allowing customization of the Module collection object for a
matching test module.
- extend and refine xfail mechanism::
@py.test.mark.xfail(run=False) do not run the decorated test
@py.test.mark.xfail(reason="...") prints the reason string in xfail summaries
specifiying ``--runxfail`` on command line ignores xfail markers to show
you the underlying traceback.
- expose (previously internal) commonly useful methods:
py.io.get_terminal_with() -> return terminal width
py.io.ansi_print(...) -> print colored/bold text on linux/win32
py.io.saferepr(obj) -> return limited representation string
- expose test outcome related exceptions as py.test.skip.Exception,
py.test.raises.Exception etc., useful mostly for plugins
doing special outcome interpretation/tweaking
- (issue85) fix junitxml plugin to handle tests with non-ascii output
- fix/refine python3 compatibility (thanks Benjamin Peterson)
- fixes for making the jython/win32 combination work, note however:
jython2.5.1/win32 does not provide a command line launcher, see
http://bugs.jython.org/issue1491 . See pylib install documentation
for how to work around.
- fixes for handling of unicode exception values and unprintable objects
- (issue87) fix unboundlocal error in assertionold code
- (issue86) improve documentation for looponfailing
- refine IO capturing: stdin-redirect pseudo-file now has a NOP close() method
- ship distribute_setup.py version 0.6.10
- added links to the new capturelog and coverage plugins
Changes between 1.2.1 and 1.2.0
=====================================
- refined usage and options for "py.cleanup"::
py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
py.cleanup -e .swp -e .cache # also remove files with these extensions
py.cleanup -s # remove "build" and "dist" directory next to setup.py files
py.cleanup -d # also remove empty directories
py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
py.cleanup -n # dry run, only show what would be removed
- add a new option "py.test --funcargs" which shows available funcargs
and their help strings (docstrings on their respective factory function)
for a given test path
- display a short and concise traceback if a funcarg lookup fails
- early-load "conftest.py" files in non-dot first-level sub directories.
allows to conveniently keep and access test-related options in a ``test``
subdir and still add command line options.
- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
- fix issue78: always call python-level teardown functions even if the
according setup failed. This includes refinements for calling setup_module/class functions
which will now only be called once instead of the previous behaviour where they'd be called
multiple times if they raise an exception (including a Skipped exception). Any exception
will be re-corded and associated with all tests in the according module/class scope.
- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
- fix pdb debugging to be in the correct frame on raises-related errors
- update apipkg.py to fix an issue where recursive imports might
unnecessarily break importing
- fix plugin links
Changes between 1.2 and 1.1.1
=====================================
- moved dist/looponfailing from py.test core into a new
separately released pytest-xdist plugin.
- new junitxml plugin: --junitxml=path will generate a junit style xml file
which is processable e.g. by the Hudson CI system.
- new option: --genscript=path will generate a standalone py.test script
which will not need any libraries installed. thanks to Ralf Schmitt.
- new option: --ignore will prevent specified path from collection.
Can be specified multiple times.
- new option: --confcutdir=dir will make py.test only consider conftest
files that are relative to the specified dir.
- new funcarg: "pytestconfig" is the pytest config object for access
to command line args and can now be easily used in a test.
- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
disambiguate between Python3, python2.X, Jython and PyPy installed versions.
- new "pytestconfig" funcarg allows access to test config object
- new "pytest_report_header" hook can return additional lines
to be displayed at the header of a test run.
- (experimental) allow "py.test path::name1::name2::..." for pointing
to a test within a test collection directly. This might eventually
evolve as a full substitute to "-k" specifications.
- streamlined plugin loading: order is now as documented in
customize.html: setuptools, ENV, commandline, conftest.
also setuptools entry point names are turned to canonical namees ("pytest_*")
- automatically skip tests that need 'capfd' but have no os.dup
- allow pytest_generate_tests to be defined in classes as well
- deprecate usage of 'disabled' attribute in favour of pytestmark
- deprecate definition of Directory, Module, Class and Function nodes
in conftest.py files. Use pytest collect hooks instead.
- collection/item node specific runtest/collect hooks are only called exactly
on matching conftest.py files, i.e. ones which are exactly below
the filesystem path of an item
- change: the first pytest_collect_directory hook to return something
will now prevent further hooks to be called.
- change: figleaf plugin now requires --figleaf to run. Also
change its long command line options to be a bit shorter (see py.test -h).
- change: pytest doctest plugin is now enabled by default and has a
new option --doctest-glob to set a pattern for file matches.
- change: remove internal py._* helper vars, only keep py._pydir
- robustify capturing to survive if custom pytest_runtest_setup
code failed and prevented the capturing setup code from running.
- make py.test.* helpers provided by default plugins visible early -
works transparently both for pydoc and for interactive sessions
which will regularly see e.g. py.test.mark and py.test.importorskip.
- simplify internal plugin manager machinery
- simplify internal collection tree by introducing a RootCollector node
- fix assert reinterpreation that sees a call containing "keyword=..."
- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
hooks on slaves during dist-testing, report module/session teardown
hooks correctly.
- fix issue65: properly handle dist-testing if no
execnet/py lib installed remotely.
- skip some install-tests if no execnet is available
- fix docs, fix internal bin/ script generation
Changes between 1.1.1 and 1.1.0
=====================================
- introduce automatic plugin registration via 'pytest11'
entrypoints via setuptools' pkg_resources.iter_entry_points
- fix py.test dist-testing to work with execnet >= 1.0.0b4
- re-introduce py.test.cmdline.main() for better backward compatibility
- svn paths: fix a bug with path.check(versioned=True) for svn paths,
allow '%' in svn paths, make svnwc.update() default to interactive mode
like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
- refine distributed tarball to contain test and no pyc files
- try harder to have deprecation warnings for py.compat.* accesses
report a correct location
Changes between 1.1.0 and 1.0.2
=====================================
* adjust and improve docs
* remove py.rest tool and internal namespace - it was
never really advertised and can still be used with
the old release if needed. If there is interest
it could be revived into its own tool i guess.
* fix issue48 and issue59: raise an Error if the module
from an imported test file does not seem to come from
the filepath - avoids "same-name" confusion that has
been reported repeatedly
* merged Ronny's nose-compatibility hacks: now
nose-style setup_module() and setup() functions are
supported
* introduce generalized py.test.mark function marking
* reshuffle / refine command line grouping
* deprecate parser.addgroup in favour of getgroup which creates option group
* add --report command line option that allows to control showing of skipped/xfailed sections
* generalized skipping: a new way to mark python functions with skipif or xfail
at function, class and modules level based on platform or sys-module attributes.
* extend py.test.mark decorator to allow for positional args
* introduce and test "py.cleanup -d" to remove empty directories
* fix issue #59 - robustify unittest test collection
* make bpython/help interaction work by adding an __all__ attribute
to ApiModule, cleanup initpkg
* use MIT license for pylib, add some contributors
* remove py.execnet code and substitute all usages with 'execnet' proper
* fix issue50 - cached_setup now caches more to expectations
for test functions with multiple arguments.
* merge Jarko's fixes, issue #45 and #46
* add the ability to specify a path for py.lookup to search in
* fix a funcarg cached_setup bug probably only occuring
in distributed testing and "module" scope with teardown.
* many fixes and changes for making the code base python3 compatible,
many thanks to Benjamin Peterson for helping with this.
* consolidate builtins implementation to be compatible with >=2.3,
add helpers to ease keeping 2 and 3k compatible code
* deprecate py.compat.doctest|subprocess|textwrap|optparse
* deprecate py.magic.autopath, remove py/magic directory
* move pytest assertion handling to py/code and a pytest_assertion
plugin, add "--no-assert" option, deprecate py.magic namespaces
in favour of (less) py.code ones.
* consolidate and cleanup py/code classes and files
* cleanup py/misc, move tests to bin-for-dist
* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
* consolidate py.log implementation, remove old approach.
* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
text/unicode and byte-streams (uses underlying standard lib io.*
if available)
* make py.unittest_convert helper script available which converts "unittest.py"
style files into the simpler assert/direct-test-classes py.test/nosetests
style. The script was written by Laura Creighton.
* simplified internal localpath implementation
Changes between 1.0.1 and 1.0.2
=====================================
* fixing packaging issues, triggered by fedora redhat packaging,
also added doc, examples and contrib dirs to the tarball.
* added a documentation link to the new django plugin.
Changes between 1.0.0 and 1.0.1
=====================================
* added a 'pytest_nose' plugin which handles nose.SkipTest,
nose-style function/method/generator setup/teardown and
tries to report functions correctly.
* capturing of unicode writes or encoded strings to sys.stdout/err
work better, also terminalwriting was adapted and somewhat
unified between windows and linux.
* improved documentation layout and content a lot
* added a "--help-config" option to show conftest.py / ENV-var names for
all longopt cmdline options, and some special conftest.py variables.
renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
* fix issue #27: better reporting on non-collectable items given on commandline
(e.g. pyc files)
* fix issue #33: added --version flag (thanks Benjamin Peterson)
* fix issue #32: adding support for "incomplete" paths to wcpath.status()
* "Test" prefixed classes are *not* collected by default anymore if they
have an __init__ method
* monkeypatch setenv() now accepts a "prepend" parameter
* improved reporting of collection error tracebacks
* simplified multicall mechanism and plugin architecture,
renamed some internal methods and argnames
Changes between 1.0.0b9 and 1.0.0
=====================================
* more terse reporting try to show filesystem path relatively to current dir
* improve xfail output a bit
Changes between 1.0.0b8 and 1.0.0b9
=====================================
* cleanly handle and report final teardown of test setup
* fix svn-1.6 compat issue with py.path.svnwc().versioned()
(thanks Wouter Vanden Hove)
* setup/teardown or collection problems now show as ERRORs
or with big "E"'s in the progress lines. they are reported
and counted separately.
* dist-testing: properly handle test items that get locally
collected but cannot be collected on the remote side - often
due to platform/dependency reasons
* simplified py.test.mark API - see keyword plugin documentation
* integrate better with logging: capturing now by default captures
test functions and their immediate setup/teardown in a single stream
* capsys and capfd funcargs now have a readouterr() and a close() method
(underlyingly py.io.StdCapture/FD objects are used which grew a
readouterr() method as well to return snapshots of captured out/err)
* make assert-reinterpretation work better with comparisons not
returning bools (reported with numpy from thanks maciej fijalkowski)
* reworked per-test output capturing into the pytest_iocapture.py plugin
and thus removed capturing code from config object
* item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr)
Changes between 1.0.0b7 and 1.0.0b8
=====================================
* pytest_unittest-plugin is now enabled by default
* introduced pytest_keyboardinterrupt hook and
refined pytest_sessionfinish hooked, added tests.
* workaround a buggy logging module interaction ("closing already closed
files"). Thanks to Sridhar Ratnakumar for triggering.
* if plugins use "py.test.importorskip" for importing
a dependency only a warning will be issued instead
of exiting the testing process.
* many improvements to docs:
- refined funcargs doc , use the term "factory" instead of "provider"
- added a new talk/tutorial doc page
- better download page
- better plugin docstrings
- added new plugins page and automatic doc generation script
* fixed teardown problem related to partially failing funcarg setups
(thanks MrTopf for reporting), "pytest_runtest_teardown" is now
always invoked even if the "pytest_runtest_setup" failed.
* tweaked doctest output for docstrings in py modules,
thanks Radomir.
Changes between 1.0.0b3 and 1.0.0b7
=============================================
* renamed py.test.xfail back to py.test.mark.xfail to avoid
two ways to decorate for xfail
* re-added py.test.mark decorator for setting keywords on functions
(it was actually documented so removing it was not nice)
* remove scope-argument from request.addfinalizer() because
request.cached_setup has the scope arg. TOOWTDI.
* perform setup finalization before reporting failures
* apply modified patches from Andreas Kloeckner to allow
test functions to have no func_code (#22) and to make
"-k" and function keywords work (#20)
* apply patch from Daniel Peolzleithner (issue #23)
* resolve issue #18, multiprocessing.Manager() and
redirection clash
* make __name__ == "__channelexec__" for remote_exec code
Changes between 1.0.0b1 and 1.0.0b3
=============================================
* plugin classes are removed: one now defines
hooks directly in conftest.py or global pytest_*.py
files.
* added new pytest_namespace(config) hook that allows
to inject helpers directly to the py.test.* namespace.
* documented and refined many hooks
* added new style of generative tests via
pytest_generate_tests hook that integrates
well with function arguments.
Changes between 0.9.2 and 1.0.0b1
=============================================
* introduced new "funcarg" setup method,
see doc/test/funcarg.txt
* introduced plugin architecuture and many
new py.test plugins, see
doc/test/plugins.txt
* teardown_method is now guaranteed to get
called after a test method has run.
* new method: py.test.importorskip(mod,minversion)
will either import or call py.test.skip()
* completely revised internal py.test architecture
* new py.process.ForkedFunc object allowing to
fork execution of a function to a sub process
and getting a result back.
XXX lots of things missing here XXX
Changes between 0.9.1 and 0.9.2
===============================
* refined installation and metadata, created new setup.py,
now based on setuptools/ez_setup (thanks to Ralf Schmitt
for his support).
* improved the way of making py.* scripts available in
windows environments, they are now added to the
Scripts directory as ".cmd" files.
* py.path.svnwc.status() now is more complete and
uses xml output from the 'svn' command if available
(Guido Wesdorp)
* fix for py.path.svn* to work with svn 1.5
(Chris Lamb)
* fix path.relto(otherpath) method on windows to
use normcase for checking if a path is relative.
* py.test's traceback is better parseable from editors
(follows the filenames:LINENO: MSG convention)
(thanks to Osmo Salomaa)
* fix to javascript-generation, "py.test --runbrowser"
should work more reliably now
* removed previously accidentally added
py.test.broken and py.test.notimplemented helpers.
* there now is a py.__version__ attribute
Changes between 0.9.0 and 0.9.1
===============================
This is a fairly complete list of changes between 0.9 and 0.9.1, which can
serve as a reference for developers.
* allowing + signs in py.path.svn urls [39106]
* fixed support for Failed exceptions without excinfo in py.test [39340]
* added support for killing processes for Windows (as well as platforms that
support os.kill) in py.misc.killproc [39655]
* added setup/teardown for generative tests to py.test [40702]
* added detection of FAILED TO LOAD MODULE to py.test [40703, 40738, 40739]
* fixed problem with calling .remove() on wcpaths of non-versioned files in
py.path [44248]
* fixed some import and inheritance issues in py.test [41480, 44648, 44655]
* fail to run greenlet tests when pypy is available, but without stackless
[45294]
* small fixes in rsession tests [45295]
* fixed issue with 2.5 type representations in py.test [45483, 45484]
* made that internal reporting issues displaying is done atomically in py.test
[45518]
* made that non-existing files are igored by the py.lookup script [45519]
* improved exception name creation in py.test [45535]
* made that less threads are used in execnet [merge in 45539]
* removed lock required for atomical reporting issue displaying in py.test
[45545]
* removed globals from execnet [45541, 45547]
* refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit
get called in 2.5 (py.execnet) [45548]
* fixed bug in joining threads in py.execnet's servemain [45549]
* refactored py.test.rsession tests to not rely on exact output format anymore
[45646]
* using repr() on test outcome [45647]
* added 'Reason' classes for py.test.skip() [45648, 45649]
* killed some unnecessary sanity check in py.test.collect [45655]
* avoid using os.tmpfile() in py.io.fdcapture because on Windows it's only
usable by Administrators [45901]
* added support for locking and non-recursive commits to py.path.svnwc [45994]
* locking files in py.execnet to prevent CPython from segfaulting [46010]
* added export() method to py.path.svnurl
* fixed -d -x in py.test [47277]
* fixed argument concatenation problem in py.path.svnwc [49423]
* restore py.test behaviour that it exits with code 1 when there are failures
[49974]
* don't fail on html files that don't have an accompanying .txt file [50606]
* fixed 'utestconvert.py < input' [50645]
* small fix for code indentation in py.code.source [50755]
* fix _docgen.py documentation building [51285]
* improved checks for source representation of code blocks in py.test [51292]
* added support for passing authentication to py.path.svn* objects [52000,
52001]
* removed sorted() call for py.apigen tests in favour of [].sort() to support
Python 2.3 [52481]

View File

@@ -0,0 +1,104 @@
py.test/pylib 1.3.1: new py.test.xfail, --maxfail, better reporting
===========================================================================
The pylib/py.test 1.3.1 release brings:
- the new imperative ``py.test.xfail()`` helper in order to have a test or
setup function result in an "expected failure"
- a new option ``--maxfail=NUM`` to stop the test run after some failures
- markers/decorators are now applicable to test classes (>=Python2.6)
- improved reporting, shorter tracebacks in several cases
- some simplified internals, more compatibility with Jython and PyPy
- bug fixes and various refinements
See the below CHANGELOG entry below for more details and
http://pylib.org/install.html for installation instructions.
If you used older versions of py.test you should be able to upgrade
to 1.3.1 without changes to your test source code.
py.test is an automated testing tool working with Python2,
Python3, Jython and PyPy versions on all major operating systems. It
offers a no-boilerplate testing approach and has inspired other testing
tools and enhancements in the standard Python library for more than five
years. It has a simple and extensive plugin architecture, configurable
reporting and provides unique ways to make it fit to your testing
process and needs.
See http://pytest.org for more info.
cheers and have fun,
holger krekel
Changes between 1.3.0 and 1.3.1
==================================================
New features
++++++++++++++++++
- issue91: introduce new py.test.xfail(reason) helper
to imperatively mark a test as expected to fail. Can
be used from within setup and test functions. This is
useful especially for parametrized tests when certain
configurations are expected-to-fail. In this case the
declarative approach with the @py.test.mark.xfail cannot
be used as it would mark all configurations as xfail.
- issue102: introduce new --maxfail=NUM option to stop
test runs after NUM failures. This is a generalization
of the '-x' or '--exitfirst' option which is now equivalent
to '--maxfail=1'. Both '-x' and '--maxfail' will
now also print a line near the end indicating the Interruption.
- issue89: allow py.test.mark decorators to be used on classes
(class decorators were introduced with python2.6) and
also allow to have multiple markers applied at class/module level
by specifying a list.
- improve and refine letter reporting in the progress bar:
. pass
f failed test
s skipped tests (reminder: use for dependency/platform mismatch only)
x xfailed test (test that was expected to fail)
X xpassed test (test that was expected to fail but passed)
You can use any combination of 'fsxX' with the '-r' extended
reporting option. The xfail/xpass results will show up as
skipped tests in the junitxml output - which also fixes
issue99.
- make py.test.cmdline.main() return the exitstatus instead of raising
SystemExit and also allow it to be called multiple times. This of
course requires that your application and tests are properly teared
down and don't have global state.
Fixes / Maintenance
++++++++++++++++++++++
- improved traceback presentation:
- improved and unified reporting for "--tb=short" option
- Errors during test module imports are much shorter, (using --tb=short style)
- raises shows shorter more relevant tracebacks
- --fulltrace now more systematically makes traces longer / inhibits cutting
- improve support for raises and other dynamically compiled code by
manipulating python's linecache.cache instead of the previous
rather hacky way of creating custom code objects. This makes
it seemlessly work on Jython and PyPy where it previously didn't.
- fix issue96: make capturing more resilient against Control-C
interruptions (involved somewhat substantial refactoring
to the underlying capturing functionality to avoid race
conditions).
- fix chaining of conditional skipif/xfail decorators - so it works now
as expected to use multiple @py.test.mark.skipif(condition) decorators,
including specific reporting which of the conditions lead to skipping.
- fix issue95: late-import zlib so that it's not required
for general py.test startup.
- fix issue94: make reporting more robust against bogus source code
(and internally be more careful when presenting unexpected byte sequences)

View File

@@ -0,0 +1,720 @@
py.test/pylib 1.3.2: API and reporting refinements, many fixes
===========================================================================
The pylib/py.test 1.3.2 release brings many bug fixes and some new
features. It was refined for and tested against the recently released
Python2.7 and remains compatibile to the usual armada of interpreters
(Python2.4 through to Python3.1.2, Jython and PyPy). Note that for using
distributed testing features you'll need to upgrade to the jointly released
pytest-xdist-1.4 because of some internal refactorings.
See http://pytest.org for general documentation and below for
a detailed CHANGELOG.
cheers & particular thanks to Benjamin Peterson, Ronny Pfannschmidt
and all issue and patch contributors,
holger krekel
Changes between 1.3.1 and 1.3.2
==================================================
New features
++++++++++++++++++
- fix issue103: introduce py.test.raises as context manager, examples::
with py.test.raises(ZeroDivisionError):
x = 0
1 / x
with py.test.raises(RuntimeError) as excinfo:
call_something()
# you may do extra checks on excinfo.value|type|traceback here
(thanks Ronny Pfannschmidt)
- Funcarg factories can now dynamically apply a marker to a
test invocation. This is for example useful if a factory
provides parameters to a test which are expected-to-fail::
def pytest_funcarg__arg(request):
request.applymarker(py.test.mark.xfail(reason="flaky config"))
...
def test_function(arg):
...
- improved error reporting on collection and import errors. This makes
use of a more general mechanism, namely that for custom test item/collect
nodes ``node.repr_failure(excinfo)`` is now uniformly called so that you can
override it to return a string error representation of your choice
which is going to be reported as a (red) string.
- introduce '--junitprefix=STR' option to prepend a prefix
to all reports in the junitxml file.
Bug fixes / Maintenance
++++++++++++++++++++++++++
- make tests and the ``pytest_recwarn`` plugin in particular fully compatible
to Python2.7 (if you use the ``recwarn`` funcarg warnings will be enabled so that
you can properly check for their existence in a cross-python manner).
- refine --pdb: ignore xfailed tests, unify its TB-reporting and
don't display failures again at the end.
- fix assertion interpretation with the ** operator (thanks Benjamin Peterson)
- fix issue105 assignment on the same line as a failing assertion (thanks Benjamin Peterson)
- fix issue104 proper escaping for test names in junitxml plugin (thanks anonymous)
- fix issue57 -f|--looponfail to work with xpassing tests (thanks Ronny)
- fix issue92 collectonly reporter and --pastebin (thanks Benjamin Peterson)
- fix py.code.compile(source) to generate unique filenames
- fix assertion re-interp problems on PyPy, by defering code
compilation to the (overridable) Frame.eval class. (thanks Amaury Forgeot)
- fix py.path.local.pyimport() to work with directories
- streamline py.path.local.mkdtemp implementation and usage
- don't print empty lines when showing junitxml-filename
- add optional boolean ignore_errors parameter to py.path.local.remove
- fix terminal writing on win32/python2.4
- py.process.cmdexec() now tries harder to return properly encoded unicode objects
on all python versions
- install plain py.test/py.which scripts also for Jython, this helps to
get canonical script paths in virtualenv situations
- make path.bestrelpath(path) return ".", note that when calling
X.bestrelpath the assumption is that X is a directory.
- make initial conftest discovery ignore "--" prefixed arguments
- fix resultlog plugin when used in an multicpu/multihost xdist situation
(thanks Jakub Gustak)
- perform distributed testing related reporting in the xdist-plugin
rather than having dist-related code in the generic py.test
distribution
- fix homedir detection on Windows
- ship distribute_setup.py version 0.6.13
Changes between 1.3.0 and 1.3.1
==================================================
New features
++++++++++++++++++
- issue91: introduce new py.test.xfail(reason) helper
to imperatively mark a test as expected to fail. Can
be used from within setup and test functions. This is
useful especially for parametrized tests when certain
configurations are expected-to-fail. In this case the
declarative approach with the @py.test.mark.xfail cannot
be used as it would mark all configurations as xfail.
- issue102: introduce new --maxfail=NUM option to stop
test runs after NUM failures. This is a generalization
of the '-x' or '--exitfirst' option which is now equivalent
to '--maxfail=1'. Both '-x' and '--maxfail' will
now also print a line near the end indicating the Interruption.
- issue89: allow py.test.mark decorators to be used on classes
(class decorators were introduced with python2.6) and
also allow to have multiple markers applied at class/module level
by specifying a list.
- improve and refine letter reporting in the progress bar:
. pass
f failed test
s skipped tests (reminder: use for dependency/platform mismatch only)
x xfailed test (test that was expected to fail)
X xpassed test (test that was expected to fail but passed)
You can use any combination of 'fsxX' with the '-r' extended
reporting option. The xfail/xpass results will show up as
skipped tests in the junitxml output - which also fixes
issue99.
- make py.test.cmdline.main() return the exitstatus instead of raising
SystemExit and also allow it to be called multiple times. This of
course requires that your application and tests are properly teared
down and don't have global state.
Fixes / Maintenance
++++++++++++++++++++++
- improved traceback presentation:
- improved and unified reporting for "--tb=short" option
- Errors during test module imports are much shorter, (using --tb=short style)
- raises shows shorter more relevant tracebacks
- --fulltrace now more systematically makes traces longer / inhibits cutting
- improve support for raises and other dynamically compiled code by
manipulating python's linecache.cache instead of the previous
rather hacky way of creating custom code objects. This makes
it seemlessly work on Jython and PyPy where it previously didn't.
- fix issue96: make capturing more resilient against Control-C
interruptions (involved somewhat substantial refactoring
to the underlying capturing functionality to avoid race
conditions).
- fix chaining of conditional skipif/xfail decorators - so it works now
as expected to use multiple @py.test.mark.skipif(condition) decorators,
including specific reporting which of the conditions lead to skipping.
- fix issue95: late-import zlib so that it's not required
for general py.test startup.
- fix issue94: make reporting more robust against bogus source code
(and internally be more careful when presenting unexpected byte sequences)
Changes between 1.2.1 and 1.3.0
==================================================
- deprecate --report option in favour of a new shorter and easier to
remember -r option: it takes a string argument consisting of any
combination of 'xfsX' characters. They relate to the single chars
you see during the dotted progress printing and will print an extra line
per test at the end of the test run. This extra line indicates the exact
position or test ID that you directly paste to the py.test cmdline in order
to re-run a particular test.
- allow external plugins to register new hooks via the new
pytest_addhooks(pluginmanager) hook. The new release of
the pytest-xdist plugin for distributed and looponfailing
testing requires this feature.
- add a new pytest_ignore_collect(path, config) hook to allow projects and
plugins to define exclusion behaviour for their directory structure -
for example you may define in a conftest.py this method::
def pytest_ignore_collect(path):
return path.check(link=1)
to prevent even a collection try of any tests in symlinked dirs.
- new pytest_pycollect_makemodule(path, parent) hook for
allowing customization of the Module collection object for a
matching test module.
- extend and refine xfail mechanism:
``@py.test.mark.xfail(run=False)`` do not run the decorated test
``@py.test.mark.xfail(reason="...")`` prints the reason string in xfail summaries
specifiying ``--runxfail`` on command line virtually ignores xfail markers
- expose (previously internal) commonly useful methods:
py.io.get_terminal_with() -> return terminal width
py.io.ansi_print(...) -> print colored/bold text on linux/win32
py.io.saferepr(obj) -> return limited representation string
- expose test outcome related exceptions as py.test.skip.Exception,
py.test.raises.Exception etc., useful mostly for plugins
doing special outcome interpretation/tweaking
- (issue85) fix junitxml plugin to handle tests with non-ascii output
- fix/refine python3 compatibility (thanks Benjamin Peterson)
- fixes for making the jython/win32 combination work, note however:
jython2.5.1/win32 does not provide a command line launcher, see
http://bugs.jython.org/issue1491 . See pylib install documentation
for how to work around.
- fixes for handling of unicode exception values and unprintable objects
- (issue87) fix unboundlocal error in assertionold code
- (issue86) improve documentation for looponfailing
- refine IO capturing: stdin-redirect pseudo-file now has a NOP close() method
- ship distribute_setup.py version 0.6.10
- added links to the new capturelog and coverage plugins
Changes between 1.2.1 and 1.2.0
=====================================
- refined usage and options for "py.cleanup"::
py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
py.cleanup -e .swp -e .cache # also remove files with these extensions
py.cleanup -s # remove "build" and "dist" directory next to setup.py files
py.cleanup -d # also remove empty directories
py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
py.cleanup -n # dry run, only show what would be removed
- add a new option "py.test --funcargs" which shows available funcargs
and their help strings (docstrings on their respective factory function)
for a given test path
- display a short and concise traceback if a funcarg lookup fails
- early-load "conftest.py" files in non-dot first-level sub directories.
allows to conveniently keep and access test-related options in a ``test``
subdir and still add command line options.
- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
- fix issue78: always call python-level teardown functions even if the
according setup failed. This includes refinements for calling setup_module/class functions
which will now only be called once instead of the previous behaviour where they'd be called
multiple times if they raise an exception (including a Skipped exception). Any exception
will be re-corded and associated with all tests in the according module/class scope.
- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
- fix pdb debugging to be in the correct frame on raises-related errors
- update apipkg.py to fix an issue where recursive imports might
unnecessarily break importing
- fix plugin links
Changes between 1.2 and 1.1.1
=====================================
- moved dist/looponfailing from py.test core into a new
separately released pytest-xdist plugin.
- new junitxml plugin: --junitxml=path will generate a junit style xml file
which is processable e.g. by the Hudson CI system.
- new option: --genscript=path will generate a standalone py.test script
which will not need any libraries installed. thanks to Ralf Schmitt.
- new option: --ignore will prevent specified path from collection.
Can be specified multiple times.
- new option: --confcutdir=dir will make py.test only consider conftest
files that are relative to the specified dir.
- new funcarg: "pytestconfig" is the pytest config object for access
to command line args and can now be easily used in a test.
- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
disambiguate between Python3, python2.X, Jython and PyPy installed versions.
- new "pytestconfig" funcarg allows access to test config object
- new "pytest_report_header" hook can return additional lines
to be displayed at the header of a test run.
- (experimental) allow "py.test path::name1::name2::..." for pointing
to a test within a test collection directly. This might eventually
evolve as a full substitute to "-k" specifications.
- streamlined plugin loading: order is now as documented in
customize.html: setuptools, ENV, commandline, conftest.
also setuptools entry point names are turned to canonical namees ("pytest_*")
- automatically skip tests that need 'capfd' but have no os.dup
- allow pytest_generate_tests to be defined in classes as well
- deprecate usage of 'disabled' attribute in favour of pytestmark
- deprecate definition of Directory, Module, Class and Function nodes
in conftest.py files. Use pytest collect hooks instead.
- collection/item node specific runtest/collect hooks are only called exactly
on matching conftest.py files, i.e. ones which are exactly below
the filesystem path of an item
- change: the first pytest_collect_directory hook to return something
will now prevent further hooks to be called.
- change: figleaf plugin now requires --figleaf to run. Also
change its long command line options to be a bit shorter (see py.test -h).
- change: pytest doctest plugin is now enabled by default and has a
new option --doctest-glob to set a pattern for file matches.
- change: remove internal py._* helper vars, only keep py._pydir
- robustify capturing to survive if custom pytest_runtest_setup
code failed and prevented the capturing setup code from running.
- make py.test.* helpers provided by default plugins visible early -
works transparently both for pydoc and for interactive sessions
which will regularly see e.g. py.test.mark and py.test.importorskip.
- simplify internal plugin manager machinery
- simplify internal collection tree by introducing a RootCollector node
- fix assert reinterpreation that sees a call containing "keyword=..."
- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
hooks on slaves during dist-testing, report module/session teardown
hooks correctly.
- fix issue65: properly handle dist-testing if no
execnet/py lib installed remotely.
- skip some install-tests if no execnet is available
- fix docs, fix internal bin/ script generation
Changes between 1.1.1 and 1.1.0
=====================================
- introduce automatic plugin registration via 'pytest11'
entrypoints via setuptools' pkg_resources.iter_entry_points
- fix py.test dist-testing to work with execnet >= 1.0.0b4
- re-introduce py.test.cmdline.main() for better backward compatibility
- svn paths: fix a bug with path.check(versioned=True) for svn paths,
allow '%' in svn paths, make svnwc.update() default to interactive mode
like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
- refine distributed tarball to contain test and no pyc files
- try harder to have deprecation warnings for py.compat.* accesses
report a correct location
Changes between 1.1.0 and 1.0.2
=====================================
* adjust and improve docs
* remove py.rest tool and internal namespace - it was
never really advertised and can still be used with
the old release if needed. If there is interest
it could be revived into its own tool i guess.
* fix issue48 and issue59: raise an Error if the module
from an imported test file does not seem to come from
the filepath - avoids "same-name" confusion that has
been reported repeatedly
* merged Ronny's nose-compatibility hacks: now
nose-style setup_module() and setup() functions are
supported
* introduce generalized py.test.mark function marking
* reshuffle / refine command line grouping
* deprecate parser.addgroup in favour of getgroup which creates option group
* add --report command line option that allows to control showing of skipped/xfailed sections
* generalized skipping: a new way to mark python functions with skipif or xfail
at function, class and modules level based on platform or sys-module attributes.
* extend py.test.mark decorator to allow for positional args
* introduce and test "py.cleanup -d" to remove empty directories
* fix issue #59 - robustify unittest test collection
* make bpython/help interaction work by adding an __all__ attribute
to ApiModule, cleanup initpkg
* use MIT license for pylib, add some contributors
* remove py.execnet code and substitute all usages with 'execnet' proper
* fix issue50 - cached_setup now caches more to expectations
for test functions with multiple arguments.
* merge Jarko's fixes, issue #45 and #46
* add the ability to specify a path for py.lookup to search in
* fix a funcarg cached_setup bug probably only occuring
in distributed testing and "module" scope with teardown.
* many fixes and changes for making the code base python3 compatible,
many thanks to Benjamin Peterson for helping with this.
* consolidate builtins implementation to be compatible with >=2.3,
add helpers to ease keeping 2 and 3k compatible code
* deprecate py.compat.doctest|subprocess|textwrap|optparse
* deprecate py.magic.autopath, remove py/magic directory
* move pytest assertion handling to py/code and a pytest_assertion
plugin, add "--no-assert" option, deprecate py.magic namespaces
in favour of (less) py.code ones.
* consolidate and cleanup py/code classes and files
* cleanup py/misc, move tests to bin-for-dist
* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
* consolidate py.log implementation, remove old approach.
* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
text/unicode and byte-streams (uses underlying standard lib io.*
if available)
* make py.unittest_convert helper script available which converts "unittest.py"
style files into the simpler assert/direct-test-classes py.test/nosetests
style. The script was written by Laura Creighton.
* simplified internal localpath implementation
Changes between 1.0.1 and 1.0.2
=====================================
* fixing packaging issues, triggered by fedora redhat packaging,
also added doc, examples and contrib dirs to the tarball.
* added a documentation link to the new django plugin.
Changes between 1.0.0 and 1.0.1
=====================================
* added a 'pytest_nose' plugin which handles nose.SkipTest,
nose-style function/method/generator setup/teardown and
tries to report functions correctly.
* capturing of unicode writes or encoded strings to sys.stdout/err
work better, also terminalwriting was adapted and somewhat
unified between windows and linux.
* improved documentation layout and content a lot
* added a "--help-config" option to show conftest.py / ENV-var names for
all longopt cmdline options, and some special conftest.py variables.
renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
* fix issue #27: better reporting on non-collectable items given on commandline
(e.g. pyc files)
* fix issue #33: added --version flag (thanks Benjamin Peterson)
* fix issue #32: adding support for "incomplete" paths to wcpath.status()
* "Test" prefixed classes are *not* collected by default anymore if they
have an __init__ method
* monkeypatch setenv() now accepts a "prepend" parameter
* improved reporting of collection error tracebacks
* simplified multicall mechanism and plugin architecture,
renamed some internal methods and argnames
Changes between 1.0.0b9 and 1.0.0
=====================================
* more terse reporting try to show filesystem path relatively to current dir
* improve xfail output a bit
Changes between 1.0.0b8 and 1.0.0b9
=====================================
* cleanly handle and report final teardown of test setup
* fix svn-1.6 compat issue with py.path.svnwc().versioned()
(thanks Wouter Vanden Hove)
* setup/teardown or collection problems now show as ERRORs
or with big "E"'s in the progress lines. they are reported
and counted separately.
* dist-testing: properly handle test items that get locally
collected but cannot be collected on the remote side - often
due to platform/dependency reasons
* simplified py.test.mark API - see keyword plugin documentation
* integrate better with logging: capturing now by default captures
test functions and their immediate setup/teardown in a single stream
* capsys and capfd funcargs now have a readouterr() and a close() method
(underlyingly py.io.StdCapture/FD objects are used which grew a
readouterr() method as well to return snapshots of captured out/err)
* make assert-reinterpretation work better with comparisons not
returning bools (reported with numpy from thanks maciej fijalkowski)
* reworked per-test output capturing into the pytest_iocapture.py plugin
and thus removed capturing code from config object
* item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr)
Changes between 1.0.0b7 and 1.0.0b8
=====================================
* pytest_unittest-plugin is now enabled by default
* introduced pytest_keyboardinterrupt hook and
refined pytest_sessionfinish hooked, added tests.
* workaround a buggy logging module interaction ("closing already closed
files"). Thanks to Sridhar Ratnakumar for triggering.
* if plugins use "py.test.importorskip" for importing
a dependency only a warning will be issued instead
of exiting the testing process.
* many improvements to docs:
- refined funcargs doc , use the term "factory" instead of "provider"
- added a new talk/tutorial doc page
- better download page
- better plugin docstrings
- added new plugins page and automatic doc generation script
* fixed teardown problem related to partially failing funcarg setups
(thanks MrTopf for reporting), "pytest_runtest_teardown" is now
always invoked even if the "pytest_runtest_setup" failed.
* tweaked doctest output for docstrings in py modules,
thanks Radomir.
Changes between 1.0.0b3 and 1.0.0b7
=============================================
* renamed py.test.xfail back to py.test.mark.xfail to avoid
two ways to decorate for xfail
* re-added py.test.mark decorator for setting keywords on functions
(it was actually documented so removing it was not nice)
* remove scope-argument from request.addfinalizer() because
request.cached_setup has the scope arg. TOOWTDI.
* perform setup finalization before reporting failures
* apply modified patches from Andreas Kloeckner to allow
test functions to have no func_code (#22) and to make
"-k" and function keywords work (#20)
* apply patch from Daniel Peolzleithner (issue #23)
* resolve issue #18, multiprocessing.Manager() and
redirection clash
* make __name__ == "__channelexec__" for remote_exec code
Changes between 1.0.0b1 and 1.0.0b3
=============================================
* plugin classes are removed: one now defines
hooks directly in conftest.py or global pytest_*.py
files.
* added new pytest_namespace(config) hook that allows
to inject helpers directly to the py.test.* namespace.
* documented and refined many hooks
* added new style of generative tests via
pytest_generate_tests hook that integrates
well with function arguments.
Changes between 0.9.2 and 1.0.0b1
=============================================
* introduced new "funcarg" setup method,
see doc/test/funcarg.txt
* introduced plugin architecuture and many
new py.test plugins, see
doc/test/plugins.txt
* teardown_method is now guaranteed to get
called after a test method has run.
* new method: py.test.importorskip(mod,minversion)
will either import or call py.test.skip()
* completely revised internal py.test architecture
* new py.process.ForkedFunc object allowing to
fork execution of a function to a sub process
and getting a result back.
XXX lots of things missing here XXX
Changes between 0.9.1 and 0.9.2
===============================
* refined installation and metadata, created new setup.py,
now based on setuptools/ez_setup (thanks to Ralf Schmitt
for his support).
* improved the way of making py.* scripts available in
windows environments, they are now added to the
Scripts directory as ".cmd" files.
* py.path.svnwc.status() now is more complete and
uses xml output from the 'svn' command if available
(Guido Wesdorp)
* fix for py.path.svn* to work with svn 1.5
(Chris Lamb)
* fix path.relto(otherpath) method on windows to
use normcase for checking if a path is relative.
* py.test's traceback is better parseable from editors
(follows the filenames:LINENO: MSG convention)
(thanks to Osmo Salomaa)
* fix to javascript-generation, "py.test --runbrowser"
should work more reliably now
* removed previously accidentally added
py.test.broken and py.test.notimplemented helpers.
* there now is a py.__version__ attribute
Changes between 0.9.0 and 0.9.1
===============================
This is a fairly complete list of changes between 0.9 and 0.9.1, which can
serve as a reference for developers.
* allowing + signs in py.path.svn urls [39106]
* fixed support for Failed exceptions without excinfo in py.test [39340]
* added support for killing processes for Windows (as well as platforms that
support os.kill) in py.misc.killproc [39655]
* added setup/teardown for generative tests to py.test [40702]
* added detection of FAILED TO LOAD MODULE to py.test [40703, 40738, 40739]
* fixed problem with calling .remove() on wcpaths of non-versioned files in
py.path [44248]
* fixed some import and inheritance issues in py.test [41480, 44648, 44655]
* fail to run greenlet tests when pypy is available, but without stackless
[45294]
* small fixes in rsession tests [45295]
* fixed issue with 2.5 type representations in py.test [45483, 45484]
* made that internal reporting issues displaying is done atomically in py.test
[45518]
* made that non-existing files are igored by the py.lookup script [45519]
* improved exception name creation in py.test [45535]
* made that less threads are used in execnet [merge in 45539]
* removed lock required for atomical reporting issue displaying in py.test
[45545]
* removed globals from execnet [45541, 45547]
* refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit
get called in 2.5 (py.execnet) [45548]
* fixed bug in joining threads in py.execnet's servemain [45549]
* refactored py.test.rsession tests to not rely on exact output format anymore
[45646]
* using repr() on test outcome [45647]
* added 'Reason' classes for py.test.skip() [45648, 45649]
* killed some unnecessary sanity check in py.test.collect [45655]
* avoid using os.tmpfile() in py.io.fdcapture because on Windows it's only
usable by Administrators [45901]
* added support for locking and non-recursive commits to py.path.svnwc [45994]
* locking files in py.execnet to prevent CPython from segfaulting [46010]
* added export() method to py.path.svnurl
* fixed -d -x in py.test [47277]
* fixed argument concatenation problem in py.path.svnwc [49423]
* restore py.test behaviour that it exits with code 1 when there are failures
[49974]
* don't fail on html files that don't have an accompanying .txt file [50606]
* fixed 'utestconvert.py < input' [50645]
* small fix for code indentation in py.code.source [50755]
* fix _docgen.py documentation building [51285]
* improved checks for source representation of code blocks in py.test [51292]
* added support for passing authentication to py.path.svn* objects [52000,
52001]
* removed sorted() call for py.apigen tests in favour of [].sort() to support
Python 2.3 [52481]

View File

@@ -5,10 +5,12 @@ Release notes
Contents:
.. toctree::
:maxdepth: 1
:maxdepth: 2
announce/release-1.0.2
announce/release-1.0.1
announce/release-1.0.0
announce/release-0.9.2
announce/release-0.9.0
.. include: release-1.1.0
.. include: release-1.0.2
release-1.0.1
release-1.0.0
release-0.9.2
release-0.9.0

View File

@@ -1,22 +1,40 @@
======================
``py/bin/`` scripts
pylib scripts
======================
The py-lib contains some scripts, most of which are
small ones (apart from ``py.test``) that help during
the python development process. If working
from a svn-checkout of py lib you may add ``py/bin``
to your shell ``PATH`` which should make the scripts
available on your command prompt.
The pylib installs several scripts to support testing and (python)
development. If working from a checkout you may also add ``bin`` to
your ``PATH`` environment variable which makes the scripts available on
your shell prompt.
``py.test``
===========
``py.test`` and ``py.test-$VERSION``
============================================
The ``py.test`` executable is the main entry point into the py-lib testing tool,
see the `py.test documentation`_.
The ``py.test`` executable is the main tool that the py lib offers;
in fact most code in the py lib is geared towards supporting the
testing process. See the `py.test documentation`_ for extensive
documentation. The ``py.test-$VERSION`` is the same script with
an interpreter specific suffix appended to make
several versions of py.test for using specific interpreters
accessible:
* CPython2.4: py.test-2.4
* CPython2.5: py.test-2.5
* ...
* CPython3.1: py.test-3.1
* Jython-2.5.1: py.test-jython
* pypy-$SUFFIX: py.test-pypy-$SUFFIX
.. _`py.test documentation`: test/index.html
``py.which`` and ``py.which-$VERSION``
=========================================
Usage: ``py.which modulename``
Print the ``__file__`` of the module that is imported via ``import modulename``.
The version-suffix is the same as with ``py.test`` above.
``py.cleanup``
==============
@@ -26,7 +44,6 @@ Delete pyc file recursively, starting from ``PATH`` (which defaults to the
current working directory). Don't follow links and don't recurse into
directories with a ".".
``py.countloc``
===============
@@ -46,25 +63,3 @@ Looks recursively at Python files for a ``SEARCH_STRING``, starting from the
present working directory. Prints the line, with the filename and line-number
prepended.
``py.rest``
===========
Usage: ``py.rest [PATHS] [options]``
[deprecated in 1.0, will likely be separated]
Loot recursively for .txt files starting from ``PATHS`` and convert them to
html using docutils or to pdf files, if the ``--pdf`` option is used. For
conversion to PDF you will need several command line tools, on Ubuntu Linux
this is **texlive** and **texlive-extra-utils**.
``py.rest`` has some extra features over rst2html (which is shipped with
docutils). Most of these are still experimental, the one which is most likely
not going to change is the `graphviz`_ directive. With that you can embed .dot
files into your document and have them be converted to png (when outputting
html) and to eps (when outputting pdf). Otherwise the directive works mostly
like the image directive::
.. graphviz:: example.dot
:scale: 90
.. _`graphviz`: http://www.graphviz.org

View File

@@ -1,263 +1,2 @@
Changes between 1.0.1 and 1.0.2
=====================================
* fixing packaging issues, triggered by fedora redhat packaging,
also added doc, examples and contrib dirs to the tarball.
* added a documentation link to the new pytest_django plugin.
Changes between 1.0.0 and 1.0.1
=====================================
* added a 'pytest_nose' plugin which handles nose.SkipTest,
nose-style function/method/generator setup/teardown and
tries to report functions correctly.
* capturing of unicode writes or encoded strings to sys.stdout/err
work better, also terminalwriting was adapted and somewhat
unified between windows and linux.
* improved documentation layout and content a lot
* added a "--help-config" option to show conftest.py / ENV-var names for
all longopt cmdline options, and some special conftest.py variables.
renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
* fix issue #27: better reporting on non-collectable items given on commandline
(e.g. pyc files)
* fix issue #33: added --version flag (thanks Benjamin Peterson)
* fix issue #32: adding support for "incomplete" paths to wcpath.status()
* "Test" prefixed classes are *not* collected by default anymore if they
have an __init__ method
* monkeypatch setenv() now accepts a "prepend" parameter
* improved reporting of collection error tracebacks
* simplified multicall mechanism and plugin architecture,
renamed some internal methods and argnames
Changes between 1.0.0b9 and 1.0.0
=====================================
* more terse reporting try to show filesystem path relatively to current dir
* improve xfail output a bit
Changes between 1.0.0b8 and 1.0.0b9
=====================================
* cleanly handle and report final teardown of test setup
* fix svn-1.6 compat issue with py.path.svnwc().versioned()
(thanks Wouter Vanden Hove)
* setup/teardown or collection problems now show as ERRORs
or with big "E"'s in the progress lines. they are reported
and counted separately.
* dist-testing: properly handle test items that get locally
collected but cannot be collected on the remote side - often
due to platform/dependency reasons
* simplified py.test.mark API - see keyword plugin documentation
* integrate better with logging: capturing now by default captures
test functions and their immediate setup/teardown in a single stream
* capsys and capfd funcargs now have a readouterr() and a close() method
(underlyingly py.io.StdCapture/FD objects are used which grew a
readouterr() method as well to return snapshots of captured out/err)
* make assert-reinterpretation work better with comparisons not
returning bools (reported with numpy from thanks maciej fijalkowski)
* reworked per-test output capturing into the pytest_iocapture.py plugin
and thus removed capturing code from config object
* item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr)
Changes between 1.0.0b7 and 1.0.0b8
=====================================
* pytest_unittest-plugin is now enabled by default
* introduced pytest_keyboardinterrupt hook and
refined pytest_sessionfinish hooked, added tests.
* workaround a buggy logging module interaction ("closing already closed
files"). Thanks to Sridhar Ratnakumar for triggering.
* if plugins use "py.test.importorskip" for importing
a dependency only a warning will be issued instead
of exiting the testing process.
* many improvements to docs:
- refined funcargs doc , use the term "factory" instead of "provider"
- added a new talk/tutorial doc page
- better download page
- better plugin docstrings
- added new plugins page and automatic doc generation script
* fixed teardown problem related to partially failing funcarg setups
(thanks MrTopf for reporting), "pytest_runtest_teardown" is now
always invoked even if the "pytest_runtest_setup" failed.
* tweaked doctest output for docstrings in py modules,
thanks Radomir.
Changes between 1.0.0b3 and 1.0.0b7
=============================================
* renamed py.test.xfail back to py.test.mark.xfail to avoid
two ways to decorate for xfail
* re-added py.test.mark decorator for setting keywords on functions
(it was actually documented so removing it was not nice)
* remove scope-argument from request.addfinalizer() because
request.cached_setup has the scope arg. TOOWTDI.
* perform setup finalization before reporting failures
* apply modified patches from Andreas Kloeckner to allow
test functions to have no func_code (#22) and to make
"-k" and function keywords work (#20)
* apply patch from Daniel Peolzleithner (issue #23)
* resolve issue #18, multiprocessing.Manager() and
redirection clash
* make __name__ == "__channelexec__" for remote_exec code
Changes between 1.0.0b1 and 1.0.0b3
=============================================
* plugin classes are removed: one now defines
hooks directly in conftest.py or global pytest_*.py
files.
* added new pytest_namespace(config) hook that allows
to inject helpers directly to the py.test.* namespace.
* documented and refined many hooks
* added new style of generative tests via
pytest_generate_tests hook that integrates
well with function arguments.
Changes between 0.9.2 and 1.0.0b1
=============================================
* introduced new "funcarg" setup method,
see doc/test/funcarg.txt
* introduced plugin architecuture and many
new py.test plugins, see
doc/test/plugins.txt
* teardown_method is now guaranteed to get
called after a test method has run.
* new method: py.test.importorskip(mod,minversion)
will either import or call py.test.skip()
* completely revised internal py.test architecture
* new py.process.ForkedFunc object allowing to
fork execution of a function to a sub process
and getting a result back.
XXX lots of things missing here XXX
Changes between 0.9.1 and 0.9.2
===============================
* refined installation and metadata, created new setup.py,
now based on setuptools/ez_setup (thanks to Ralf Schmitt
for his support).
* improved the way of making py.* scripts available in
windows environments, they are now added to the
Scripts directory as ".cmd" files.
* py.path.svnwc.status() now is more complete and
uses xml output from the 'svn' command if available
(Guido Wesdorp)
* fix for py.path.svn* to work with svn 1.5
(Chris Lamb)
* fix path.relto(otherpath) method on windows to
use normcase for checking if a path is relative.
* py.test's traceback is better parseable from editors
(follows the filenames:LINENO: MSG convention)
(thanks to Osmo Salomaa)
* fix to javascript-generation, "py.test --runbrowser"
should work more reliably now
* removed previously accidentally added
py.test.broken and py.test.notimplemented helpers.
* there now is a py.__version__ attribute
Changes between 0.9.0 and 0.9.1
===============================
This is a fairly complete list of changes between 0.9 and 0.9.1, which can
serve as a reference for developers.
* allowing + signs in py.path.svn urls [39106]
* fixed support for Failed exceptions without excinfo in py.test [39340]
* added support for killing processes for Windows (as well as platforms that
support os.kill) in py.misc.killproc [39655]
* added setup/teardown for generative tests to py.test [40702]
* added detection of FAILED TO LOAD MODULE to py.test [40703, 40738, 40739]
* fixed problem with calling .remove() on wcpaths of non-versioned files in
py.path [44248]
* fixed some import and inheritance issues in py.test [41480, 44648, 44655]
* fail to run greenlet tests when pypy is available, but without stackless
[45294]
* small fixes in rsession tests [45295]
* fixed issue with 2.5 type representations in py.test [45483, 45484]
* made that internal reporting issues displaying is done atomically in py.test
[45518]
* made that non-existing files are igored by the py.lookup script [45519]
* improved exception name creation in py.test [45535]
* made that less threads are used in execnet [merge in 45539]
* removed lock required for atomical reporting issue displaying in py.test
[45545]
* removed globals from execnet [45541, 45547]
* refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit
get called in 2.5 (py.execnet) [45548]
* fixed bug in joining threads in py.execnet's servemain [45549]
* refactored py.test.rsession tests to not rely on exact output format anymore
[45646]
* using repr() on test outcome [45647]
* added 'Reason' classes for py.test.skip() [45648, 45649]
* killed some unnecessary sanity check in py.test.collect [45655]
* avoid using os.tmpfile() in py.io.fdcapture because on Windows it's only
usable by Administrators [45901]
* added support for locking and non-recursive commits to py.path.svnwc [45994]
* locking files in py.execnet to prevent CPython from segfaulting [46010]
* added export() method to py.path.svnurl
* fixed -d -x in py.test [47277]
* fixed argument concatenation problem in py.path.svnwc [49423]
* restore py.test behaviour that it exits with code 1 when there are failures
[49974]
* don't fail on html files that don't have an accompanying .txt file [50606]
* fixed 'utestconvert.py < input' [50645]
* small fix for code indentation in py.code.source [50755]
* fix _docgen.py documentation building [51285]
* improved checks for source representation of code blocks in py.test [51292]
* added support for passing authentication to py.path.svn* objects [52000,
52001]
* removed sorted() call for py.apigen tests in favour of [].sort() to support
Python 2.3 [52481]
.. include:: ../CHANGELOG

View File

@@ -2,35 +2,33 @@
py.code: higher level python code and introspection objects
================================================================================
The :api:`py.code` part of the pylib contains some functionality to help
The ``py.code`` part of the pylib contains some functionality to help
dealing with Python code objects. Even though working with Python's internal
code objects (as found on frames and callables) can be very powerful, it's
usually also quite cumbersome, because the API provided by core Python is
relatively low level and not very accessible.
The :api:`py.code` library tries to simplify accessing the code objects as well
The ``py.code`` library tries to simplify accessing the code objects as well
as creating them. There is a small set of interfaces a user needs to deal with,
all nicely bundled together, and with a rich set of 'Pythonic' functionality.
source: :source:`py/code/`
Contents of the library
=======================
Every object in the :api:`py.code` library wraps a code Python object related
to code objects, source code, frames and tracebacks: the :api:`py.code.Code`
class wraps code objects, :api:`py.code.Source` source snippets,
:api:`py.code.Traceback` exception tracebacks, :api:`py.code.Frame` frame
objects (as found in e.g. tracebacks) and :api:`py.code.ExceptionInfo` the
Every object in the ``py.code`` library wraps a code Python object related
to code objects, source code, frames and tracebacks: the ``py.code.Code``
class wraps code objects, ``py.code.Source`` source snippets,
``py.code.Traceback` exception tracebacks, ``py.code.Frame`` frame
objects (as found in e.g. tracebacks) and ``py.code.ExceptionInfo`` the
tuple provided by sys.exc_info() (containing exception and traceback
information when an exception occurs). Also in the library is a helper function
:api:`py.code.compile()` that provides the same functionality as Python's
``py.code.compile()`` that provides the same functionality as Python's
built-in 'compile()' function, but returns a wrapped code object.
The wrappers
============
:api:`py.code.Code`
``py.code.Code``
-------------------
Code objects are instantiated with a code object or a callable as argument,
@@ -46,11 +44,9 @@ A quick example::
>>> isinstance(c.source(), py.code.Source)
True
>>> str(c.source()).split('\n')[0]
"def read(self, mode='rb'):"
"def read(self, mode='r'):"
source: :source:`py/code/code.py`
:api:`py.code.Source`
``py.code.Source``
---------------------
Source objects wrap snippets of Python source code, providing a simple yet
@@ -71,9 +67,8 @@ Example::
>>> str(sub).strip() # XXX why is the strip() required?!?
'print "foo"'
source: :source:`py/code/source.py`
:api:`py.code.Traceback`
``py.code.Traceback``
------------------------
Tracebacks are usually not very easy to examine, you need to access certain
@@ -97,15 +92,13 @@ Example::
>>> str(first.statement).strip().startswith('raise ValueError')
True
source: :source:`py/code/traceback2.py`
:api:`py.code.Frame`
``py.code.Frame``
--------------------
Frame wrappers are used in :api:`py.code.Traceback` items, and will usually not
Frame wrappers are used in ``py.code.Traceback`` items, and will usually not
directly be instantiated. They provide some nice methods to evaluate code
'inside' the frame (using the frame's local variables), get to the underlying
code (frames have a code attribute that points to a :api:`py.code.Code` object)
code (frames have a code attribute that points to a ``py.code.Code`` object)
and examine the arguments.
Example (using the 'first' TracebackItem instance created above)::
@@ -113,12 +106,12 @@ Example (using the 'first' TracebackItem instance created above)::
>>> frame = first.frame
>>> isinstance(frame.code, py.code.Code)
True
>>> isinstance(frame.eval('self'), py.__.path.local.local.LocalPath)
>>> isinstance(frame.eval('self'), py.path.local)
True
>>> [namevalue[0] for namevalue in frame.getargs()]
['cls', 'path']
:api:`py.code.ExceptionInfo`
``py.code.ExceptionInfo``
----------------------------
A wrapper around the tuple returned by sys.exc_info() (will call sys.exc_info()

View File

@@ -1,6 +1,6 @@
import py
from py.__.misc.rest import convert_rest_html, strip_html_header
from py.__.misc.difftime import worded_time
from py._plugin.pytest_restdoc import convert_rest_html, strip_html_header
html = py.xml.html
@@ -57,24 +57,24 @@ pageTracker._trackPageview();
def fill_menubar(self):
items = [
self.a_docref("install", "download.html"),
self.a_docref("contact", "contact.html"),
self.a_docref("changelog", "changelog.html"),
self.a_docref("faq", "faq.html"),
self.a_docref("INSTALL", "install.html"),
self.a_docref("CONTACT", "contact.html"),
self.a_docref("CHANGELOG", "changelog.html"),
self.a_docref("FAQ", "faq.html"),
html.div(
html.h3("py.test:"),
self.a_docref("doc index", "test/index.html"),
self.a_docref("features", "test/features.html"),
self.a_docref("quickstart", "test/quickstart.html"),
self.a_docref("tutorials", "test/talks.html"),
self.a_docref("plugins", "test/plugin/index.html"),
self.a_docref("funcargs", "test/funcargs.html"),
self.a_docref("customize", "test/customize.html"),
self.a_docref("Index", "test/index.html"),
self.a_docref("Quickstart", "test/quickstart.html"),
self.a_docref("Features", "test/features.html"),
self.a_docref("Funcargs", "test/funcargs.html"),
self.a_docref("Plugins", "test/plugin/index.html"),
self.a_docref("Customize", "test/customize.html"),
self.a_docref("Tutorials", "test/talks.html"),
self.a_href("hudson-tests", "http://hudson.testrun.org")
),
html.div(
html.h3("supporting APIs:"),
self.a_docref("pylib index", "index.html"),
self.a_docref("py.execnet", "execnet.html"),
self.a_docref("Index", "index.html"),
self.a_docref("py.path", "path.html"),
self.a_docref("py.code", "code.html"),
)
@@ -86,9 +86,10 @@ pageTracker._trackPageview();
self.menubar = html.div(id=css.menubar, *[
html.div(item) for item in items])
version = py.version
announcelink = self.a_docref("%s ANN" % version,
"announce/release-%s.html" %(version,))
self.menubar.insert(0,
html.div("%s" % (py.version), style="font-style: italic;")
)
html.div(announcelink))
#self.a_href("%s-%s" % (self.title, py.version),
# "http://pypi.python.org/pypi/py/%s" % version,
#id="versioninfo",
@@ -149,7 +150,7 @@ def getrealname(username):
class Project:
mydir = py.magic.autopath().dirpath()
mydir = py.path.local(__file__).dirpath()
title = "py lib"
prefix_title = "" # we have a logo already containing "py lib"
encoding = 'latin1'
@@ -286,5 +287,3 @@ def relpath(p1, p2, sep=os.path.sep, back='..', normalize=True):
if tolist_diff:
return sep.join([back,]*(backcount-1) + tolist_diff)
return sep.join([back,]*(backcount) + tolist[commonindex:])

View File

@@ -1,7 +1,8 @@
#XXX make work: excludedirs = ['_build']
import py
#py.test.importorskip("pygments")
pytest_plugins = ['pytest_restdoc']
rsyncdirs = ['.']
collect_ignore = ['test/attic.txt']
def pytest_runtest_setup(item):
if item.fspath.ext == ".txt":
py.test.importorskip("pygments") # for raising an error

18
doc/download.html Normal file
View File

@@ -0,0 +1,18 @@
<html>
<head>
<meta http-equiv="refresh" content=" 1 ; URL=install.html" />
</head>
<body>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-7597274-3");
pageTracker._trackPageview();
} catch(err) {}</script>
</body>
</html>

View File

@@ -1,130 +0,0 @@
..
==============
Downloading
==============
.. _`PyPI project page`: http://pypi.python.org/pypi/py/
Latest Release, see `PyPI project page`_
using easy_install
===================================================
With a working `setuptools installation`_ you can type::
easy_install -U py
to get the latest release of the py lib. The ``-U`` switch
will trigger an upgrade if you already have an older version installed.
On Linux systems you may need to execute the command as superuser and
on Windows you might need to write down the full path to ``easy_install``.
The py lib and its tools are expected to work well on Linux,
Windows and OSX, Python versions 2.3, 2.4, 2.5 and 2.6.
**IMPORTANT NOTE**: if you are using Windows and have
0.8 versions of the py lib on your system, please download
and execute http://codespeak.net/svn/py/build/winpathclean.py
This will check that no previous files are getting in the way.
You can find out the py lib version with::
import py
print py.version
.. _mercurial: http://mercurial.selenic.com/wiki/
.. _checkout:
.. _tarball:
Working from version control or a tarball
=================================================
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/
This currrently contains a 1.0.x branch and the
default 'trunk' branch where mainline development
takes place. There also is a readonly subversion
checkout available::
svn co https://codespeak.net/svn/py/dist
You can also go to the python package index and
download and unpack a TAR file::
http://pypi.python.org/pypi/py/
activating checkout with setuptools
--------------------------------------------
With a working `setuptools installation`_ you can issue::
python setup.py develop
in order to work with the tools and the lib of your checkout.
.. _`no-setuptools`:
activating a checkout or tarball without setuptools
-------------------------------------------------------------
To import the py lib the ``py`` package directory needs to
be on the ``$PYTHONPATH``. If you exexute scripts directly
from ``py/bin/`` or ``py\bin\win32`` they will find their
containing py lib automatically.
It is usually a good idea to add the parent directory of the ``py`` package
directory to your ``PYTHONPATH`` and ``py/bin`` or ``py\bin\win32`` to your
system wide ``PATH`` settings. There are helper scripts that set ``PYTHONPATH`` and ``PATH`` on your system:
on windows execute::
# inside autoexec.bat or shell startup
c:\\path\to\checkout\py\env.cmd
on linux/OSX add this to your shell initialization::
# inside .bashrc
eval `python ~/path/to/checkout/py/env.py`
both of which which will get you good settings
for ``PYTHONPATH`` and ``PATH``.
note: scripts look for "nearby" py-lib
-----------------------------------------------------
Note that the `command line scripts`_ will look
for "nearby" py libs, so if you have a layout like this::
mypkg/
subpkg1/
tests/
tests/
py/
issuing ``py.test subpkg1`` will use the py lib
from that projects root directory.
.. _`command line scripts`: bin.html
Debian and RPM packages
===================================
As of August 2009 pytest/pylib 1.0 RPMs and Debian packages
are not available. You will only find 0.9 versions -
on Debian systems look for ``python-codespeak-lib``
and Dwayne Bailey has put together a Fedora `RPM`_.
If you can help with providing/upgrading distribution
packages please use of the contact_ channels in case
of questions or need for changes.
.. _contact: contact.html
.. _`RPM`: http://translate.sourceforge.net/releases/testing/fedora/pylib-0.9.2-1.fc9.noarch.rpm
.. _`setuptools installation`: http://pypi.python.org/pypi/setuptools

View File

@@ -96,7 +96,7 @@ class TestFailing(object):
def test_reinterpret_fails_with_print_for_the_fun_of_it(self):
l = [1,2,3]
print "l is", l
print ("l is %r" % l)
a,b = l.pop()
def test_some_error(self):
@@ -113,7 +113,7 @@ def test_dynamic_compile_shows_nicely():
name = 'abc-123'
module = py.std.imp.new_module(name)
code = py.code.compile(src, name, 'exec')
exec code in module.__dict__
py.builtin.exec_(code, module.__dict__)
py.std.sys.modules[name] = module
module.foo()

View File

@@ -0,0 +1,10 @@
import py
mydir = py.path.local(__file__).dirpath()
def pytest_runtest_setup(item):
if isinstance(item, py.test.collect.Function):
if not item.fspath.relto(mydir):
return
mod = item.getparent(py.test.collect.Module).obj
if hasattr(mod, 'hello'):
py.builtin.print_("mod.hello", mod.hello)

View File

@@ -0,0 +1,5 @@
hello = "world"
def test_func():
pass

View File

@@ -0,0 +1,15 @@
import py
failure_demo = py.path.local(__file__).dirpath('failure_demo.py')
pytest_plugins = "pytest_pytester"
def test_failure_demo_fails_properly(testdir):
target = testdir.tmpdir.join(failure_demo.basename)
failure_demo.copy(target)
failure_demo.copy(testdir.tmpdir.join(failure_demo.basename))
result = testdir.runpytest(target)
result.stdout.fnmatch_lines([
"*20 failed*"
])
assert result.ret != 0

View File

@@ -9,7 +9,7 @@ class TestStateFullThing:
cls.classcount -= 1
def setup_method(self, method):
self.id = eval(method.func_name[5:])
self.id = eval(method.__name__[5:])
def test_42(self):
assert self.classcount == 1

View File

@@ -1,5 +1,5 @@
from myapp import MyApp
from mysetup.myapp import MyApp
def pytest_funcarg__mysetup(request):
return MySetup()

View File

@@ -1,5 +1,5 @@
import py
from myapp import MyApp
from mysetup2.myapp import MyApp
def pytest_funcarg__mysetup(request):
return MySetup(request)
@@ -20,5 +20,5 @@ class MySetup:
host = self.config.option.ssh
if host is None:
py.test.skip("specify ssh host with --ssh")
return py.execnet.SshGateway(host)
return execnet.SshGateway(host)

View File

@@ -0,0 +1,65 @@
"""
module containing a parametrized tests testing cross-python
serialization via the pickle module.
"""
import py
pythonlist = ['python2.3', 'python2.4', 'python2.5', 'python2.6']
# 'jython' 'python3.1']
def pytest_generate_tests(metafunc):
if 'python1' in metafunc.funcargnames:
assert 'python2' in metafunc.funcargnames
for obj in metafunc.function.multiarg.kwargs['obj']:
for py1 in pythonlist:
for py2 in pythonlist:
metafunc.addcall(id="%s-%s-%s" % (py1, py2, obj),
param=(py1, py2, obj))
@py.test.mark.multiarg(obj=[42, {}, {1:3},])
def test_basic_objects(python1, python2, obj):
python1.dumps(obj)
python2.load_and_is_true("obj == %s" % obj)
def pytest_funcarg__python1(request):
tmpdir = request.getfuncargvalue("tmpdir")
picklefile = tmpdir.join("data.pickle")
return Python(request.param[0], picklefile)
def pytest_funcarg__python2(request):
python1 = request.getfuncargvalue("python1")
return Python(request.param[1], python1.picklefile)
def pytest_funcarg__obj(request):
return request.param[2]
class Python:
def __init__(self, version, picklefile):
self.pythonpath = py.path.local.sysfind(version)
if not self.pythonpath:
py.test.skip("%r not found" %(version,))
self.picklefile = picklefile
def dumps(self, obj):
dumpfile = self.picklefile.dirpath("dump.py")
dumpfile.write(py.code.Source("""
import pickle
f = open(%r, 'wb')
s = pickle.dump(%r, f)
f.close()
""" % (str(self.picklefile), obj)))
py.process.cmdexec("%s %s" %(self.pythonpath, dumpfile))
def load_and_is_true(self, expression):
loadfile = self.picklefile.dirpath("load.py")
loadfile.write(py.code.Source("""
import pickle
f = open(%r, 'rb')
obj = pickle.load(f)
f.close()
res = eval(%r)
if not res:
raise SystemExit(1)
""" % (str(self.picklefile), expression)))
print (loadfile)
py.process.cmdexec("%s %s" %(self.pythonpath, loadfile))

View File

@@ -0,0 +1,15 @@
# conftest.py
import py
def pytest_addoption(parser):
grp = parser.getgroup("testserver options")
grp.addoption("--url", action="store", default=None,
help="url for testserver")
def pytest_funcarg__url(request):
url = request.config.getvalue("url")
if url is None:
py.test.skip("need --url")
return url

16
doc/example/xfail_demo.py Normal file
View File

@@ -0,0 +1,16 @@
import py
@py.test.mark.xfail
def test_hello():
assert 0
@py.test.mark.xfail(run=False)
def test_hello2():
assert 0
@py.test.mark.xfail("hasattr(os, 'sep')")
def test_hello3():
assert 0
def test_hello5():
py.test.xfail("reason")

View File

@@ -2,263 +2,11 @@
py.execnet: *elastic* distributed programming
==============================================================================
``execnet`` helps you to:
Since pylib 1.1 "py.execnet" ceased to exist and is now available
as a separately developed `execnet standalone package`_.
* ad-hoc instantiate local or remote Python Processes
* send code for execution in one or many processes
* send and receive data between processes through channels
One of it's unique features is that it uses a **zero-install**
technique: no manual installation steps are required on
remote places, only a basic working Python interpreter
and some input/output connection to it.
There is a `EuroPython2009 talk`_ from July 2009 with
examples and some pictures.
.. contents::
:local:
:depth: 2
.. _`EuroPython2009 talk`: http://codespeak.net/download/py/ep2009-execnet.pdf
Gateways: immediately spawn local or remote process
===================================================
In order to send code to a remote place or a subprocess
you need to instantiate a so-called Gateway object.
There are currently three Gateway classes:
* :api:`py.execnet.PopenGateway` to open a subprocess
on the local machine. Useful for making use
of multiple processors to to contain code execution
in a separated environment.
* :api:`py.execnet.SshGateway` to connect to
a remote ssh server and distribute execution to it.
* :api:`py.execnet.SocketGateway` a way to connect to
a remote Socket based server. *Note* that this method
requires a manually started
:source:py/execnet/script/socketserver.py
script. You can run this "server script" without
having the py lib installed on the remote system
and you can setup it up as permanent service.
remote_exec: execute source code remotely
===================================================
All gateways offer remote code execution via this high level function::
def remote_exec(source):
"""return channel object for communicating with the asynchronously
executing 'source' code which will have a corresponding 'channel'
object in its executing namespace."""
With `remote_exec` you send source code to the other
side and get both a local and a remote Channel_ object,
which you can use to have the local and remote site
communicate data in a structured way. Here is
an example for reading the PID::
>>> import py
>>> gw = py.execnet.PopenGateway()
>>> channel = gw.remote_exec("""
... import os
... channel.send(os.getpid())
... """)
>>> remote_pid = channel.receive()
>>> remote_pid != py.std.os.getpid()
True
.. _`Channel`:
.. _`channel-api`:
.. _`exchange data`:
Channels: bidirectionally exchange data between hosts
=======================================================
A channel object allows to send and receive data between
two asynchronously running programs. When calling
`remote_exec` you will get a channel object back and
the code fragment running on the other side will
see a channel object in its global namespace.
Here is the interface of channel objects::
#
# API for sending and receiving anonymous values
#
channel.send(item):
sends the given item to the other side of the channel,
possibly blocking if the sender queue is full.
Note that items need to be marshallable (all basic
python types are).
channel.receive():
receives an item that was sent from the other side,
possibly blocking if there is none.
Note that exceptions from the other side will be
reraised as gateway.RemoteError exceptions containing
a textual representation of the remote traceback.
channel.waitclose(timeout=None):
wait until this channel is closed. Note that a closed
channel may still hold items that will be received or
send. Note that exceptions from the other side will be
reraised as gateway.RemoteError exceptions containing
a textual representation of the remote traceback.
channel.close():
close this channel on both the local and the remote side.
A remote side blocking on receive() on this channel
will get woken up and see an EOFError exception.
.. _xspec:
XSpec: string specification for gateway type and configuration
===============================================================
``py.execnet`` supports a simple extensible format for
specifying and configuring Gateways for remote execution.
You can use a string specification to instantiate a new gateway,
for example a new SshGateway::
gateway = py.execnet.makegateway("ssh=myhost")
Let's look at some examples for valid specifications.
Specification for an ssh connection to `wyvern`, running on python2.4 in the (newly created) 'mycache' subdirectory::
ssh=wyvern//python=python2.4//chdir=mycache
Specification of a python2.5 subprocess; with a low CPU priority ("nice" level). Current dir will be the current dir of the instantiator (that's true for all 'popen' specifications unless they specify 'chdir')::
popen//python=2.5//nice=20
Specification of a Python Socket server process that listens on 192.168.1.4:8888; current dir will be the 'pyexecnet-cache' sub directory which is used a default for all remote processes::
socket=192.168.1.4:8888
More generally, a specification string has this general format::
key1=value1//key2=value2//key3=value3
If you omit a value, a boolean true value is assumed. Currently
the following key/values are supported:
* ``popen`` for a PopenGateway
* ``ssh=host`` for a SshGateway
* ``socket=address:port`` for a SocketGateway
* ``python=executable`` for specifying Python executables
* ``chdir=path`` change remote working dir to given relative or absolute path
* ``nice=value`` decrease remote nice level if platforms supports it
Examples of py.execnet usage
===============================================================
Compare cwd() of Popen Gateways
----------------------------------------
A PopenGateway has the same working directory as the instantiatior::
>>> import py, os
>>> gw = py.execnet.PopenGateway()
>>> ch = gw.remote_exec("import os; channel.send(os.getcwd())")
>>> res = ch.receive()
>>> assert res == os.getcwd()
>>> gw.exit()
Synchronously receive results from two sub processes
-----------------------------------------------------
Use MultiChannels for receiving multiple results from remote code::
>>> import py
>>> ch1 = py.execnet.PopenGateway().remote_exec("channel.send(1)")
>>> ch2 = py.execnet.PopenGateway().remote_exec("channel.send(2)")
>>> mch = py.execnet.MultiChannel([ch1, ch2])
>>> l = mch.receive_each()
>>> assert len(l) == 2
>>> assert 1 in l
>>> assert 2 in l
Asynchronously receive results from two sub processes
-----------------------------------------------------
Use ``MultiChannel.make_receive_queue()`` for asynchronously receiving
multiple results from remote code. This standard Queue provides
``(channel, result)`` tuples which allows to determine where
a result comes from::
>>> import py
>>> ch1 = py.execnet.PopenGateway().remote_exec("channel.send(1)")
>>> ch2 = py.execnet.PopenGateway().remote_exec("channel.send(2)")
>>> mch = py.execnet.MultiChannel([ch1, ch2])
>>> queue = mch.make_receive_queue()
>>> chan1, res1 = queue.get() # you may also specify a timeout
>>> chan2, res2 = queue.get()
>>> res1 + res2
3
>>> assert chan1 in (ch1, ch2)
>>> assert chan2 in (ch1, ch2)
>>> assert chan1 != chan2
Receive file contents from remote SSH account
-----------------------------------------------------
Here is a small program that you can use to retrieve
contents of remote files::
import py
# open a gateway to a fresh child process
gw = py.execnet.SshGateway('codespeak.net')
channel = gw.remote_exec("""
for fn in channel:
f = open(fn, 'rb')
channel.send(f.read())
f.close()
""")
for fn in somefilelist:
channel.send(fn)
content = channel.receive()
# process content
# later you can exit / close down the gateway
gw.exit()
Instantiate a socket server in a new subprocess
-----------------------------------------------------
The following example opens a PopenGateway, i.e. a python
child process, and starts a socket server within that process
and then opens a second gateway to the freshly started
socketserver::
import py
popengw = py.execnet.PopenGateway()
socketgw = py.execnet.SocketGateway.new_remote(popengw, ("127.0.0.1", 0))
print socketgw._rinfo() # print some info about the remote environment
Sending a module / checking if run through remote_exec
--------------------------------------------------------------
You can pass a module object to ``remote_exec`` in which case
its source code will be sent. No dependencies will be transferred
so the module must be self-contained or only use modules that are
installed on the "other" side. Module code can detect if it is
running in a remote_exec situation by checking for the special
``__name__`` attribute like this::
if __name__ == '__channelexec__':
# ... call module functions ...
If you have previosly used "py.execnet.*" and the 1.0 API just
rename all occurences of the string "``py.execnet.``" with the
string "``execnet.``" as execnet-1.0 is API compatible.
.. _`execnet standalone package`: http://codespeak.net/execnet

View File

@@ -6,81 +6,97 @@ Frequently Asked Questions
:local:
:depth: 2
On naming, nose and magic
============================
Why the ``py`` naming? what is it?
------------------------------------
On naming, nosetests, licensing and magic
===========================================
Because the name was kind of available and there was the
idea to have the package evolve into a "standard" library
kind of thing that works cross-python versions and is
not tied to a particular CPython revision or its release
cycle. Clearly, this was ambitious and the naming
has maybe haunted the project rather than helping it.
There may be a project name change and possibly a
split up into different projects sometime.
Why the ``py`` naming? Why not ``pytest``?
----------------------------------------------------
This mostly has historic reasons - the aim is
to get away from the somewhat questionable 'py' name
at some point. These days (2010) the 'py' library
almost completely comprises APIs that are used
by the ``py.test`` tool. There also are some
other uses, e.g. of the ``py.path.local()`` and
other path implementations. So it requires some
work to factor them out and do the shift.
Why the ``py.test`` naming?
------------------------------------
the py lib contains other command line tools that
all share the ``py.`` prefix which makes it easy
to use TAB-completion on the shell. Another motivation
was to make it obvious where testing functionality
for the ``py.test`` command line tool is: in the
``py.test`` package name space.
because of TAB-completion under Bash/Shells. If you hit
``py.<TAB>`` you'll get a list of available development
tools that all share the ``py.`` prefix. Another motivation
was to unify the package ("py.test") and tool filename.
What's the relation to ``nosetests``?
----------------------------------------
What's py.test's relation to ``nosetests``?
---------------------------------------------
py.test and nose_ share basic philosophy when it comes
to running Python tests. In fact,
with py.test-1.0.1 it is easy to run many test suites
with py.test-1.1.0 it is ever easier to run many test suites
that currently work with ``nosetests``. nose_ was created
as a clone of ``py.test`` when it was in the ``0.8`` release
as a clone of ``py.test`` when py.test was in the ``0.8`` release
cycle so some of the newer features_ introduced with py.test-1.0
have no counterpart in nose_.
and py.test-1.1 have no counterpart in nose_.
.. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.1/
.. _features: test/features.html
.. _apipkg: http://pypi.python.org/pypi/apipkg
What's all this "magic" with py.test?
What's this "magic" with py.test?
----------------------------------------
"All this magic" usually boils down to two issues:
issues where people have used the term "magic" in the past:
* There is a special tweak to importing: `py/__init__.py`_ contains
a dictionary which maps the importable ``py.*`` namespaces to
objects in files. When looking at the project source code
you see imports like ``from py.__.test.session import Session``. The
the double ``__`` underscore indicates the "normal" python
filesystem/namespace coupled import, i.e. it points to
``py/test/session.py``'s ``Session`` object. However,
from the outside you use the "non-underscore" `py namespaces`_
so this distinction usually only shows up if you hack
on internal code or see internal tracebacks.
* `py/__init__.py`_ uses the apipkg_ mechanism for lazy-importing
and full control on what API you get when importing "import py".
* when an ``assert`` fails, py.test re-interprets the expression
to show intermediate values. This allows to use the plain ``assert``
statement instead of the many methods that you otherwise need
to mimick this behaviour. This means that in case of a failing
assert, your expressions gets evaluated *twice*. If your expression
has side effects the outcome may be different. If the test suddenly
passes you will get a detailed message. It is good practise, anyway,
to not have asserts with side effects. ``py.test --nomagic`` turns
off assert re-intepretation.
* when an ``assert`` statement fails, py.test re-interprets the expression
to show intermediate values if a test fails. If your expression
has side effects the intermediate values may not be the same, obfuscating
the initial error (this is also explained at the command line if it happens).
``py.test --no-assert`` turns off assert re-intepretation.
Sidenote: it is good practise to avoid asserts with side effects.
Other than that, ``py.test`` has bugs or quirks like any other computer
software. In fact, it has a *strong* focus on running robustly and has
over a thousand automated tests for its own code base.
.. _`py namespaces`: index.html
.. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/1.0.x/py/__init__.py
.. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/trunk/py/__init__.py
Where does my ``py.test`` come/import from?
----------------------------------------------
You can issue::
py.test --version
which tells you both version and import location of the tool.
function arguments and parametrized tests
===============================================
function arguments, parametrized tests and setup
====================================================
.. _funcargs: test/funcargs.html
Is using funcarg- versus xUnit-based setup a style question?
---------------------------------------------------------------
It depends. For simple applications or for people experienced
with nose_ or unittest-style test setup using `xUnit style setup`_
make some sense. For larger test suites, parametrized testing
or setup of complex test resources using funcargs_ is recommended.
Moreover, funcargs are ideal for writing advanced test support
code (like e.g. the monkeypatch_, the tmpdir_ or capture_ funcargs)
because the support code can register setup/teardown functions
in a managed class/module/function scope.
.. _monkeypatch: test/plugin/monkeypatch.html
.. _tmpdir: test/plugin/tmpdir.html
.. _capture: test/plugin/capture.html
.. _`xUnit style setup`: test/xunit_setup.html
.. _`pytest_nose`: test/plugin/nose.html
.. _`why pytest_pyfuncarg__ methods?`:
@@ -93,15 +109,15 @@ flexibility we decided to go for `Convention over Configuration`_ and
allow to directly specify the factory. Besides removing the need
for an indirection it allows to "grep" for ``pytest_funcarg__MYARG``
and will safely find all factory functions for the ``MYARG`` function
argument. It helps to alleviates the de-coupling of function
argument. It helps to alleviate the de-coupling of function
argument usage and creation.
.. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration
Can i yield multiple values from a factory function?
Can I yield multiple values from a factory function?
-----------------------------------------------------
There are two reasons why yielding from a factory function
There are two conceptual reasons why yielding from a factory function
is not possible:
* Calling factories for obtaining test function arguments
@@ -121,3 +137,36 @@ and implement the `parametrization scheme of your choice`_.
.. _`parametrization scheme of your choice`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/
py.test interaction with other packages
===============================================
Issues with py.test, multiprocess and setuptools?
------------------------------------------------------------
On windows the multiprocess package will instantiate sub processes
by pickling and thus implicitely re-import a lot of local modules.
Unfortuantely, setuptools-0.6.11 does not ``if __name__=='__main__'``
protect its generated command line script. This leads to infinite
recursion when running a test that instantiates Processes.
There are these workarounds:
* `install Distribute`_ as a drop-in replacement for setuptools
and install py.test
* `directly use a checkout`_ which avoids all setuptools/Distribute
installation
If those options are not available to you, you may also manually
fix the script that is created by setuptools by inserting an
``if __name__ == '__main__'``. Or you can create a "pytest.py"
script with this content and invoke that with the python version::
import py
if __name__ == '__main__':
py.cmdline.pytest()
.. _`directly use a checkout`: install.html#directly-use-a-checkout
.. _`install distribute`: http://pypi.python.org/pypi/distribute#installation-instructions

View File

@@ -1,14 +1,12 @@
py lib: testing and distributed programming library
py lib: testing and filesystem abstraction
====================================================
The ``py`` lib has several namespaces which help with testing,
generating and distributing code across machines. Here is
documentation on the most interesting ones:
The ``py`` lib has several namespaces which help with automated testing,
and with accessing filesystems. Here is some documentation on the
core namespaces:
`py.test`_ write and deploy unit- and functional tests to multiple machines.
`py.execnet`_ elastic distributed programming.
`py.code`_: generate code and use advanced introspection/traceback support.
`py.path`_: use path objects to transparently access local and svn filesystems.
@@ -31,9 +29,7 @@ Other (minor) support functionality
For the latest Release, see `PyPI project page`_
.. _`download and installation`: download.html
.. _`py-dev at codespeak net`: http://codespeak.net/mailman/listinfo/py-dev
.. _`py.execnet`: execnet.html
.. _`py.log`: log.html
.. _`py.io`: io.html
.. _`py.path`: path.html

190
doc/install.txt Normal file
View File

@@ -0,0 +1,190 @@
.. _`index page`: http://pypi.python.org/pypi/py/
py.test/pylib installation info in a nutshell
===================================================
**Pythons**: 2.4, 2.5, 2.6, 2.7, 3.0, 3.1.x, Jython-2.5.1, PyPy-1.2
**Operating systems**: Linux, Windows, OSX, Unix
**Requirements**: setuptools_ or Distribute_
**Installers**: easy_install_ and pip_ or `standalone`_ (new for 1.2)
**Distribution names**:
* PyPI name: ``py`` (see `index page`_ for versions)
* redhat fedora: ``python-py``
* debian: ``python-codespeak-lib``
* gentoo: ``pylib``
**Installed scripts**: see `bin`_ for which and how scripts are installed.
**hg repository**: https://bitbucket.org/hpk42/py-trunk
.. _`bin`: bin.html
Best practise: install tool and dependencies virtually
===========================================================
It is recommended to work with virtual environments
(e.g. virtualenv_ or buildout_ based) and use easy_install_
(or pip_) for installing py.test/pylib and any dependencies
you need to run your tests. Local virtual Python environments
(as opposed to system-wide "global" environments) make for a more
reproducible and reliable test environment.
.. _`virtualenv`: http://pypi.python.org/pypi/virtualenv
.. _`buildout`: http://www.buildout.org/
.. _pip: http://pypi.python.org/pypi/pip
.. _`easy_install`:
using easy_install (from setuptools or Distribute)
===================================================
Both `Distribute`_ and setuptools_ provide the ``easy_install``
installation tool. While setuptools should work ok with
Python2 interpreters, `Distribute`_ also works with Python3
and it avoids some issues on Windows. In both cases you
can open a command line window and then type::
easy_install -U py
to install the latest release of the py lib and py.test. The ``-U`` switch
will trigger an upgrade if you already have an older version installed.
If you now type::
py.test --version
you should see the version number and the import location of the tool.
Maybe you want to head on with the `quickstart`_ now?
.. _quickstart: test/quickstart.html
.. _standalone:
Generating a py.test standalone Script
============================================
If you are a maintainer or application developer and want users
to run tests you can use a facility to generate a standalone
"py.test" script that you can tell users to run::
py.test --genscript=mytest
will generate a ``mytest`` script that is, in fact, a ``py.test`` under
disguise. You can tell people to download and then e.g. run it like this::
python mytest --pastebin=all
and ask them to send you the resulting URL. The resulting script has
all core features and runs unchanged under Python2 and Python3 interpreters.
Troubleshooting / known issues
===============================
.. _`Jython does not create command line launchers`: http://bugs.jython.org/issue1491
**Jython2.5.1 on XP**: `Jython does not create command line launchers`_
so ``py.test`` will not work correctly. You may install py.test on
CPython and type ``py.test --genscript=mytest`` and then use
``jython mytest`` to run py.test for your tests to run in Jython.
**On Linux**: If ``easy_install`` fails because it needs to run
as the superuser you are trying to install things globally
and need to put ``sudo`` in front of the command.
**On Windows**: If "easy_install" or "py.test" are not found
please see here: `How do i run a Python program under Windows?`_
.. _`How do i run a Python program under Windows?`: http://www.python.org/doc/faq/windows/#how-do-i-run-a-python-program-under-windows
.. _mercurial: http://mercurial.selenic.com/wiki/
.. _`Distribute`:
.. _`Distribute for installation`: http://pypi.python.org/pypi/distribute#installation-instructions
.. _`distribute installation`: http://pypi.python.org/pypi/distribute
.. _checkout:
.. _tarball:
Working from version control or a tarball
=================================================
To follow development or start experiments, checkout the
complete code and documentation source with mercurial_::
hg clone https://bitbucket.org/hpk42/py-trunk/
Development takes place on the 'trunk' branch.
You can also go to the python package index and
download and unpack a TAR file::
http://pypi.python.org/pypi/py/
activating a checkout with setuptools
--------------------------------------------
With a working `Distribute`_ or setuptools_ installation you can type::
python setup.py develop
in order to work inline with the tools and the lib of your checkout.
.. _`no-setuptools`:
.. _`directly use a checkout`:
directly use a checkout or tarball / avoid setuptools
-------------------------------------------------------------
Get a checkout_ or tarball_ and add paths to your environment variables:
* ``PYTHONPATH`` needs to contain the root directory (where ``py`` resides)
* ``PATH`` needs to contain ``ROOT/bin`` or ``ROOT\bin\win32`` respectively.
There also are helper scripts that set the variables accordingly. On windows
execute::
# inside autoexec.bat or shell startup
c:\\path\to\checkout\bin\env.cmd
on linux/OSX add this to your shell initialization::
# inside e.g. .bashrc
eval `python ~/path/to/checkout/bin/env.py`
both of which which will get you good settings. If you install
the pylib this way you can easily ``hg pull && hg up`` or download
a new tarball_ to follow the development tree.
Note that the scripts manually added like this will look for
py libs in the chain of parent directories of the current working dir.
For example, if you have a layout like this::
mypkg/
subpkg1/
tests/
tests/
py/
issuing ``py.test subpkg1`` will use the py lib
from that projects root directory. If in doubt over where
the pylib comes from you can always do::
py.test --version
to see where py.test is imported from.
.. _`command line scripts`: bin.html
.. _contact: contact.html
.. _`RPM`: http://translate.sourceforge.net/releases/testing/fedora/pylib-0.9.2-1.fc9.noarch.rpm
.. _`setuptools`: http://pypi.python.org/pypi/setuptools

View File

@@ -9,10 +9,10 @@ execution of a program.
IO Capturing examples
===============================================
:api:`py.io.StdCapture`
``py.io.StdCapture``
---------------------------
Basic Example:
Basic Example::
>>> import py
>>> capture = py.io.StdCapture()
@@ -21,7 +21,7 @@ Basic Example:
>>> out.strip() == "hello"
True
For calling functions you may use a shortcut:
For calling functions you may use a shortcut::
>>> import py
>>> def f(): print "hello"
@@ -29,14 +29,14 @@ For calling functions you may use a shortcut:
>>> out.strip() == "hello"
True
:api:`py.io.StdCaptureFD`
``py.io.StdCaptureFD``
---------------------------
If you also want to capture writes to the stdout/stderr
filedescriptors you may invoke:
filedescriptors you may invoke::
>>> import py, sys
>>> capture = py.io.StdCaptureFD()
>>> capture = py.io.StdCaptureFD(out=False, in_=False)
>>> sys.stderr.write("world")
>>> out,err = capture.reset()
>>> err

View File

@@ -5,7 +5,7 @@ Miscellaneous features of the py lib
Mapping the standard python library into py
===========================================
The :api:`py.std` object allows lazy access to
The ``py.std`` object allows lazy access to
standard library modules. For example, to get to the print-exception
functionality of the standard library you can write::
@@ -21,9 +21,9 @@ Support for interaction with system utilities/binaries
======================================================
Currently, the py lib offers two ways to interact with
system executables. :api:`py.process.cmdexec()` invokes
system executables. ``py.process.cmdexec()`` invokes
the shell in order to execute a string. The other
one, :api:`py.path.local`'s 'sysexec()' method lets you
one, ``py.path.local``'s 'sysexec()' method lets you
directly execute a binary.
Both approaches will raise an exception in case of a return-
@@ -87,44 +87,7 @@ right version::
binsvn = py.path.local.sysfind('svn', checker=mysvn)
Cross-Python Version compatibility helpers
=============================================
sources:
* :source:`py/compat/`
* :source:`py/builtin/`
The compat and builtin namespaces help to write code using newer python features on older python interpreters.
:api:`py.compat`
----------------
:api:`py.compat` provides fixed versions (currently taken from Python 2.4.4) of
a few selected modules to be able to use them across python versions. Currently these are:
* doctest
* optparse
* subprocess
* textwrap
Note that for example ``import doctest`` and ``from py.compat import doctest`` result
into two different module objects no matter what Python version you are using.
So you should only use exactly one of these to avoid confusion in your program.
:api:`py.builtin`
-----------------
:api:`py.builtin` provides builtin functions/types that were added in later Python
versions. If the used Python version used does not provide these builtins the
py lib provides some reimplementations. These currently are:
* enumerate
* reversed
* sorted
* BaseException
* set and frozenset (using either the builtin, if available, or the sets
module)
:api:`py.builtin.BaseException` is just ``Exception`` before Python 2.5.
The ``py.builtin`` namespace provides a number of helpers that help to write python code compatible across Python interpreters, mainly Python2 and Python3. Type ``help(py.builtin)`` on a Python prompt for a the selection of builtins.

View File

@@ -3,17 +3,17 @@ py.path
=======
The 'py' lib provides a uniform high-level api to deal with filesystems
and filesystem-like interfaces: :api:`py.path`. It aims to offer a central
and filesystem-like interfaces: ``py.path``. It aims to offer a central
object to fs-like object trees (reading from and writing to files, adding
files/directories, examining the types and structure, etc.), and out-of-the-box
provides a number of implementations of this API.
Path implementations provided by :api:`py.path`
Path implementations provided by ``py.path``
===============================================
.. _`local`:
:api:`py.path.local`
``py.path.local``
--------------------
The first and most obvious of the implementations is a wrapper around a local
@@ -21,8 +21,8 @@ filesystem. It's just a bit nicer in usage than the regular Python APIs, and
of course all the functionality is bundled together rather than spread over a
number of modules.
Example usage, here we use the :api:`py.test.ensuretemp()` function to create
a :api:`py.path.local` object for us (which wraps a directory):
Example usage, here we use the ``py.test.ensuretemp()`` function to create
a ``py.path.local`` object for us (which wraps a directory):
.. sourcecode:: pycon
@@ -40,17 +40,17 @@ a :api:`py.path.local` object for us (which wraps a directory):
>>> foofile.read(1)
'b'
:api:`py.path.svnurl` and :api:`py.path.svnwc`
``py.path.svnurl`` and ``py.path.svnwc``
----------------------------------------------
Two other :api:`py.path` implementations that the py lib provides wrap the
Two other ``py.path`` implementations that the py lib provides wrap the
popular `Subversion`_ revision control system: the first (called 'svnurl')
by interfacing with a remote server, the second by wrapping a local checkout.
Both allow you to access relatively advanced features such as metadata and
versioning, and both in a way more user-friendly manner than existing other
solutions.
Some example usage of :api:`py.path.svnurl`:
Some example usage of ``py.path.svnurl``:
.. sourcecode:: pycon
@@ -65,7 +65,7 @@ Some example usage of :api:`py.path.svnurl`:
>>> time.strftime('%Y-%m-%d', time.gmtime(firstentry.date))
'2004-10-02'
Example usage of :api:`py.path.svnwc`:
Example usage of ``py.path.svnwc``:
.. sourcecode:: pycon
@@ -125,7 +125,7 @@ specific directory.
Working with Paths
.......................
This example shows the :api:`py.path` features to deal with
This example shows the ``py.path`` features to deal with
filesystem paths Note that the filesystem is never touched,
all operations are performed on a string level (so the paths
don't have to exist, either):
@@ -154,7 +154,7 @@ don't have to exist, either):
>>> p4.purebasename == "bar"
True
This should be possible on every implementation of :api:`py.path`, so
This should be possible on every implementation of ``py.path``, so
regardless of whether the implementation wraps a UNIX filesystem, a Windows
one, or a database or object tree, these functions should be available (each
with their own notion of path seperators and dealing with conversions, etc.).
@@ -189,7 +189,7 @@ Setting svn-properties
.......................
As an example of 'uncommon' methods, we'll show how to read and write
properties in an :api:`py.path.svnwc` instance:
properties in an ``py.path.svnwc`` instance:
.. sourcecode:: pycon
@@ -246,7 +246,7 @@ on the `svn` command line, not on the bindings.
It makes sense now to directly use the bindings.
Moreover, it would be good, also considering
`py.execnet`_ distribution of programs, to
`execnet`_ distribution of programs, to
be able to manipulate Windows Paths on Linux
and vice versa. So we'd like to consider
refactoring the path implementations
@@ -254,7 +254,7 @@ to provide this choice (and getting rid
of platform-dependencies as much as possible).
There is some experimental small approach
(:source:`py/path/gateway/`) aiming at having
(``py/path/gateway/``) aiming at having
a convenient Remote Path implementation.
There are various hacks out there to have
@@ -269,5 +269,5 @@ the quite full interface without requiring
to know about all details of the full path
implementation.
.. _`py.execnet`: execnet.html
.. _`execnet`: execnet.html

View File

@@ -744,6 +744,7 @@ td.toplist {
img#pyimg {
float: left;
padding-bottom: 1em;
}
div#navspace {

View File

@@ -95,8 +95,8 @@ per-test run basetemp directory.
.. _`function arguments`: funcargs.html
.. _`extensions`:
Plugin basics
=========================
Plugin basics and project configuration
=============================================
.. _`local plugin`:
@@ -125,6 +125,8 @@ Plugin discovery at tool startup
py.test loads plugin modules at tool startup in the following way:
* by loading all plugins registered through `setuptools entry points`_.
* by reading the ``PYTEST_PLUGINS`` environment variable
and importing the comma-separated list of named plugins.
@@ -132,17 +134,13 @@ py.test loads plugin modules at tool startup in the following way:
and loading the specified plugin before actual command line parsing.
* by loading all `conftest.py plugin`_ files as inferred by the command line
invocation
invocation (test files and all of its parent directories).
Note that ``conftest.py`` files from sub directories are loaded
during test collection and not at tool startup.
* by recursively loading all plugins specified by the
``pytest_plugins`` variable in a ``conftest.py`` file
Note that at tool startup only ``conftest.py`` files in
the directory of the specified test modules (or the current dir if None)
or any of the parent directories are found. There is no try to
pre-scan all subdirectories to find ``conftest.py`` files or test
modules.
Specifying plugins in a test module or plugin
-----------------------------------------------
@@ -160,8 +158,8 @@ must be lowercase.
.. _`conftest.py plugin`:
.. _`conftestplugin`:
conftest.py as anonymous per-project plugins
--------------------------------------------------
Writing per-project plugins (conftest.py)
------------------------------------------------------
The purpose of ``conftest.py`` files is to allow `project-specific
test configuration`_. They thus make for a good place to implement
@@ -181,6 +179,55 @@ by defining the following hook in a ``conftest.py`` file:
if config.getvalue("runall"):
collect_ignore[:] = []
.. _`setuptools entry points`:
Writing setuptools-registered plugins
------------------------------------------------------
.. _`Distribute`: http://pypi.python.org/pypi/distribute
.. _`setuptools`: http://pypi.python.org/pypi/setuptools
If you want to make your plugin publically available, you
can use `setuptools`_ or `Distribute`_ which both allow
to register an entry point. ``py.test`` will register
all objects with the ``pytest11`` entry point.
To make your plugin available you may insert the following
lines in your setuptools/distribute-based setup-invocation:
.. sourcecode:: python
# sample ./setup.py file
from setuptools import setup
setup(
name="myproject",
packages = ['myproject']
# the following makes a plugin available to py.test
entry_points = {
'pytest11': [
'name_of_plugin = myproject.pluginmodule',
]
},
)
If a package is installed with this setup, py.test will load
``myproject.pluginmodule`` under the ``name_of_plugin`` name
and use it as a plugin.
Accessing another plugin by name
--------------------------------------------
If a plugin wants to collaborate with code from
another plugin it can obtain a reference through
the plugin manager like this:
.. sourcecode:: python
plugin = config.pluginmanager.getplugin("name_of_plugin")
If you want to look at the names of existing plugins, use
the ``--traceconfig`` option.
.. _`well specified hooks`:
.. _`implement hooks`:
@@ -226,6 +273,8 @@ for example:
When the test run finishes this corresponding finalizer hook is called:
.. sourcecode:: python
def pytest_unconfigure(config):
...
@@ -234,7 +283,9 @@ adding global py.test helpers and functionality
--------------------------------------------------------------------
If you want to make global helper functions or objects available
to your test code you can implement:
to your test code you can implement:
.. sourcecode:: python
def pytest_namespace():
""" return dictionary with items to be made available on py.test. namespace """
@@ -293,7 +344,7 @@ A ``report`` object contains status and reporting information:
report.failed = True or False
report.skipped = True or False
The `pytest_terminal plugin`_ uses this hook to print information
The `terminal plugin`_ uses this hook to print information
about a test run.
The whole protocol described here is implemented via this hook:
@@ -312,8 +363,8 @@ The call object contains information about a performed call:
call.when = "setup", "call" or "teardown"
call.outerr = None or tuple of strings representing captured stdout/stderr
.. _`pytest_pdb plugin`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_pdb.py
.. _`pytest_terminal plugin`: http://bitbucket.org/hpk42/py-trunk/src/tip/py/test/plugin/pytest_terminal.py
.. _`pytest_pdb plugin`: plugin/pdb.html
.. _`terminal plugin`: plugin/terminal.html
generic collection hooks
@@ -353,6 +404,26 @@ Python module. The return value is a custom `collection node`_ or None.
.. XXX or ``False`` if you want to indicate that the given item should not be collected.
Gateway initialization (distributed testing)
----------------------------------------------------
(alpha) For distributed testing it can be useful to prepare the
remote environment. For this you can implement the newgateway hook:
.. sourcecode:: python
def pytest_gwmanage_newgateway(gateway, platinfo):
""" called after a gateway is instantiated. """
The ``gateway`` object here has a ``spec`` attribute which is an ``execnet.XSpec``
object, which has attributes that map key/values as specified from a ``--txspec``
option. The platinfo object is a dictionary with information about the remote process:
* ``version``: remote python's ``sys.version_info``
* ``platform``: remote ``sys.platform``
* ``cwd``: remote ``os.getcwd``
.. _`collection process`:
.. _`collection node`:
.. _`test collection`:
@@ -395,6 +466,15 @@ and test classes and methods. Test functions and methods
are prefixed ``test`` by default. Test classes must
start with a capitalized ``Test`` prefix.
Customizing error messages
-------------------------------------------------
On test and collection nodes ``py.test`` will invoke
the ``node.repr_failure(excinfo)`` function which
you may override and make it return an error
representation string of your choice. It
will be reported as a (red) string.
.. _`package name`:
constructing the package name for test modules
@@ -409,13 +489,3 @@ name. Given a filesystem ``fspath`` it is constructed as follows:
* perform ``sys.path.insert(0, basedir)``.
* import the root package as ``root``
* determine the fully qualified name for ``fspath`` by either:
* calling ``root.__pkg__.getimportname(fspath)`` if the
``__pkg__`` exists.` or
* otherwise use the relative path of the module path to
the base dir and turn slashes into dots and strike
the trailing ``.py``.

18
doc/test/dist.html Normal file
View File

@@ -0,0 +1,18 @@
<html>
<head>
<meta http-equiv="refresh" content=" 1 ; URL=plugin/xdist.html" />
</head>
<body>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-7597274-3");
pageTracker._trackPageview();
} catch(err) {}</script>
</body>
</html>

View File

@@ -1,125 +0,0 @@
.. _`distribute tests across machines`:
===================
Distributed testing
===================
``py.test`` can ad-hoc distribute test runs to multiple CPUs or remote
machines. This allows to speed up development or to use special resources
of remote machines. Before running tests remotely, ``py.test`` efficiently
synchronizes your program source code to the remote place. All test results
are reported back and displayed to your local test session. You may
specify different Python versions and interpreters.
Synchronisation and running of tests only requires
a bare Python installation on the remote side. No
special software is installed - this is realized
by use of the **zero installation** `py.execnet`_ mechanisms.
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.
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 provided specifications strings
use the `xspec syntax`_.
.. _`xspec syntax`: ../execnet.html#xspec
.. _`socketserver.py`: http://codespeak.net/svn/py/dist/py/execnet/script/socketserver.py
.. _`py.execnet`: ../execnet.html
Specifying test exec environments in a conftest.py
-------------------------------------------------------------
Instead of specifying command line options, you can
put options values in a ``conftest.py`` file like this::
pytest_option_tx = ['ssh=myhost//python=python2.5', 'popen//python=python2.5']
pytest_option_dist = True
Any commandline ``--tx`` specifictions will add to the list of available execution
environments.
Specifying "rsync" dirs in a conftest.py
-------------------------------------------------------------
In your ``mypkg/conftest.py`` you may specify directories to synchronise
or to exclude::
rsyncdirs = ['.', '../plugins']
rsyncignore = ['_cache']
These directory specifications are relative to the directory
where the ``conftest.py`` is found.

View File

@@ -9,24 +9,42 @@ py.test feature overview
mature command line testing tool
====================================================
py.test is a command line tool to collect and run automated tests. It
runs well on Linux, Windows and OSX Python 2.4 through to 2.6 versions.
It can distribute a single test run to multiple machines. It is used in
many projects, ranging from running 10 thousands of tests integrated
with buildbot to a few inlined tests on a command line script.
py.test is a command line tool to collect, run and report about automated tests. It runs well on Linux, Windows and OSX and on Python 2.4 through to 3.1 versions.
It is used in many projects, ranging from running 10 thousands of tests
to a few inlined tests on a command line script. As of version 1.2 you can also
generate a no-dependency py.test-equivalent standalone script that you
can distribute along with your application.
.. _`autocollect`:
extensive easy plugin system
======================================================
automatically collects and executes tests
===============================================
.. _`suprisingly easy`: http://bruynooghe.blogspot.com/2009/12/skipping-slow-test-by-default-in-pytest.html
py.test discovers tests automatically by looking at
specified directories and its files for common
naming patterns. As ``py.test`` operates as a separate
cmdline tool you can easily have a command line utility and
some tests in the same file.
py.test delegates almost all aspects of its operation to plugins_.
It is `suprisingly easy`_ to add command line options or
do other kind of add-ons and customizations. This can
be done per-project or by distributing a global plugin.
One can can thus modify or add aspects for purposes such as:
supports many testing practises and methods
* reporting extensions
* customizing collection and execution of tests
* running and managing non-python tests
* managing domain-specific test state setup
* adding non-python tests into the run, e.g. driven by data files
.. _`plugins`: plugin/index.html
distributing tests to your CPUs and SSH accounts
==========================================================
.. _`pytest-xdist`: plugin/xdist.html
Through the use of the separately released `pytest-xdist`_ plugin you
can seemlessly distribute runs to multiple CPUs or remote computers
through SSH and sockets. This plugin also offers a ``--looponfailing``
mode which will continously re-run only failing tests in a subprocess.
supports several testing practises and methods
==================================================================
py.test supports many testing methods conventionally used in
@@ -40,9 +58,20 @@ with figleaf`_ or `Javasript unit- and functional testing`_.
.. _`Javasript unit- and functional testing`: plugin/oejskit.html
.. _`coverage testing with figleaf`: plugin/figleaf.html
integrates well with CI systems
====================================================
py.test can produce JUnitXML style output as well as formatted
"resultlog" files that can be postprocessed by Continous Integration
systems such as Hudson or Buildbot easily. It also provides command
line options to control test configuration lookup behaviour or ignoring
certain tests or directories.
no-boilerplate test functions with Python
===================================================
.. _`autocollect`:
automatic Python test discovery
------------------------------------
@@ -53,13 +82,18 @@ filename are inspected for finding tests:
* classes with a leading ``Test`` name and ``test`` prefixed methods.
* ``unittest.TestCase`` subclasses
test functions can run with different argument sets
-----------------------------------------------------------
parametrizing test functions and advanced 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
functions with different argument values.
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
----------------------------------------------------
@@ -96,14 +130,35 @@ first failed and then succeeded.
asserting expected exceptions
----------------------------------------
In order to write assertions about exceptions, you use
one of two forms::
In order to write assertions about exceptions, you can use
``py.test.raises`` as a context manager like this:
py.test.raises(Exception, func, *args, **kwargs)
py.test.raises(Exception, "func(*args, **kwargs)")
.. sourcecode:: python
with py.test.raises(ZeroDivisionError):
1 / 0
and if you need to have access to the actual exception info you may use:
.. sourcecode:: python
with py.test.raises(RuntimeError) as excinfo:
def f():
f()
f()
# do checks related to excinfo.type, excinfo.value, excinfo.traceback
If you want to write test code that works on Python2.4 as well,
you may also use two other ways to test for an expected exception:
.. sourcecode:: python
py.test.raises(ExpectedException, func, *args, **kwargs)
py.test.raises(ExpectedException, "func(*args, **kwargs)")
both of which execute the specified function with args and kwargs and
asserts that the given ``Exception`` is raised. The reporter will
asserts that the given ``ExpectedException`` is raised. The reporter will
provide you with helpful output in case of failures such as *no
exception* or *wrong exception*.
@@ -123,61 +178,27 @@ command line. Using the `--pdb`` option you can automatically activate
a PDB `Python debugger`_ when a test fails.
advanced skipping of tests
-------------------------------
======================================
If you want to skip tests you can use ``py.test.skip`` within
test or setup functions. Example::
def test_hello():
if sys.platform != "win32":
py.test.skip("only win32 supported")
You can also use a helper to skip on a failing import::
docutils = py.test.importorskip("docutils")
or to skip if a library does not have the right version::
docutils = py.test.importorskip("docutils", minversion="0.3")
The version will be read from the specified module's ``__version__`` attribute.
py.test has `advanced support for skipping tests`_ or expecting
failures on tests on certain platforms. Apart from the
minimal py.test style also unittest- and nose-style tests
can make use of this feature.
.. _`advanced support for skipping tests`: plugin/skipping.html
.. _`funcargs mechanism`: funcargs.html
.. _`unittest.py`: http://docs.python.org/library/unittest.html
.. _`doctest.py`: http://docs.python.org/library/doctest.html
.. _`xUnit style setup`: xunit_setup.html
.. _`pytest_nose`: plugin/nose.html
load-balance test runs to multiple CPUs
========================================
For large test suites you can distribute your
tests to multiple CPUs by issuing for example::
py.test -n 3
Read more on `distributed testing`_.
.. _`distributed testing`: dist.html
ad-hoc run tests cross-platform
==================================================
py.test supports the sending of tests to
remote ssh-accounts, socket servers.
It can `ad-hoc run your test on multiple
platforms one a single test run`. Ad-hoc
means that there are **no installation
requirements whatsoever** on the remote side.
.. _`ad-hoc run your test on multiple platforms one a single test run`: dist.html#atonce
advanced test selection and running modes
=========================================================
.. _`selection by keyword`:
``py.test --looponfailing`` allows to run a test suite,
``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.
@@ -202,7 +223,9 @@ 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::
kewords like this:
.. sourcecode:: python
@py.test.mark.webtest
def test_send_http():
@@ -211,23 +234,8 @@ kewords like this::
and then use those keywords to select tests. See the `pytest_keyword`_
plugin for more information.
.. _`pytest_keyword`: plugin/keyword.html
.. _`pytest_keyword`: plugin/mark.html
easy to extend
=========================================
py.test has advanced `extension mechanisms`_
with a growing `list of default plugins`_.
One can can easily modify or add aspects for for
purposes such as:
* reporting extensions
* customizing collection and execution of tests
* running and managing non-python tests
* managing domain-specific test state setup
.. _`list of default plugins`: plugin/index.html
.. _`extension mechanisms`: customize.html#extensions
.. _`reStructured Text`: http://docutils.sourceforge.net
.. _`Python debugger`: http://docs.python.org/lib/module-pdb.html

View File

@@ -1,43 +1,320 @@
==========================================================
**funcargs**: test function arguments FTW
==========================================================
==============================================================
**funcargs**: advanced test fixtures and parametrization
==============================================================
.. contents::
:local:
:depth: 2
Goals of the "funcarg" mechanism
==========================================
what is a "funcarg"?
=================================================
Since version 1.0 py.test features the "funcarg" mechanism which
allows a Python test function to take arguments independently provided
by factory functions. Factory functions allow to encapsulate
all setup and fixture glue code into nicely separated objects
and provide a natural way for writing python test functions.
Compared to `xUnit style`_ the new mechanism is meant to:
* make test functions easier to write and to read
* isolate test fixture creation to a single place
* bring new flexibility and power to test state management
* naturally extend towards parametrizing test functions
with multiple argument sets
* enable creation of zero-boilerplate test helper objects that
interact with the execution of a test function, see the
`blog post about the monkeypatch funcarg`_.
If you find issues or have further suggestions for improving
the mechanism you are welcome to checkout `contact possibilities`_ page.
A *funcarg* is the short name for "test function argument". Each python test function invocation may receive one or multiple function arguments. Function argument values can be created next to the test code or in separate test configuration files which allows test functions to remain ignorant of how its base test values are created. A test function can also be called multiple times with different sets of function arguments, allowing for arbitrary parametrization. A Funcarg parameter can be any value, a simple number or an application object.
.. _`contact possibilities`: ../contact.html
.. _`parametrizing tests, generalized`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/
.. _`blog post about the monkeypatch funcarg`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/
.. _`xUnit style`: xunit_setup.html
.. _`funcarg factory`:
.. _factory:
funcarg factories: creating test function arguments
==============================================================
Test functions can specify one ore more arguments ("funcargs")
and a test module or plugin can define factory functions that provide
the function argument. Let's look at a simple self-contained
example that you can put into a test module:
.. sourcecode:: python
# ./test_simplefactory.py
def pytest_funcarg__myfuncarg(request):
return 42
def test_function(myfuncarg):
assert myfuncarg == 17
If you run this with ``py.test test_simplefactory.py`` you see something like this:
.. sourcecode:: python
=========================== test session starts ============================
python: platform linux2 -- Python 2.6.2
test object 1: /home/hpk/hg/py/trunk/example/funcarg/test_simplefactory.py
test_simplefactory.py F
================================ FAILURES ==================================
______________________________ test_function _______________________________
myfuncarg = 42
def test_function(myfuncarg):
> assert myfuncarg == 17
E assert 42 == 17
test_simplefactory.py:6: AssertionError
======================== 1 failed in 0.11 seconds ==========================
This means that the test function was called with a ``myfuncarg`` value
of ``42`` and the assert fails accordingly. Here is how py.test
calls the test function:
1. py.test discovers the ``test_function`` because of the ``test_`` prefix.
The test function needs a function argument named ``myfuncarg``.
A matching factory function is discovered by looking for the
name ``pytest_funcarg__myfuncarg``.
2. ``pytest_funcarg__myfuncarg(request)`` is called and
returns the value for ``myfuncarg``.
3. ``test_function(42)`` call is executed.
Note that if you misspell a function argument or want
to use one that isn't available, you'll see an error
with a list of available function arguments. You can
also issue::
py.test --funcargs test_simplefactory.py
to see available function arguments (which you can also
think of as "resources").
Factory functions receive a `request object`_
which they can use to register setup/teardown
functions or access meta data about a test.
.. _`request object`:
funcarg factory request objects
------------------------------------------
Request objects represents a handle on a specific python test function call. A request object is passed to a funcarg factory and provides access to test configuration and context as well as some `useful caching and finalization helpers`_. Here is a list of attributes:
``request.function``: python function object requesting the argument
``request.cls``: class object where the test function is defined in or None.
``request.module``: module object where the test function is defined in.
``request.config``: access to command line opts and general config
``request.param``: if exists was passed by a previous `metafunc.addcall`_
.. _`useful caching and finalization helpers`:
registering funcarg related finalizers/cleanup
----------------------------------------------------
.. sourcecode:: python
def addfinalizer(func):
""" call a finalizer function when test function finishes. """
Calling ``request.addfinalizer()`` is useful for scheduling teardown
functions. Here is an example for providing a ``myfile``
object that is to be closed when the execution of a
test function finishes.
.. sourcecode:: python
def pytest_funcarg__myfile(self, request):
# ... create and open a unique per-function "myfile" object ...
request.addfinalizer(lambda: myfile.close())
return myfile
managing fixtures across test modules and test runs
----------------------------------------------------------
.. sourcecode:: python
def cached_setup(setup, teardown=None, scope="module", extrakey=None):
""" cache and return result of calling setup().
The requested argument name, the scope and the ``extrakey``
determine the cache key. The scope also determines when
teardown(result) will be called. valid scopes are:
scope == 'function': when the single test function run finishes.
scope == 'module': when tests in a different module are run
scope == 'session': when tests of the session have run.
"""
Calling ``request.cached_setup()`` helps you to manage fixture
objects across several scopes. For example, for creating a Database object
that is to be setup only once during a test session you can use the helper
like this:
.. sourcecode:: python
def pytest_funcarg__database(request):
return request.cached_setup(
setup=lambda: Database("..."),
teardown=lambda val: val.close(),
scope="session"
)
dynamically applying a marker
---------------------------------------------
.. sourcecode:: python
def applymarker(self, marker):
""" apply a marker to a test function invocation.
The 'marker' must be created with py.test.mark.* XYZ.
"""
``request.applymarker(marker)`` will mark the test invocation
with the given marker. For example, if your funcarg factory provides
values which may cause a test function to fail you can call
``request.applymarker(py.test.mark.xfail(reason='flaky config'))``
and this will cause the test to not show tracebacks. See xfail_
for details.
.. _`xfail`: plugin/skipping.html#xfail
requesting values of other funcargs
---------------------------------------------
.. sourcecode:: python
def getfuncargvalue(name):
""" Lookup and call function argument factory for the given name.
Each function argument is only created once per function setup.
"""
``request.getfuncargvalue(name)`` calls another funcarg factory function.
You can use this function if you want to `decorate a funcarg`_, i.e.
you want to provide the "normal" value but add something
extra. If a factory cannot be found a ``request.Error``
exception will be raised.
.. _`test generators`:
.. _`parametrizing-tests`:
generating parametrized tests
===========================================================
You can parametrize multiple runs of the same test
function by adding new test function calls with different
function argument values. Let's look at a simple self-contained
example:
.. sourcecode:: python
# ./test_example.py
def pytest_generate_tests(metafunc):
if "numiter" in metafunc.funcargnames:
for i in range(10):
metafunc.addcall(funcargs=dict(numiter=i))
def test_func(numiter):
assert numiter < 9
If you run this with ``py.test test_example.py`` you'll get:
.. sourcecode:: python
============================= test session starts ==========================
python: platform linux2 -- Python 2.6.2
test object 1: /home/hpk/hg/py/trunk/test_example.py
test_example.py .........F
================================ FAILURES ==================================
__________________________ test_func.test_func[9] __________________________
numiter = 9
def test_func(numiter):
> assert numiter < 9
E assert 9 < 9
/home/hpk/hg/py/trunk/test_example.py:10: AssertionError
Here is what happens in detail:
1. ``pytest_generate_tests(metafunc)`` hook is called once for each test
function. It adds ten new function calls with explicit function arguments.
2. **execute tests**: ``test_func(numiter)`` is called ten times with
ten different arguments.
.. _`metafunc object`:
test generators and metafunc objects
-------------------------------------------
metafunc objects are passed to the ``pytest_generate_tests`` hook.
They help to inspect a testfunction and to generate tests
according to test configuration or values specified
in the class or module where a test function is defined:
``metafunc.funcargnames``: set of required function arguments for given function
``metafunc.function``: underlying python test function
``metafunc.cls``: class object where the test function is defined in or None.
``metafunc.module``: the module object where the test function is defined in.
``metafunc.config``: access to command line opts and general config
.. _`metafunc.addcall`:
the ``metafunc.addcall()`` method
-----------------------------------------------
.. sourcecode:: python
def addcall(funcargs={}, id=None, param=None):
""" trigger a new test function call. """
``funcargs`` can be a dictionary of argument names
mapped to values - providing it is called *direct parametrization*.
If you provide an `id`` it will be used for reporting
and identification purposes. If you don't supply an `id`
the stringified counter of the list of added calls will be used.
``id`` values needs to be unique between all
invocations for a given test function.
``param`` if specified will be seen by any
`funcarg factory`_ as a ``request.param`` attribute.
Setting it is called *indirect parametrization*.
Indirect parametrization is preferable if test values are
expensive to setup or can only be created in certain environments.
Test generators and thus ``addcall()`` invocations are performed
during test collection which is separate from the actual test
setup and test run phase. With distributed testing collection
and test setup/run happens in different process.
.. _`tutorial examples`:
Tutorial Examples
=======================================
To see how you can implement custom paramtrization schemes,
see e.g. `parametrizing tests, generalized`_ (blog post).
To enable creation of test support code that can flexibly
register setup/teardown functions see the `blog post about
the monkeypatch funcarg`_.
If you find issues or have further suggestions for improving
the mechanism you are welcome to checkout `contact possibilities`_ page.
.. _`application setup tutorial example`:
.. _appsetup:
@@ -165,7 +442,7 @@ and to offer a new mysetup method:
host = self.config.option.ssh
if host is None:
py.test.skip("specify ssh host with --ssh")
return py.execnet.SshGateway(host)
return execnet.SshGateway(host)
Now any test function can use the ``mysetup.getsshconnection()`` method like this:
@@ -274,261 +551,3 @@ methods in a convenient way.
.. _`py.path.local`: ../path.html#local
.. _`conftest plugin`: customize.html#conftestplugin
.. _`funcarg factory`:
funcarg factories: setting up test function arguments
==============================================================
Test functions can specify one ore more arguments ("funcargs")
and a test module or plugin can define functions that provide
the function argument. Let's look at a simple self-contained
example that you can put into a test module:
.. sourcecode:: python
# ./test_simplefactory.py
def pytest_funcarg__myfuncarg(request):
return 42
def test_function(myfuncarg):
assert myfuncarg == 17
If you run this with ``py.test test_simplefactory.py`` you see something like this:
.. sourcecode:: python
=========================== test session starts ============================
python: platform linux2 -- Python 2.6.2
test object 1: /home/hpk/hg/py/trunk/example/funcarg/test_simplefactory.py
test_simplefactory.py F
================================ FAILURES ==================================
______________________________ test_function _______________________________
myfuncarg = 42
def test_function(myfuncarg):
> assert myfuncarg == 17
E assert 42 == 17
test_simplefactory.py:6: AssertionError
======================== 1 failed in 0.11 seconds ==========================
This means that the test function got executed and the assertion failed.
Here is how py.test comes to execute this test function:
1. py.test discovers the ``test_function`` because of the ``test_`` prefix.
The test function needs a function argument named ``myfuncarg``.
A matching factory function is discovered by looking for the special
name ``pytest_funcarg__myfuncarg``.
2. ``pytest_funcarg__myfuncarg(request)`` is called and
returns the value for ``myfuncarg``.
3. ``test_function(42)`` call is executed.
Note that if you misspell a function argument or want
to use one that isn't available, an error with a list of
available function argument is provided.
For more interesting factory functions that make good use of the
`request object`_ please see the `application setup tutorial example`_.
.. _`request object`:
funcarg factory request objects
------------------------------------------
Request objects are passed to funcarg factories and allow
to access test configuration, test context and `useful caching
and finalization helpers`_. Here is a list of attributes:
``request.function``: python function object requesting the argument
``request.cls``: class object where the test function is defined in or None.
``request.module``: module object where the test function is defined in.
``request.config``: access to command line opts and general config
``request.param``: if exists was passed by a previous `metafunc.addcall`_
.. _`useful caching and finalization helpers`:
registering funcarg related finalizers/cleanup
----------------------------------------------------
.. sourcecode:: python
def addfinalizer(func):
""" call a finalizer function when test function finishes. """
Calling ``request.addfinalizer()`` is useful for scheduling teardown
functions. Here is an example for providing a ``myfile``
object that is to be closed when the execution of a
test function finishes.
.. sourcecode:: python
def pytest_funcarg__myfile(self, request):
# ... create and open a unique per-function "myfile" object ...
request.addfinalizer(lambda: myfile.close())
return myfile
managing fixtures across test modules and test runs
----------------------------------------------------------
.. sourcecode:: python
def cached_setup(setup, teardown=None, scope="module", extrakey=None):
""" cache and return result of calling setup().
The scope and the ``extrakey`` determine the cache key.
The scope also determines when teardown(result)
will be called. valid scopes are:
scope == 'function': when the single test function run finishes.
scope == 'module': when tests in a different module are run
scope == 'session': when tests of the session have run.
"""
Calling ``request.cached_setup()`` helps you to manage fixture
objects across several scopes. For example, for creating a Database object
that is to be setup only once during a test session you can use the helper
like this:
.. sourcecode:: python
def pytest_funcarg__database(request):
return request.cached_setup(
setup=lambda: Database("..."),
teardown=lambda val: val.close(),
scope="session"
)
requesting values of other funcargs
---------------------------------------------
.. sourcecode:: python
def getfuncargvalue(name):
""" Lookup and call function argument factory for the given name.
Each function argument is only created once per function setup.
"""
``request.getfuncargvalue(name)`` calls another funcarg factory function.
You can use this function if you want to `decorate a funcarg`_, i.e.
you want to provide the "normal" value but add something
extra. If a factory cannot be found a ``request.Error``
exception will be raised.
.. _`test generators`:
.. _`parametrizing-tests`:
generating parametrized tests
===========================================================
You can parametrize multiple runs of the same test
function by adding new test function calls with different
function argument values. Let's look at a simple self-contained
example:
.. sourcecode:: python
# ./test_example.py
def pytest_generate_tests(metafunc):
if "numiter" in metafunc.funcargnames:
for i in range(10):
metafunc.addcall(funcargs=dict(numiter=i))
def test_func(numiter):
assert numiter < 9
If you run this with ``py.test test_example.py`` you'll get:
.. sourcecode:: python
============================= test session starts ==========================
python: platform linux2 -- Python 2.6.2
test object 1: /home/hpk/hg/py/trunk/test_example.py
test_example.py .........F
================================ FAILURES ==================================
__________________________ test_func.test_func[9] __________________________
numiter = 9
def test_func(numiter):
> assert numiter < 9
E assert 9 < 9
/home/hpk/hg/py/trunk/test_example.py:10: AssertionError
Here is what happens in detail:
1. ``pytest_generate_tests(metafunc)`` hook is called once for each test
function. It adds ten new function calls with explicit function arguments.
2. **execute tests**: ``test_func(numiter)`` is called ten times with
ten different arguments.
.. _`metafunc object`:
test generators and metafunc objects
-------------------------------------------
metafunc objects are passed to the ``pytest_generate_tests`` hook.
They help to inspect a testfunction and to generate tests
according to test configuration or values specified
in the class or module where a test function is defined:
``metafunc.funcargnames``: set of required function arguments for given function
``metafunc.function``: underlying python test function
``metafunc.cls``: class object where the test function is defined in or None.
``metafunc.module``: the module object where the test function is defined in.
``metafunc.config``: access to command line opts and general config
.. _`metafunc.addcall`:
the ``metafunc.addcall()`` method
-----------------------------------------------
.. sourcecode:: python
def addcall(funcargs={}, id=None, param=None):
""" trigger a new test function call. """
``funcargs`` can be a dictionary of argument names
mapped to values - providing it is called *direct parametrization*.
If you provide an `id`` it will be used for reporting
and identification purposes. If you don't supply an `id`
the stringified counter of the list of added calls will be used.
``id`` values needs to be unique between all
invocations for a given test function.
``param`` if specified will be seen by any
`funcarg factory`_ as a ``request.param`` attribute.
Setting it is called *indirect parametrization*.
Indirect parametrization is preferable if test values are
expensive to setup or can only be created in certain environments.
Test generators and thus ``addcall()`` invocations are performed
during test collection which is separate from the actual test
setup and test run phase. With distributed testing collection
and test setup/run happens in different process.

Some files were not shown because too many files have changed in this diff Show More