nose 1.3.7
This commit is contained in:
parent
24ea0412b5
commit
3a5dd251de
432 changed files with 9624 additions and 2968 deletions
14
pythonPackages/nose/AUTHORS
Executable file → Normal file
14
pythonPackages/nose/AUTHORS
Executable file → Normal file
|
@ -11,3 +11,17 @@ Pam Zerbinos
|
|||
Augie Fackler
|
||||
Peter Fein
|
||||
Kevin Mitchell
|
||||
Alex Stewart
|
||||
Timothee Peignier
|
||||
Thomas Kluyver
|
||||
Heng Liu
|
||||
Rosen Diankov
|
||||
Buck Golemon
|
||||
Bobby Impollonia
|
||||
Takafumi Arakaki
|
||||
Peter Bengtsson
|
||||
Gary Donovan
|
||||
Brendan McCollam
|
||||
Erik Rose
|
||||
Sascha Peilicke
|
||||
Andre Caron
|
||||
|
|
342
pythonPackages/nose/CHANGELOG
Executable file → Normal file
342
pythonPackages/nose/CHANGELOG
Executable file → Normal file
|
@ -1,3 +1,323 @@
|
|||
1.3.7
|
||||
|
||||
- Fix loading packages from capitalised package on Windows
|
||||
Patch by Thomas Kluyver
|
||||
|
||||
1.3.6
|
||||
|
||||
- Re-release of 1.3.5 with wheels fixed.
|
||||
|
||||
1.3.5
|
||||
|
||||
- Fix #875: nose doesn't collect tests when subpackage is given as arg
|
||||
- Fix #809: tests not discovered for namespace packages on Windows
|
||||
- Fix #815: "ValueError: unsupported pickle protocol" with --with-id
|
||||
- Wrap the working dir path name in quotes when reporting an error.
|
||||
Patch by Őry Máté.
|
||||
- Fix #887: Fix a discrepancy in test names between Python 2 and Python 3
|
||||
- Fix #131: Use os.stat() to check if file is executable
|
||||
Patch by Arnon Yaari.
|
||||
- Fix #820 and #719: Fix coverage plugin with multiprocess
|
||||
Patch by Nicolas Grasset.
|
||||
|
||||
1.3.4
|
||||
|
||||
- Recognize doctest options defined in other plugins
|
||||
Patch by Daniel Lepage
|
||||
- Another fix for Python 3.4: Call super in LazySuite to access
|
||||
_removed_tests variable
|
||||
Patch by Robert Kuska
|
||||
- Fix for try_run when using bound methods
|
||||
Patch by Christian Lyder Jacobsen
|
||||
|
||||
1.3.3
|
||||
|
||||
- Fixed a minor issue with the reported version number.
|
||||
|
||||
1.3.2
|
||||
|
||||
- Fixed an issue where build_ext was not working under setup.py nosetest
|
||||
Patch by Michael Crusoe
|
||||
- Fixed #786: generator method fails with callable instance
|
||||
Patch by Antoine Dechaume
|
||||
- Fixed a traceback when using string exceptions
|
||||
- Fixed #792: "Not a directory" error when using python setup.py nosetests
|
||||
- Fixed #779: xunit report file is written in --where directory
|
||||
- Fixed #782: Test failures with Python >= 3.3
|
||||
Patch by Dmitry Shachnev
|
||||
- Fixed #780: Fix a regression with Python 3
|
||||
- Fixed #783: try_run is broken with Python 3.4
|
||||
|
||||
1.3.1
|
||||
|
||||
- The log capture plugin now correctly applies filters that were added
|
||||
using `addFilter`.
|
||||
Patch by Malthe Borch.
|
||||
- Corrected a reference to the multiprocessing plugin in the documentation.
|
||||
Patch by Nick Loadholtes.
|
||||
- Fixed #447: doctests fail when getpackage() returns None
|
||||
Patch by Matthew Brett.
|
||||
- Fixed #749: xunit exceeds recursion limit
|
||||
Patch by André Caron.
|
||||
- Fixed a number of unicode-related issues.
|
||||
Patch by John Szakmeister.
|
||||
- Added the ability to ignore config files via an environment variable
|
||||
Patch by Lukasz Balcerzak
|
||||
- Fixed #720: nose with detailed errors raises encoding error
|
||||
Patch by John Szakmeister. Thanks to Guillaume Ayoub for the test case.
|
||||
- Fixed #692: UnicodeDecodeError in xunit when capturing stdout and stderr
|
||||
Patch by John Szakmeister.
|
||||
- Fixed #693: Python 2.4 incompatibilities
|
||||
Patch by John Szakmeister.
|
||||
- Don't save zero-byte xunit test reports
|
||||
Patch by Dan Savilonis.
|
||||
- Fix Importer.importFromPath to be able to import modules whose names start
|
||||
with __init__
|
||||
Patch by Paul Bonser.
|
||||
- Add a fake isatty() method to Tee
|
||||
Patch by Jimmy Wennlund.
|
||||
- Fix #700: Tee is missing the writelines() method
|
||||
Patch by John Szakmeister.
|
||||
- Fix #649: UnicodeDecodeError when an exception contains encoded strings
|
||||
Patch by John Szakmeister.
|
||||
- Fix #687: verbosity is not a flag
|
||||
Patch by John Szakmeister.
|
||||
- Fixed a suppressed deprecation warning
|
||||
Patch by Arnon Yaari.
|
||||
- Fixed some broken links in the documentation
|
||||
Patch by Arnon Yaari.
|
||||
- Add missing format parameter in error message
|
||||
Patch by Etienne Millon.
|
||||
- Switched docs to point at the GitHub site for the issue tracker
|
||||
Patch by Daniel Beck.
|
||||
- Fix #447: doctests fail when getpackage() returns None
|
||||
Patch by Matthew Brett.
|
||||
- Fix #366: make --pdb report on errors and failures. Use --pdb-error to get
|
||||
the old behavior.
|
||||
Patch by Arnon Yaari.
|
||||
- Fix #501: Imported test generators are misrecognized as simple test
|
||||
functions
|
||||
Patch by John Szakmeister.
|
||||
- Added a test for issue #501
|
||||
Patch by Michael Killough.
|
||||
- Use SkipTest from unittest2, if available, for better integration with
|
||||
testtools
|
||||
Patch by Ian Wienand.
|
||||
- Fix #759: Test failures with Python 3.4
|
||||
Patch by Barry Warsaw.
|
||||
- Add a note about executable files in the usage, and how to workaround it
|
||||
Patch by Michael Dunn.
|
||||
- Fix #743: fix an incorrect regex in writing_tests.rst
|
||||
Patch by Anne Moroney.
|
||||
- Fix #690: Don't traceback when coverage reports fail.
|
||||
Patch by John Szakmeister.
|
||||
- Display the report summary and stack traces even if Ctrl-C was pressed
|
||||
during the test run.
|
||||
Patch by Kevin Qiu.
|
||||
- Fix #771: attr plugin is broken when parent and child share same method
|
||||
name with different attributes
|
||||
Patch by John Szakmeister. Test case provided by Thomas Grainger.
|
||||
- Fix #728: attrib plugin rejects any staticmethod
|
||||
Patch by John Szakmesiter. Test case provided by Thomas Kluyver.
|
||||
- Fix the plugin testing example.
|
||||
Patch by Charlie Dominio.
|
||||
- Instruct coverage instance to cover requested packages only.
|
||||
|
||||
1.3.0
|
||||
|
||||
- Fix #556: fix selecting specific tests in the setuptools command.
|
||||
Patch by Andrey Golovizin.
|
||||
- Fixed timed decorator to return the result of the wrapped function.
|
||||
Patch by Praful Mathur.
|
||||
- Fixed #513: exception in test generator leads to a TypeError.
|
||||
Patch by Dmitry Shachnev.
|
||||
- Fixed #535: nose.importer causes bizarre import errors if sys.path includes
|
||||
symlinks.
|
||||
Patch by Antoine Pitrou.
|
||||
- Added support for Python 3.3.
|
||||
Patch by John Szakmeister and Bradley Froehle.
|
||||
- Added the ability to skip generating .pyc files with --no-byte-complie.
|
||||
Patch by John Szakmeister.
|
||||
- Suppress tracebacks caused by configuration errors (#401).
|
||||
Patch by Andrea Corbellini.
|
||||
- Fixed doctest failures under Python 3 (#519).
|
||||
Patch by John Szakmeister.
|
||||
- Fixed test_address's checking for builtins to work with Python 2 and 3.
|
||||
Patch by Joe Mathes and John Szakmeister.
|
||||
- Fixed a bug where nose.tools was not being installed on systems without
|
||||
setuptools. (#554)
|
||||
Patch by Bradley Froehle.
|
||||
- Fixed a bug in xunit that was causing it to die ungracefully under
|
||||
Python 3. (#134)
|
||||
Patch by John Szakmeister.
|
||||
- Fixed #561: logcapture shouldn't buffer records, breaks %r point-in-time
|
||||
formatting.
|
||||
Patch by Santeri Paavolainen.
|
||||
- Taught xunit to capture stdout and stderr in the xunit report.
|
||||
Patch by John Szakmeister.
|
||||
- Repopulate nose.tools.__all__ so that the autodocs generate correctly.
|
||||
Patch by Taavi Burns.
|
||||
- Fixed a bug where nose was failing to parse the NOSE_COVER_PACKAGE
|
||||
environment variable correctly. (#109)
|
||||
Patch by Churkin Oleg.
|
||||
- Taught nose to lookup it's usage text according to PEP-302.
|
||||
Patch by Bradely Froehle.
|
||||
- Fixed an ugly traceback when a test class was imported from another module,
|
||||
but was missing a method. (#595)
|
||||
Patch by Michael Williamson.
|
||||
- Fix formatFailure expection if missing tb in exc_info. (#603)
|
||||
Patch by Sascha Peilicke.
|
||||
- Taught the test suite to skip coverage tests if the coverage module is not
|
||||
available. (#597)
|
||||
Patch by Dmitry Shachnev.
|
||||
- Fix #135: ResultProxy._prepareErr mangles error output in some cases.
|
||||
Patch by Arnon Yaari.
|
||||
- Updated plugin documentation to fix numerous typos and incorrect names.
|
||||
Patch by Arnon Yaari.
|
||||
- Added the ability to run nose as a module.
|
||||
Patch by Stefano Rivera.
|
||||
- Fix installing Nose under Windows with Python 3.3.
|
||||
Patch by John Szakmeister.
|
||||
- Added documentation for --processes=0 and the default value of
|
||||
--process-timeout.
|
||||
Patch by Takafumi Arakaki.
|
||||
- Fixed broken references to non-existent documentation.
|
||||
Patch by Dmitry Shachnev.
|
||||
- Fix --cover-min-percentage with --cover-branches. (#626)
|
||||
Patch by B. W. Baugh.
|
||||
- Fix --cover-min-percentage with single packages.
|
||||
Patch by John Szakmeister.
|
||||
- Fixed reference to PEP 8 to use Sphinx construct for better linking.
|
||||
Patch by Mahhtijs van der Vleuten.
|
||||
- Fixed a reference to --cover-packages to use the correct option name.
|
||||
Patch by Wesley Baugh.
|
||||
- Updated Nose to avoid using the deprecated compiler module when possible.
|
||||
Patch by Kim Scheilbel.
|
||||
- Updated docstrings of formatFailure() and formatError().
|
||||
Patch by Daniel Abel.
|
||||
- Several man page fixes for better formatting.
|
||||
Patches by Dmitry Shachnev.
|
||||
- Fixed a bug causing Nose to crash in directories that end in '.py'. (#612)
|
||||
Patch by Arnon Yaari.
|
||||
- Fixed a traceback when a test raises SystemExit and has captured
|
||||
output. (#526)
|
||||
Patch by Arnon Yaari.
|
||||
- Fixed ImportError running nosetests on namespace package in a subdirectory
|
||||
on Windows. (#19)
|
||||
Patch by Arnon Yaari.
|
||||
|
||||
1.2.1
|
||||
|
||||
- Correct nose.__version__ (#549). Thanks to Chris Withers for the bug report.
|
||||
|
||||
1.2.0
|
||||
|
||||
- Fixed issue where plugins included with `addplugins` keyword could
|
||||
be overridden by built-in plugins (or third-party plugins registered
|
||||
with setuptools) of the same name (#466).
|
||||
Patch by Brendan McCollam
|
||||
- Adds :option:`--cover-xml` and :option:`--cover-xml-file` (#311).
|
||||
Patch by Timothée Peignier.
|
||||
- Adds support for :option:`--cover-branches` (related to #370).
|
||||
Patch by Timothée Peignier.
|
||||
- Fixed Unicode issue on Python 3.1 with coverage (#442)
|
||||
- fixed class level fixture handling in multiprocessing plugin
|
||||
- Clue in the ``unittest`` module so it no longer prints traceback frames for
|
||||
our clones of their simple assertion helpers (#453). Patch by Erik Rose.
|
||||
- Stop using the ``assert`` statement in ``ok_`` and ``eq_`` so they work under
|
||||
``python -O`` (#504). Patch by Erik Rose.
|
||||
- Add loglevel option to logcapture plugin (#493). Patch by Arach Tchoupani.
|
||||
- Add doctest options flag (#7 from google code tracker). Patch by Michael
|
||||
Forbes.
|
||||
- Add support for using 2to3 with the nosetests setuptools command. Patch by
|
||||
Andrey Golovizin.
|
||||
- Add --cover-min-percentage flag to force test runs without sufficient
|
||||
coverage to fail (#540). Patch by Domen Kožar.
|
||||
- Add travis-ci configuraion (#545). Patch by Domen Kožar.
|
||||
- Call reactor.stop from twisted thread (#301). Patch by Adi Roiban.
|
||||
|
||||
|
||||
1.1.2
|
||||
|
||||
- Fixed regression where the .coverage file was not saved (#439).
|
||||
Patch by Timothée Peignier.
|
||||
|
||||
1.1.1
|
||||
|
||||
- Fixed missing nose.sphinx module in source distribution (#436).
|
||||
|
||||
1.1.0
|
||||
|
||||
- Revised multiprocessing implementation so that it works for test generators
|
||||
(#399). Thanks to Rosen Diankov for the patch.
|
||||
- More fixes to multiprocessing implemented by Buck Golemon and Gary Donovan
|
||||
(also part of #399).
|
||||
- Lots of improvements to the attrib plugin by Bobby Impollonia (#412, #411,
|
||||
#324 and #381)
|
||||
- Code coverage plugin now uses native HTML generation when coverage 3 is
|
||||
installed (#264). Thanks to Timothée Peignier for the patch.
|
||||
- Xunit plugin now shows test run time in fractions of a second (#317)
|
||||
- @attr (from nose.plugins.attrib) can now be used as a class decorator (#292)
|
||||
- Fixes Xunit plugin to handle non-UTF8 characters (#395)
|
||||
- Fixes Xunit plugin for reporting generator tests (#369)
|
||||
- Fixed problems with SkipTest in Python 3.2 (#389)
|
||||
- Fixed bug in doctest plugin under python 3. Thanks to Thomas Kluyver
|
||||
for the patch. (#391)
|
||||
- Fixes mishandling of custom exceptions during failures (#405)
|
||||
- Fixed subtle bug in :option:`--first-package-wins` that made it
|
||||
unpredictable (#293)
|
||||
- Fixes case where teardown_class() was called more than once (#408). Thanks
|
||||
to Heng Liu for the patch.
|
||||
- Fixes coverage module names -- 'cal' used to also match calendar which was a
|
||||
bug (#433)
|
||||
- Fixes capture plugin when exception message contains non-ascii chars (#402)
|
||||
- Fixed bug in tests for twisted tools. Thanks to Thomas Kluyver
|
||||
for the patch.
|
||||
- Makes :option:`--plugins` more succinct when there are no options (#235)
|
||||
|
||||
1.0.0
|
||||
|
||||
- Made nose compatible with python 3. **Huge** thanks to Alex "foogod"
|
||||
Stewart!
|
||||
|
||||
0.11.4
|
||||
|
||||
- Made nose compatible with Python 2.7.
|
||||
|
||||
0.11.3
|
||||
|
||||
- Fixed default plugin manager's use of plugin overriding. Thanks to
|
||||
rob.daylife for the bug report and patch. (#323).
|
||||
|
||||
0.11.2
|
||||
|
||||
- Changed plugin loading so that external plugins loaded via extension
|
||||
points can override builtin plugins with the same name.
|
||||
- Updated multiprocess plugin and nose's packaging to allow multiprocess
|
||||
plugin to work on Windows (#265).
|
||||
- Fixed bug in xunit plugin's interaction with suites and errors in
|
||||
module-level setup. Thanks to Mark McCague for the bug report (#279).
|
||||
- Fixed bug in nose.loader.TestLoader that allowed Test classes that raise
|
||||
exceptions in __init__ to crash the test run (#269).
|
||||
- Fixed bugs in nose's test suite that caused spurious failures on Windows.
|
||||
- Fixed bug in twisted tools: delayed calls were not shut down on
|
||||
reactor stop. Thanks to abbeyj for the patch (#278).
|
||||
- Fixed bug where root log handlers were not cleared. For example, this was
|
||||
emitting unwanted messages when testing Google App Engine websites.
|
||||
- Fixed bug in test names output by xunit plugin. Thanks to Philip
|
||||
Jenvey for the bug report and patch (#280).
|
||||
- Fixed bug in profile plugin that caused stats to fail to print under Python
|
||||
2.5 and later. Thanks to djs at n-cube dot org for the bug report (#285).
|
||||
- Improved logcapture filtering, with default setting to filter out log
|
||||
messages from nose itself. Thanks to gfxmonk for the patch (#277).
|
||||
- The xunit plugin now tags skipped tests with a <skipped> testcase tag, and
|
||||
prevents the XML from containing invalid control characters.
|
||||
- Updated nose to be compatible with python 2.7 (#305).
|
||||
- Updated loading of usage document to allow nose to run from within
|
||||
an egg archive (#288).
|
||||
- Fixed IronPython checks to make nose compatible with more versions
|
||||
of IronPython. Thanks to Kevin Mitchell for the patch (#316).
|
||||
|
||||
0.11.1
|
||||
|
||||
- Fixed bug in xunit plugin xml escaping. Thanks to Nat Williams for the bug
|
||||
|
@ -12,6 +332,28 @@
|
|||
|
||||
0.11
|
||||
|
||||
- **All new documentation!** nose's documentation is now generated by
|
||||
Sphinx. And thanks to Pam Zerbinos, it is much better organized and easier
|
||||
to use and read.
|
||||
- Two new core commandline options can help with testing namespace
|
||||
packages. :option:`--first-package-wins` is useful when you want to test one
|
||||
part of a namespace package that uses another part; in previous versions of
|
||||
nose, the other part of the namespace package would be evicted from
|
||||
sys.modules when the 2nd loaded. :option:`--traverse-namespace` is useful if
|
||||
you want nose to discover tests across entries in a package's
|
||||
__path__. (This was formerly the default behavior).
|
||||
- To make it easier to use custom plugins without needing setuptools,
|
||||
:func:`nose.core.main` and :func:`nose.core.run` now support an
|
||||
:doc:`addplugins <doc_tests/test_addplugins/test_addplugins>` keyword
|
||||
argument that takes a list of additional plugins to make available. **Note**
|
||||
that adding a plugin to this list **does not** activate or enable the
|
||||
plugin, only makes it available to be enabled via command-line or
|
||||
config file settings.
|
||||
- Thanks to Kevin Mitchell, nose is now more compatible with
|
||||
IronPython. IronPython is still not fully supported, but it should work. If
|
||||
you'd like to improve nose's support for IronPython further, please join the
|
||||
nose developer's list and volunteer to become the IronPython maintainer for
|
||||
nose!
|
||||
- Added multiprocess plugin that allows tests to be run in parallel
|
||||
across multiple processes.
|
||||
- Added logcapture plugin that captures logging messages and prints them with
|
||||
|
|
3
pythonPackages/nose/MANIFEST.in
Executable file → Normal file
3
pythonPackages/nose/MANIFEST.in
Executable file → Normal file
|
@ -6,7 +6,10 @@ include lgpl.txt
|
|||
include nosetests.1
|
||||
include install-rpm.sh
|
||||
include bin/nosetests
|
||||
include distribute_setup.py
|
||||
include selftest.py
|
||||
include setup3lib.py
|
||||
include patch.py
|
||||
include nose/usage.txt
|
||||
graft doc
|
||||
graft examples
|
||||
|
|
19
pythonPackages/nose/NEWS
Executable file → Normal file
19
pythonPackages/nose/NEWS
Executable file → Normal file
|
@ -1,7 +1,14 @@
|
|||
0.10.3
|
||||
------
|
||||
1.3.5
|
||||
-----
|
||||
|
||||
nose version 0.10.3 fixes a serious bug found in 0.10.2's nosetests
|
||||
setuptools command, and updates the coverage plugin to be more
|
||||
friendly to other plugins that trigger imports in begin(). Thanks to
|
||||
Philip Jenvey and Ned Batchelder for reporting these issues.
|
||||
1.3.5 fixes several minor issues, including the gathering of tests when using
|
||||
package notation, using the coverage plugin with multiprocessing, and several
|
||||
others. See the CHANGELOG for more details.
|
||||
|
||||
Also note that nose 1.x is in maintenance mode. We will not be
|
||||
looking to add any features, and you should seriously consider
|
||||
looking at nose2 as the way forward.
|
||||
|
||||
If you're interested in the future of nose, please take a look at the
|
||||
nose2 project on github (https://github.com/nose-devs/nose2) or pypi
|
||||
(http://pypi.python.org/pypi/nose2/0.5.0).
|
||||
|
|
16
pythonPackages/nose/PKG-INFO
Executable file → Normal file
16
pythonPackages/nose/PKG-INFO
Executable file → Normal file
|
@ -1,12 +1,11 @@
|
|||
Metadata-Version: 1.0
|
||||
Metadata-Version: 1.1
|
||||
Name: nose
|
||||
Version: 0.11.1
|
||||
Version: 1.3.7
|
||||
Summary: nose extends unittest to make testing easier
|
||||
Home-page: http://somethingaboutorange.com/mrl/projects/nose/
|
||||
Home-page: http://readthedocs.org/docs/nose/
|
||||
Author: Jason Pellerin
|
||||
Author-email: jpellerin+nose@gmail.com
|
||||
License: GNU LGPL
|
||||
Download-URL: http://somethingaboutorange.com/mrl/projects/nose/nose-0.11.1.tar.gz
|
||||
Description: nose extends the test loading and running features of unittest, making
|
||||
it easier to write, find and run tests.
|
||||
|
||||
|
@ -21,18 +20,19 @@ Description: nose extends the test loading and running features of unittest, mak
|
|||
coverage and profiling, flexible attribute-based test selection,
|
||||
output capture and more. More information about writing plugins may be
|
||||
found on in the nose API documentation, here:
|
||||
http://somethingaboutorange.com/mrl/projects/nose/
|
||||
http://readthedocs.org/docs/nose/
|
||||
|
||||
If you have recently reported a bug marked as fixed, or have a craving for
|
||||
the very latest, you may want the unstable development version instead:
|
||||
http://bitbucket.org/jpellerin/nose/get/tip.gz#egg=nose-dev
|
||||
the very latest, you may want the development version instead:
|
||||
https://github.com/nose-devs/nose/tarball/master#egg=nose-dev
|
||||
|
||||
Keywords: test unittest doctest automatic discovery
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 4 - Beta
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
|
||||
Classifier: Natural Language :: English
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Topic :: Software Development :: Testing
|
||||
|
|
110
pythonPackages/nose/README.txt
Executable file → Normal file
110
pythonPackages/nose/README.txt
Executable file → Normal file
|
@ -16,6 +16,11 @@ removed:
|
|||
verbosity=3
|
||||
with-doctest=1
|
||||
|
||||
There is also possiblity to disable configuration files loading (might
|
||||
be useful when runnig i.e. tox and you don't want your global nose
|
||||
config file to be used by tox). In order to ignore those configuration
|
||||
files simply set an environment variable "NOSE_IGNORE_CONFIG_FILES".
|
||||
|
||||
There are several other ways to use the nose test runner besides the
|
||||
*nosetests* script. You may use nose in a test script:
|
||||
|
||||
|
@ -61,6 +66,11 @@ may use the assert keyword or raise AssertionErrors to indicate test
|
|||
failure. TestCase subclasses may do the same or use the various
|
||||
TestCase methods available.
|
||||
|
||||
**It is important to note that the default behavior of nose is to not
|
||||
include tests from files which are executable.** To include tests
|
||||
from such files, remove their executable bit or use the --exe flag
|
||||
(see 'Options' section below).
|
||||
|
||||
|
||||
Selecting Tests
|
||||
---------------
|
||||
|
@ -104,18 +114,20 @@ Configuration
|
|||
-------------
|
||||
|
||||
In addition to passing command-line options, you may also put
|
||||
configuration options in a .noserc or nose.cfg file in your home
|
||||
directory. These are standard .ini-style config files. Put your
|
||||
nosetests configuration in a [nosetests] section. Options are the same
|
||||
as on the command line, with the -- prefix removed. For options that
|
||||
are simple switches, you must supply a value:
|
||||
configuration options in your project's *setup.cfg* file, or a .noserc
|
||||
or nose.cfg file in your home directory. In any of these standard ini-
|
||||
style config files, you put your nosetests configuration in a
|
||||
"[nosetests]" section. Options are the same as on the command line,
|
||||
with the -- prefix removed. For options that are simple switches, you
|
||||
must supply a value:
|
||||
|
||||
[nosetests]
|
||||
verbosity=3
|
||||
with-doctest=1
|
||||
|
||||
All configuration files that are found will be loaded and their
|
||||
options combined.
|
||||
options combined. You can override the standard config file loading
|
||||
with the "-c" option.
|
||||
|
||||
|
||||
Using Plugins
|
||||
|
@ -139,7 +151,7 @@ plugins keyword argument.
|
|||
0.9 plugins
|
||||
-----------
|
||||
|
||||
nose 0.11 can use SOME plugins that were written for nose 0.9. The
|
||||
nose 1.0 can use SOME plugins that were written for nose 0.9. The
|
||||
default plugin manager inserts a compatibility wrapper around 0.9
|
||||
plugins that adapts the changed plugin api calls. However, plugins
|
||||
that access nose internals are likely to fail, especially if they
|
||||
|
@ -151,10 +163,10 @@ plugin is trying to find out if the test is an instance of a class
|
|||
that no longer exists.
|
||||
|
||||
|
||||
0.10 plugins
|
||||
------------
|
||||
0.10 and 0.11 plugins
|
||||
---------------------
|
||||
|
||||
All plugins written for nose 0.10 should work with nose 0.11.
|
||||
All plugins written for nose 0.10 and 0.11 should work with nose 1.0.
|
||||
|
||||
|
||||
Options
|
||||
|
@ -193,6 +205,14 @@ Options
|
|||
in place of the current working directory, which is the default.
|
||||
Others will be added to the list of tests to execute. [NOSE_WHERE]
|
||||
|
||||
--py3where=PY3WHERE
|
||||
|
||||
Look for tests in this directory under Python 3.x. Functions the
|
||||
same as 'where', but only applies if running under Python 3.x or
|
||||
above. Note that, if present under 3.x, this option completely
|
||||
replaces any directories specified with 'where', so the 'where'
|
||||
option becomes ineffective. [NOSE_PY3WHERE]
|
||||
|
||||
-m=REGEX, --match=REGEX, --testmatch=REGEX
|
||||
|
||||
Files, directories, function names, and class names that match this
|
||||
|
@ -221,6 +241,13 @@ Options
|
|||
Load logging config from this file -- bypasses all other logging
|
||||
config settings.
|
||||
|
||||
-I=REGEX, --ignore-files=REGEX
|
||||
|
||||
Completely ignore any file that matches this regular expression.
|
||||
Takes precedence over any other settings or plugins. Specifying
|
||||
this option will replace the default setting. Specify this option
|
||||
multiple times to add more regular expressions [NOSE_IGNORE_FILES]
|
||||
|
||||
-e=REGEX, --exclude=REGEX
|
||||
|
||||
Don't run tests that match regular expression [NOSE_EXCLUDE]
|
||||
|
@ -255,12 +282,17 @@ Options
|
|||
|
||||
Traverse through all path entries of a namespace package
|
||||
|
||||
--first-package-wins=DEFAULT, --first-pkg-wins=DEFAULT, --1st-pkg-wins=DEFAULT
|
||||
--first-package-wins, --first-pkg-wins, --1st-pkg-wins
|
||||
|
||||
nose's importer will normally evict a package from sys.modules if
|
||||
it sees a package with the same name in a different location. Set
|
||||
this option to disable that behavior.
|
||||
|
||||
--no-byte-compile
|
||||
|
||||
Prevent nose from byte-compiling the source into .pyc files while
|
||||
nose is scanning for and running tests.
|
||||
|
||||
-a=ATTR, --attr=ATTR
|
||||
|
||||
Run only tests that have attributes specified by ATTR [NOSE_ATTR]
|
||||
|
@ -277,7 +309,7 @@ Options
|
|||
|
||||
--nologcapture
|
||||
|
||||
Disable logging capture plugin. Logging configurtion will be left
|
||||
Disable logging capture plugin. Logging configuration will be left
|
||||
intact. [NOSE_NOLOGCAPTURE]
|
||||
|
||||
--logging-format=FORMAT
|
||||
|
@ -297,12 +329,18 @@ Options
|
|||
filter out needless output. Example: filter=foo will capture
|
||||
statements issued ONLY to foo or foo.what.ever.sub but not foobar
|
||||
or other logger. Specify multiple loggers with comma:
|
||||
filter=foo,bar,baz. [NOSE_LOGFILTER]
|
||||
filter=foo,bar,baz. If any logger name is prefixed with a minus, eg
|
||||
filter=-foo, it will be excluded rather than included. Default:
|
||||
exclude logging messages from nose itself (-nose). [NOSE_LOGFILTER]
|
||||
|
||||
--logging-clear-handlers
|
||||
|
||||
Clear all other logging handlers
|
||||
|
||||
--logging-level=DEFAULT
|
||||
|
||||
Set the log level to capture
|
||||
|
||||
--with-coverage
|
||||
|
||||
Enable plugin Coverage: Activate a coverage report using Ned
|
||||
|
@ -320,6 +358,11 @@ Options
|
|||
|
||||
Include test modules in coverage report [NOSE_COVER_TESTS]
|
||||
|
||||
--cover-min-percentage=DEFAULT
|
||||
|
||||
Minimum percentage of coverage for tests to pass
|
||||
[NOSE_COVER_MIN_PERCENTAGE]
|
||||
|
||||
--cover-inclusive
|
||||
|
||||
Include all python files under working directory in coverage
|
||||
|
@ -334,14 +377,30 @@ Options
|
|||
|
||||
Produce HTML coverage information in dir
|
||||
|
||||
--cover-branches
|
||||
|
||||
Include branch coverage in coverage report [NOSE_COVER_BRANCHES]
|
||||
|
||||
--cover-xml
|
||||
|
||||
Produce XML coverage information
|
||||
|
||||
--cover-xml-file=FILE
|
||||
|
||||
Produce XML coverage information in file
|
||||
|
||||
--pdb
|
||||
|
||||
Drop into debugger on errors
|
||||
Drop into debugger on failures or errors
|
||||
|
||||
--pdb-failures
|
||||
|
||||
Drop into debugger on failures
|
||||
|
||||
--pdb-errors
|
||||
|
||||
Drop into debugger on errors
|
||||
|
||||
--no-deprecated
|
||||
|
||||
Disable special handling of DeprecatedTest exceptions.
|
||||
|
@ -374,6 +433,11 @@ Options
|
|||
Find fixtures for a doctest file in module with this name appended
|
||||
to the base name of the doctest file
|
||||
|
||||
--doctest-options=OPTIONS
|
||||
|
||||
Specify options to pass to doctest. Eg.
|
||||
'+ELLIPSIS,+NORMALIZE_WHITESPACE'
|
||||
|
||||
--with-isolation
|
||||
|
||||
Enable plugin IsolationPlugin: Activate the isolation plugin to
|
||||
|
@ -429,12 +493,21 @@ Options
|
|||
|
||||
Spread test run among this many processes. Set a number equal to
|
||||
the number of processors or cores in your machine for best results.
|
||||
[NOSE_PROCESSES]
|
||||
Pass a negative number to have the number of processes
|
||||
automatically set to the number of cores. Passing 0 means to
|
||||
disable parallel testing. Default is 0 unless NOSE_PROCESSES is
|
||||
set. [NOSE_PROCESSES]
|
||||
|
||||
--process-timeout=SECONDS
|
||||
|
||||
Set timeout for return of results from each test runner process.
|
||||
[NOSE_PROCESS_TIMEOUT]
|
||||
Default is 10. [NOSE_PROCESS_TIMEOUT]
|
||||
|
||||
--process-restartworker
|
||||
|
||||
If set, will restart each worker process once their tests are done,
|
||||
this helps control memory leaks from killing the system.
|
||||
[NOSE_PROCESS_RESTARTWORKER]
|
||||
|
||||
--with-xunit
|
||||
|
||||
|
@ -446,6 +519,11 @@ Options
|
|||
Path to xml file to store the xunit report in. Default is
|
||||
nosetests.xml in the working directory [NOSE_XUNIT_FILE]
|
||||
|
||||
--xunit-testsuite-name=PACKAGE
|
||||
|
||||
Name of the testsuite in the xunit xml, generated by plugin.
|
||||
Default test suite name is nosetests.
|
||||
|
||||
--all-modules
|
||||
|
||||
Enable plugin AllModules: Collect tests from all python modules.
|
||||
|
|
546
pythonPackages/nose/distribute_setup.py
Normal file
546
pythonPackages/nose/distribute_setup.py
Normal file
|
@ -0,0 +1,546 @@
|
|||
#!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 shutil
|
||||
import sys
|
||||
import time
|
||||
import fnmatch
|
||||
import tempfile
|
||||
import tarfile
|
||||
import optparse
|
||||
|
||||
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.35"
|
||||
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, install_args=()):
|
||||
# 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', *install_args):
|
||||
log.warn('Something went wrong during the installation.')
|
||||
log.warn('See the error message above.')
|
||||
# exitcode will be 2
|
||||
return 2
|
||||
finally:
|
||||
os.chdir(old_wd)
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
|
||||
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)
|
||||
shutil.rmtree(tmpdir)
|
||||
# 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"""
|
||||
f = open(path)
|
||||
existing_content = f.read()
|
||||
f.close()
|
||||
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):
|
||||
f = open(path)
|
||||
existing_content = f.read()
|
||||
f.close()
|
||||
return existing_content == content
|
||||
|
||||
|
||||
def _rename_path(path):
|
||||
new_name = path + '.OLD.%s' % time.time()
|
||||
log.warn('Renaming %s to %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('Moving 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)
|
||||
try:
|
||||
f = open(pkg_info, 'w')
|
||||
except EnvironmentError:
|
||||
log.warn("Don't have permissions to write %s, skipping", pkg_info)
|
||||
return
|
||||
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('Patching complete.')
|
||||
_relaunch()
|
||||
|
||||
|
||||
def _relaunch():
|
||||
log.warn('Relaunching...')
|
||||
# we have to relaunch the process
|
||||
# pip marker to avoid a relaunch bug
|
||||
_cmd1 = ['-c', 'install', '--single-version-externally-managed']
|
||||
_cmd2 = ['-c', 'install', '--record']
|
||||
if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2:
|
||||
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 _build_install_args(options):
|
||||
"""
|
||||
Build the arguments to 'python setup.py install' on the distribute package
|
||||
"""
|
||||
install_args = []
|
||||
if options.user_install:
|
||||
if sys.version_info < (2, 6):
|
||||
log.warn("--user requires Python 2.6 or later")
|
||||
raise SystemExit(1)
|
||||
install_args.append('--user')
|
||||
return install_args
|
||||
|
||||
def _parse_args():
|
||||
"""
|
||||
Parse the command line for options
|
||||
"""
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option(
|
||||
'--user', dest='user_install', action='store_true', default=False,
|
||||
help='install in user site package (requires Python 2.6 or later)')
|
||||
parser.add_option(
|
||||
'--download-base', dest='download_base', metavar="URL",
|
||||
default=DEFAULT_URL,
|
||||
help='alternative URL from where to download the distribute package')
|
||||
options, args = parser.parse_args()
|
||||
# positional arguments are ignored
|
||||
return options
|
||||
|
||||
def main(version=DEFAULT_VERSION):
|
||||
"""Install or upgrade setuptools and EasyInstall"""
|
||||
options = _parse_args()
|
||||
tarball = download_setuptools(download_base=options.download_base)
|
||||
return _install(tarball, _build_install_args(options))
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
0
pythonPackages/nose/doc/.static/nose.css
Executable file → Normal file
0
pythonPackages/nose/doc/.static/nose.css
Executable file → Normal file
0
pythonPackages/nose/doc/.templates/index.html
Executable file → Normal file
0
pythonPackages/nose/doc/.templates/index.html
Executable file → Normal file
24
pythonPackages/nose/doc/.templates/indexsidebar.html
Executable file → Normal file
24
pythonPackages/nose/doc/.templates/indexsidebar.html
Executable file → Normal file
|
@ -1,14 +1,14 @@
|
|||
<h3><a href="/mrl/projects/nose/nose-{{ release }}.tar.gz">Download</a></h3>
|
||||
<h3><a href="http://pypi.python.org/pypi/nose/">Download</a></h3>
|
||||
<ul>
|
||||
<li><a href="/mrl/projects/nose/nose-{{ release }}.tar.gz">
|
||||
Current version: {{ version }}</a>
|
||||
<li><a href="http://pypi.python.org/pypi/nose/{{ release }}">
|
||||
Current version: {{ release }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Install</h3>
|
||||
<ul>
|
||||
<li>This release:<br/>
|
||||
<tt>easy_install nose=={{ version }}</tt></li>
|
||||
<tt>easy_install nose=={{ release }}</tt></li>
|
||||
<li>Development (unstable):<br/>
|
||||
<tt>easy_install nose==dev</tt>
|
||||
</li>
|
||||
|
@ -16,11 +16,6 @@
|
|||
|
||||
<h3>Community</h3>
|
||||
<ul>
|
||||
<li><a href="http://groups.google.com/group/nose-announce">
|
||||
Announcement list</a>
|
||||
<ul><li>Sign up to receive email announcements
|
||||
of new releases</li></ul>
|
||||
</li>
|
||||
<li><a href="http://groups.google.com/group/nose-users">
|
||||
Users' discussion list</a>
|
||||
<ul><li>Talk about using nose. Get help. Give help!</li></ul>
|
||||
|
@ -33,13 +28,13 @@
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="http://code.google.com/p/python-nose/">Tracker</a></h3>
|
||||
<h3><a href="https://github.com/nose-devs/nose/">Tracker</a></h3>
|
||||
<ul><li>Report bugs, request features, wik the wiki, browse source.</li></ul>
|
||||
|
||||
<h3>Other links</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://codespeak.net/py/current/doc/test.html">py.test</a>
|
||||
<a href="http://pytest.org">pytest</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://peak.telecommunity.com/DevCenter/setuptools">
|
||||
|
@ -47,10 +42,3 @@
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Older versions</h3>
|
||||
<ul>
|
||||
<li><a href="../0.10.4/">nose 0.10, the previous major
|
||||
release.</a></li>
|
||||
<li><a href="../0.9.3/">nose 0.9.3, a very old version that you
|
||||
shouldn't use.</a></li>
|
||||
</ul>
|
||||
|
|
2
pythonPackages/nose/doc/.templates/layout.html
Executable file → Normal file
2
pythonPackages/nose/doc/.templates/layout.html
Executable file → Normal file
|
@ -6,6 +6,7 @@
|
|||
|
||||
{%- block footer %}
|
||||
{{ super() }}
|
||||
{% if not embedded %}
|
||||
<script src="http://www.google-analytics.com/urchin.js"
|
||||
type="text/javascript">
|
||||
</script>
|
||||
|
@ -13,4 +14,5 @@
|
|||
_uacct = "UA-2236166-1";
|
||||
urchinTracker();
|
||||
</script>
|
||||
{% endif %}
|
||||
{%- endblock %}
|
||||
|
|
0
pythonPackages/nose/doc/.templates/page.html
Executable file → Normal file
0
pythonPackages/nose/doc/.templates/page.html
Executable file → Normal file
4
pythonPackages/nose/doc/Makefile
Executable file → Normal file
4
pythonPackages/nose/doc/Makefile
Executable file → Normal file
|
@ -76,8 +76,8 @@ linkcheck:
|
|||
|
||||
man:
|
||||
mkdir -p .build/man ./build/doctrees
|
||||
$(SPHINXBUILD) -b manpage $(ALLSPHINXOPTS) .build/man man.rst
|
||||
cp .build/man/man.man ../nosetests.1
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) .build/man
|
||||
cp .build/man/nosetests.1 ../
|
||||
@echo
|
||||
@echo "Generated man page copied to ../nosetests.1"
|
||||
|
||||
|
|
0
pythonPackages/nose/doc/api.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/commands.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/commands.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/config.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/config.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/core.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/core.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/importer.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/importer.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/inspector.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/inspector.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/loader.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/loader.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/plugin_manager.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/plugin_manager.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/proxy.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/proxy.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/result.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/result.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/selector.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/selector.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/suite.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/suite.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/test_cases.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/test_cases.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/twistedtools.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/twistedtools.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/util.rst
Executable file → Normal file
0
pythonPackages/nose/doc/api/util.rst
Executable file → Normal file
16
pythonPackages/nose/doc/conf.py
Executable file → Normal file
16
pythonPackages/nose/doc/conf.py
Executable file → Normal file
|
@ -22,9 +22,11 @@ import sys, os
|
|||
|
||||
# need to be brutal because of easy_install's pth hacks:
|
||||
sys.path.insert(0,
|
||||
os.path.join(os.path.dirname(__file__), '..'))
|
||||
os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
from nose import __versioninfo__ as nose_version
|
||||
nose_version = tuple(str(x) for x in nose_version)
|
||||
|
||||
# General configuration
|
||||
# ---------------------
|
||||
|
@ -32,7 +34,7 @@ sys.path.insert(0, os.path.abspath('.'))
|
|||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
|
||||
'nose.sphinx.pluginopts', 'manbuilder']
|
||||
'nose.sphinx.pluginopts']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['.templates']
|
||||
|
@ -55,9 +57,9 @@ copyright = u'2009, Jason Pellerin'
|
|||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.11'
|
||||
version = '.'.join(nose_version[:2])
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.11.1'
|
||||
release = '.'.join(nose_version[:3])
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -196,6 +198,9 @@ html_theme_options = {
|
|||
'relbarlinkcolor': '#355f7c',
|
||||
}
|
||||
|
||||
# the css mostly overrides this:
|
||||
html_theme = 'default'
|
||||
|
||||
# Options for LaTeX output
|
||||
# ------------------------
|
||||
|
||||
|
@ -232,3 +237,6 @@ latex_documents = [
|
|||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'http://docs.python.org/dev': None}
|
||||
|
||||
# Man page
|
||||
man_pages = [('man', 'nosetests', 'Nicer testing for Python', 'Nose developers', 1)]
|
||||
|
|
52
pythonPackages/nose/doc/contributing.rst
Executable file → Normal file
52
pythonPackages/nose/doc/contributing.rst
Executable file → Normal file
|
@ -2,26 +2,28 @@ Contributing to nose
|
|||
====================
|
||||
|
||||
You'd like to contribute to nose? Great! Now that nose is hosted under
|
||||
`Mercurial <http://selenic.com/mercurial/>`__, contributing is even easier.
|
||||
`GitHub <http://github.com/>`__, contributing is even easier.
|
||||
|
||||
Get the code!
|
||||
-------------
|
||||
|
||||
Start by getting a local working copy of nose, either stable, from google code::
|
||||
Start by getting a local working copy of nose from github::
|
||||
|
||||
hg clone http://python-nose.googlecode.com/hg/ nose-stable
|
||||
|
||||
or unstable, from bitbucket::
|
||||
|
||||
hg clone http://bitbucket.org/jpellerin/nose/ nose-unstable
|
||||
git clone https://github.com/nose-devs/nose
|
||||
|
||||
If you plan to submit changes back to the core repository, you should set up a
|
||||
public repository of your own somewhere. `Bitbucket <http://bitbucket.org>`__
|
||||
is a good place to do that. Once you've set up your bitbucket nose repository,
|
||||
if working from **stable**, pull from your working copy of nose-stable, and push
|
||||
to bitbucket. That (with occasional merging) will be your normal practice for
|
||||
keeping your repository up to date. If you're on bitbucket and working from
|
||||
**unstable**, just **fork** http://bitbucket.org/jpellerin/nose/.
|
||||
public fork of your own somewhere (`GitHub <http://github.com/>`__ is a good
|
||||
place to do that). See GitHub's `help <http://help.github.com/>`__ for details
|
||||
on how to contribute to a Git hosted project like nose.
|
||||
|
||||
Running nose's tests
|
||||
--------------------
|
||||
|
||||
nose runs its own test suite with `tox
|
||||
<http://codespeak.net/tox/>`. You don't have to install tox to run
|
||||
nose's test suite, but you should, because tox makes it easy to run
|
||||
all tests on all supported python versions. You'll also need python
|
||||
2.4, 2.5, 2.6, 2.7, 3.1 and jython installed somewhere in your $PATH.
|
||||
|
||||
Discuss
|
||||
-------
|
||||
|
@ -33,28 +35,10 @@ low-traffic and mostly signal.
|
|||
What to work on?
|
||||
----------------
|
||||
|
||||
You can find a list of open issues at nose's `google code repository
|
||||
<http://code.google.com/p/python-nose/issues>`__. If you'd like to
|
||||
You can find a list of open issues at nose's `issue tracker
|
||||
<http://github.com/nose-devs/nose/issues>`__. If you'd like to
|
||||
work on an issue, leave a comment on the issue detailing how you plan
|
||||
to fix it, and where to find the Mercurial repository where you will
|
||||
publish your changes.
|
||||
|
||||
Actually, I want to work on the python 3.0 version
|
||||
--------------------------------------------------
|
||||
|
||||
The python 3.0 version of nose, nose3, is hosted at bitbucket. You can
|
||||
clone the repository from here::
|
||||
|
||||
hg clone http://bitbucket.org/jpellerin/nose3
|
||||
|
||||
If you plan to contribute changes back, you should fork the repository
|
||||
on bitbucket.
|
||||
|
||||
Issues affecting nose3 should likewise be reported at the bitbucket
|
||||
site, not at google code.
|
||||
|
||||
nose3 hosting may move to google code at some future date, when google
|
||||
code supports bitbucket-style forking.
|
||||
to fix it, or simply submit a pull request.
|
||||
|
||||
I have a great idea for a plugin...
|
||||
-----------------------------------
|
||||
|
|
22
pythonPackages/nose/doc/developing.rst
Executable file → Normal file
22
pythonPackages/nose/doc/developing.rst
Executable file → Normal file
|
@ -4,25 +4,15 @@ Developing with nose
|
|||
Get the code
|
||||
------------
|
||||
|
||||
The stable branch of nose is hosted at `google code
|
||||
<http://code.google.com/p/python-nose/>`__. You should clone this
|
||||
branch if you're developing a plugin or working on bug fixes for nose::
|
||||
nose is hosted at `GitHub
|
||||
<http://github.com/nose-devs/nose/>`__. You should clone this
|
||||
repository if you're developing a plugin or working on bug fixes for nose::
|
||||
|
||||
hg clone http://python-nose.googlecode.com/hg/ nose-stable
|
||||
git clone https://github.com/nose-devs/nose
|
||||
|
||||
The **unstable** branch of nose is hosted at `bitbucket
|
||||
<http://bitbucket.org/jpellerin/nose/>`__. You should **fork** this branch if
|
||||
you are developing new features for nose. Then clone your fork, and submit
|
||||
your changes as a pull request. If you just want to use unstable, you can
|
||||
clone the branch::
|
||||
You should **fork** this repository if you are developing new features for
|
||||
nose. Then submit your changes as a pull request.
|
||||
|
||||
hg clone http://bitbucket.org/jpellerin/nose/ nose-unstable
|
||||
|
||||
The **python3.0** version of nose, nose3, is also hosted at bitbucket. You can
|
||||
fork that branch to work on features or bug fixes for nose3. If you just want
|
||||
to use it, clone the branch::
|
||||
|
||||
hg clone http://bitbucket.org/jpellerin/nose3/
|
||||
|
||||
Read
|
||||
----
|
||||
|
|
0
pythonPackages/nose/doc/docstring.py
Executable file → Normal file
0
pythonPackages/nose/doc/docstring.py
Executable file → Normal file
0
pythonPackages/nose/doc/finding_tests.rst
Executable file → Normal file
0
pythonPackages/nose/doc/finding_tests.rst
Executable file → Normal file
2
pythonPackages/nose/doc/further_reading.rst
Executable file → Normal file
2
pythonPackages/nose/doc/further_reading.rst
Executable file → Normal file
|
@ -5,7 +5,6 @@ Further reading
|
|||
:maxdepth: 2
|
||||
|
||||
doc_tests/test_addplugins/test_addplugins.rst
|
||||
doc_tests/test_coverage_html/coverage_html.rst
|
||||
doc_tests/test_doctest_fixtures/doctest_fixtures.rst
|
||||
doc_tests/test_init_plugin/init_plugin.rst
|
||||
doc_tests/test_issue089/unwanted_package.rst
|
||||
|
@ -18,6 +17,7 @@ Further reading
|
|||
doc_tests/test_restricted_plugin_options/restricted_plugin_options.rst
|
||||
doc_tests/test_selector_plugin/selector_plugin.rst
|
||||
doc_tests/test_allmodules/test_allmodules.rst
|
||||
doc_tests/test_xunit_plugin/test_skips.rst
|
||||
more_info
|
||||
|
||||
Articles, etc
|
||||
|
|
4
pythonPackages/nose/doc/index.html
Executable file → Normal file
4
pythonPackages/nose/doc/index.html
Executable file → Normal file
|
@ -1,8 +1,8 @@
|
|||
<html>
|
||||
<head><title>Redirecting to nose 0.11 docs</title>
|
||||
<meta http-equiv="refresh" content="0; ./0.11.1/"/>
|
||||
<meta http-equiv="refresh" content="0; ./1.0.0/"/>
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirecting to <a href="./0.11.1/">nose 0.11 docs</a></p>
|
||||
<p>Redirecting to <a href="./1.0.0/">nose 1.0 docs</a></p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
36
pythonPackages/nose/doc/index.rst
Executable file → Normal file
36
pythonPackages/nose/doc/index.rst
Executable file → Normal file
|
@ -9,18 +9,23 @@ Installation and quick start
|
|||
*On most UNIX-like systems, you'll probably need to run these commands as root
|
||||
or using sudo.*
|
||||
|
||||
Install nose using setuptools::
|
||||
Install nose using setuptools/distribute::
|
||||
|
||||
easy_install nose
|
||||
|
||||
Or, if you don't have setuptools installed, use the download link at right to
|
||||
download the source package, and install it in the normal fashion: Ungzip and
|
||||
untar the source package, cd to the new directory, and::
|
||||
Or pip::
|
||||
|
||||
pip install nose
|
||||
|
||||
Or, if you don't have setuptools/distribute installed, use the download
|
||||
link at right to download the source package, and install it in the
|
||||
normal fashion: Ungzip and untar the source package, cd to the new
|
||||
directory, and::
|
||||
|
||||
python setup.py install
|
||||
|
||||
However, **please note** that without setuptools installed, you will not be
|
||||
able to use third-party nose plugins.
|
||||
However, **please note** that without setuptools/distribute installed,
|
||||
you will not be able to use third-party nose plugins.
|
||||
|
||||
This will install the nose libraries, as well as the :doc:`nosetests <usage>`
|
||||
script, which you can use to automatically discover and run tests.
|
||||
|
@ -46,6 +51,25 @@ For help with nosetests' many command-line options, try::
|
|||
|
||||
or visit the :doc:`usage documentation <usage>`.
|
||||
|
||||
|
||||
Python3
|
||||
=======
|
||||
|
||||
nose supports python3. Building from source on python3 requires
|
||||
`distribute <http://packages.python.org/distribute/>`_. If you don't
|
||||
have distribute installed, ``python3 setup.py install`` will install
|
||||
it via distribute's bootstrap script.
|
||||
|
||||
Additionally, if your project is using `2to3
|
||||
<http://docs.python.org/library/2to3.html>`_, ``python3 setup.py nosetests``
|
||||
command will automatically convert your sources with 2to3 and then run the
|
||||
tests with python 3.
|
||||
|
||||
.. warning ::
|
||||
|
||||
nose itself supports python 3, but many 3rd-party plugins do not!
|
||||
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
|
|
7
pythonPackages/nose/doc/man.rst
Executable file → Normal file
7
pythonPackages/nose/doc/man.rst
Executable file → Normal file
|
@ -6,13 +6,6 @@
|
|||
nicer testing for python
|
||||
------------------------
|
||||
|
||||
:Author: jpellerin+nose@gmail.com
|
||||
:Date: 2009-04-23
|
||||
:Copyright: LGPL
|
||||
:Version: 0.11
|
||||
:Manual section: 1
|
||||
:Manual group: User Commands
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
from manpage import Writer
|
||||
from sphinx.builders.text import TextBuilder
|
||||
|
||||
|
||||
class ManBuilder(TextBuilder):
|
||||
name = 'manpage'
|
||||
format = 'man'
|
||||
out_suffix = '.man'
|
||||
|
||||
def prepare_writing(self, docnames):
|
||||
self.writer = ManpageWriter(self)
|
||||
|
||||
|
||||
class ManpageWriter(Writer):
|
||||
def __init__(self, builder):
|
||||
self.builder = builder
|
||||
Writer.__init__(self)
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_builder(ManBuilder)
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load diff
0
pythonPackages/nose/doc/more_info.rst
Executable file → Normal file
0
pythonPackages/nose/doc/more_info.rst
Executable file → Normal file
105
pythonPackages/nose/doc/news.rst
Executable file → Normal file
105
pythonPackages/nose/doc/news.rst
Executable file → Normal file
|
@ -1,109 +1,4 @@
|
|||
What's new
|
||||
==========
|
||||
|
||||
0.11 is a major release of nose, featuring several new or improved plugins,
|
||||
completely revised documentation, some small, mostly backwards-compatible
|
||||
changes in behavior, and numerous bug fixes.
|
||||
|
||||
New plugins
|
||||
-----------
|
||||
|
||||
* :doc:`Multiprocess <plugins/multiprocess>`
|
||||
|
||||
The multiprocess plugin enables splitting test runs across multiple
|
||||
processes. For some test suites, this can shorten run time tremendously.
|
||||
See also: :doc:`doc_tests/test_multiprocess/multiprocess`.
|
||||
|
||||
.. warning ::
|
||||
|
||||
The multiprocess plugin is not available on Windows.
|
||||
|
||||
* :doc:`Log capture <plugins/logcapture>`
|
||||
|
||||
The log capture plugin does for logging what the
|
||||
:doc:`capture <plugins/capture>` plugin does for stdout. All :mod:`logging`
|
||||
messages produced during a failing test are appended to the error
|
||||
output printed at the end of the test run.
|
||||
|
||||
* :doc:`Xunit <plugins/xunit>`
|
||||
|
||||
The Xunit plugin produces a test result file in ant/junit xml format,
|
||||
suitable for use with `Hudson`_ and other continuous integration systems
|
||||
that consume this format.
|
||||
|
||||
* :doc:`Collect only <plugins/collect>`
|
||||
|
||||
The collect only plugin just collects all of your tests, it doesn't run
|
||||
them. Fixtures are also skipped, so collection should be quick.
|
||||
|
||||
* :doc:`Collect tests from all modules <plugins/allmodules>`
|
||||
|
||||
This plugin enables collecting tests from all python modules, not just those
|
||||
that match testMatch.
|
||||
|
||||
.. _`Hudson` : https://hudson.dev.java.net/
|
||||
|
||||
Plugin improvements
|
||||
-------------------
|
||||
|
||||
* Doctest fixtures
|
||||
|
||||
The :doc:`doctest plugin <plugins/doctests>` now supports using fixtures with
|
||||
doctest files. You can specify a module prefix (eg, "_fixture") and if a
|
||||
module exists with that prefix appended to the name of the doctest file (eg,
|
||||
"test_pillow_fixture.py" for the doctest file "test_pillow.txt"), then
|
||||
fixtures for the doctest will be extracted from the module. See
|
||||
:doc:`doc_tests/test_doctest_fixtures/doctest_fixtures` for more.
|
||||
|
||||
* Looping over failed tests
|
||||
|
||||
The :doc:`testid plugin <plugins/testid>` has been much improved. It is
|
||||
possible now to leave it on all the time: the recorded test id list will be
|
||||
refreshed appropriately if you pass non-id test names. Leaving testid on is
|
||||
recommended if you want to use the new :option:`--failed` option. This
|
||||
option will direct nose to replay the last set of failed tests, if any. It's
|
||||
very convenient for handling regressions, as it enables you to easily re-run
|
||||
just the tests you want to.
|
||||
|
||||
* HTML coverage reports
|
||||
|
||||
The :doc:`coverage plugin <plugins/cover>` can now produce html coverage
|
||||
reports. Use the :option:`--cover-html` commandline option to activate html
|
||||
reports.
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
* **All new documentation!** nose's documentation is now generated by
|
||||
Sphinx. And thanks to Pam Zerbinos, it is much better organized and easier
|
||||
to use and read.
|
||||
|
||||
* Two new core commandline options can help with testing namespace
|
||||
packages. :option:`--first-package-wins` is useful when you want to test one
|
||||
part of a namespace package that uses another part; in previous versions of
|
||||
nose, the other part of the namespace package would be evicted from
|
||||
sys.modules when the 2nd loaded. :option:`--traverse-namespace` is useful if
|
||||
you want nose to discover tests across entries in a package's
|
||||
__path__. (This was formerly the default behavior).
|
||||
|
||||
* To make it easier to use custom plugins without needing setuptools,
|
||||
:func:`nose.core.main` and :func:`nose.core.run` now support an
|
||||
:doc:`addplugins <doc_tests/test_addplugins/test_addplugins>` keyword
|
||||
argument that takes a list of additional plugins to make available. **Note**
|
||||
that adding a plugin to this list **does not** activate or enable the
|
||||
plugin, only makes it available to be enabled via command-line or
|
||||
config file settings.
|
||||
|
||||
* Thanks to Kevin Mitchell, nose is now more compatible with
|
||||
IronPython. IronPython is still not fully supported, but it should work. If
|
||||
you'd like to improve nose's support for IronPython further, please join the
|
||||
`nose developer's list`_ and volunteer to become the IronPython maintainer for
|
||||
nose!
|
||||
|
||||
Detailed changes
|
||||
----------------
|
||||
|
||||
.. include :: ../CHANGELOG
|
||||
|
||||
|
||||
.. _`nose developer's list`: http://groups.google.com/group/nose-dev
|
0
pythonPackages/nose/doc/plugins.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/allmodules.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/allmodules.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/attrib.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/attrib.rst
Executable file → Normal file
8
pythonPackages/nose/doc/plugins/builtin.rst
Executable file → Normal file
8
pythonPackages/nose/doc/plugins/builtin.rst
Executable file → Normal file
|
@ -1,6 +1,14 @@
|
|||
Batteries included: builtin nose plugins
|
||||
========================================
|
||||
|
||||
nose includes a number of builtin plugins that can make testing faster and easier.
|
||||
|
||||
.. note ::
|
||||
|
||||
nose 0.11.2 includes a change to default plugin loading. Now, a 3rd party
|
||||
plugin with *the same name* as a builtin *will be loaded instead*
|
||||
of the builtin plugin.
|
||||
|
||||
.. toctree ::
|
||||
:maxdepth: 2
|
||||
|
||||
|
|
0
pythonPackages/nose/doc/plugins/capture.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/capture.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/collect.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/collect.rst
Executable file → Normal file
10
pythonPackages/nose/doc/plugins/cover.rst
Executable file → Normal file
10
pythonPackages/nose/doc/plugins/cover.rst
Executable file → Normal file
|
@ -1,4 +1,14 @@
|
|||
Cover: code coverage
|
||||
====================
|
||||
|
||||
.. note ::
|
||||
|
||||
Newer versions of coverage contain their own nose plugin which is
|
||||
superior to the builtin plugin. It exposes more of coverage's
|
||||
options and uses coverage's native html output. Depending on the
|
||||
version of coverage installed, the included plugin may override the
|
||||
nose builtin plugin, or be available under a different name. Check
|
||||
``nosetests --help`` or ``nosetests --plugins`` to find out which
|
||||
coverage plugin is available on your system.
|
||||
|
||||
.. autoplugin :: nose.plugins.cover
|
||||
|
|
0
pythonPackages/nose/doc/plugins/debug.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/debug.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/deprecated.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/deprecated.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/doctests.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/doctests.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/documenting.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/documenting.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/errorclasses.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/errorclasses.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/failuredetail.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/failuredetail.rst
Executable file → Normal file
3
pythonPackages/nose/doc/plugins/interface.rst
Executable file → Normal file
3
pythonPackages/nose/doc/plugins/interface.rst
Executable file → Normal file
|
@ -1,3 +1,6 @@
|
|||
|
||||
.. _plugin-interface:
|
||||
|
||||
Plugin Interface
|
||||
================
|
||||
|
||||
|
|
0
pythonPackages/nose/doc/plugins/isolate.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/isolate.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/logcapture.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/logcapture.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/multiprocess.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/multiprocess.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/other.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/other.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/prof.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/prof.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/skip.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/skip.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/testid.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/testid.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/testing.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/testing.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/writing.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/writing.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/xunit.rst
Executable file → Normal file
0
pythonPackages/nose/doc/plugins/xunit.rst
Executable file → Normal file
3
pythonPackages/nose/doc/rtd-requirements.txt
Normal file
3
pythonPackages/nose/doc/rtd-requirements.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# requirements file for Read The Docs
|
||||
# http://readthedocs.org/docs/nose/
|
||||
sphinx>=1.0
|
0
pythonPackages/nose/doc/setuptools_integration.rst
Executable file → Normal file
0
pythonPackages/nose/doc/setuptools_integration.rst
Executable file → Normal file
0
pythonPackages/nose/doc/testing.rst
Executable file → Normal file
0
pythonPackages/nose/doc/testing.rst
Executable file → Normal file
4
pythonPackages/nose/doc/testing_tools.rst
Executable file → Normal file
4
pythonPackages/nose/doc/testing_tools.rst
Executable file → Normal file
|
@ -4,8 +4,8 @@ Testing tools
|
|||
The nose.tools module provides a number of testing aids that you may
|
||||
find useful, including decorators for restricting test execution time
|
||||
and testing for exceptions, and all of the same assertX methods found
|
||||
in `unittest.TestCase` (only spelled in pep08 fashion, so `assert_equal`
|
||||
rather than `assertEqual`).
|
||||
in `unittest.TestCase` (only spelled in :pep:`8#function-names`
|
||||
fashion, so `assert_equal` rather than `assertEqual`).
|
||||
|
||||
.. automodule :: nose.tools
|
||||
:members:
|
5
pythonPackages/nose/doc/usage.rst
Executable file → Normal file
5
pythonPackages/nose/doc/usage.rst
Executable file → Normal file
|
@ -14,6 +14,11 @@ standard .ini-style config files. Put your nosetests configuration in a
|
|||
verbosity=3
|
||||
with-doctest=1
|
||||
|
||||
There is also possiblity to disable configuration files loading (might be
|
||||
useful when runnig i.e. tox and you don't want your global nose config file to
|
||||
be used by tox). In order to ignore those configuration files simply set an
|
||||
environment variable ``NOSE_IGNORE_CONFIG_FILES``.
|
||||
|
||||
There are several other ways to use the nose test runner besides the
|
||||
`nosetests` script. You may use nose in a test script::
|
||||
|
||||
|
|
4
pythonPackages/nose/doc/writing_tests.rst
Executable file → Normal file
4
pythonPackages/nose/doc/writing_tests.rst
Executable file → Normal file
|
@ -3,7 +3,7 @@ Writing tests
|
|||
|
||||
As with py.test_, nose tests need not be subclasses of
|
||||
:class:`unittest.TestCase`. Any function or class that matches the configured
|
||||
testMatch regular expression (``(?:^|[\\b_\\.-])[Tt]est)`` by default -- that
|
||||
testMatch regular expression (``(?:^|[\\b_\\.-])[Tt]est`` by default -- that
|
||||
is, has test or Test at a word boundary or following a - or _) and lives in a
|
||||
module that also matches that expression will be run as a test. For the sake
|
||||
of compatibility with legacy unittest test cases, nose will also load tests
|
||||
|
@ -127,7 +127,7 @@ example from nose's selftest suite is probably the best explanation::
|
|||
def check_even(n, nn):
|
||||
assert n % 2 == 0 or nn % 2 == 0
|
||||
|
||||
This will result in four tests. nose will iterate the generator, creating a
|
||||
This will result in five tests. nose will iterate the generator, creating a
|
||||
function test case wrapper for each tuple it yields. As in the example, test
|
||||
generators must yield tuples, the first element of which must be a callable
|
||||
and the remaining elements the arguments to be passed to the callable.
|
||||
|
|
0
pythonPackages/nose/examples/attrib_plugin.py
Executable file → Normal file
0
pythonPackages/nose/examples/attrib_plugin.py
Executable file → Normal file
0
pythonPackages/nose/examples/html_plugin/htmlplug.py
Executable file → Normal file
0
pythonPackages/nose/examples/html_plugin/htmlplug.py
Executable file → Normal file
0
pythonPackages/nose/examples/html_plugin/setup.py
Executable file → Normal file
0
pythonPackages/nose/examples/html_plugin/setup.py
Executable file → Normal file
0
pythonPackages/nose/examples/plugin/plug.py
Executable file → Normal file
0
pythonPackages/nose/examples/plugin/plug.py
Executable file → Normal file
0
pythonPackages/nose/examples/plugin/setup.py
Executable file → Normal file
0
pythonPackages/nose/examples/plugin/setup.py
Executable file → Normal file
|
@ -0,0 +1,2 @@
|
|||
def test():
|
||||
pass
|
|
@ -0,0 +1,80 @@
|
|||
Using custom plugins without setuptools
|
||||
---------------------------------------
|
||||
|
||||
If you have one or more custom plugins that you'd like to use with nose, but
|
||||
can't or don't want to register that plugin as a setuptools entrypoint, you
|
||||
can use the ``addplugins`` keyword argument to :func:`nose.core.main` or
|
||||
:func:`nose.core.run` to make the plugins available.
|
||||
|
||||
To do this you would construct a launcher script for nose, something like::
|
||||
|
||||
from nose import main
|
||||
from yourpackage import YourPlugin, YourOtherPlugin
|
||||
|
||||
if __name__ == '__main__':
|
||||
nose.main(addplugins=[YourPlugin(), YourOtherPlugin()])
|
||||
|
||||
Here's an example. Say that you don't like the fact that the collect-only
|
||||
plugin outputs 'ok' for each test it finds; instead you want it to output
|
||||
'maybe.' You could modify the plugin itself, or instead, create a Maybe plugin
|
||||
that transforms the output into your desired shape.
|
||||
|
||||
Without the plugin, we get 'ok.'
|
||||
|
||||
>>> import os
|
||||
>>> support = os.path.join(os.path.dirname(__file__), 'support')
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
>>> argv = [__file__, '-v', support] # --collect-only
|
||||
>>> run(argv=argv)
|
||||
test.test ... ok
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
Without '-v', we get a dot.
|
||||
|
||||
>>> run(argv=[__file__, support])
|
||||
.
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
The plugin is simple. It captures and wraps the test result output stream and
|
||||
replaces 'ok' with 'maybe' and '.' with '?'.
|
||||
|
||||
>>> from nose.plugins.base import Plugin
|
||||
>>> class Maybe(Plugin):
|
||||
... def setOutputStream(self, stream):
|
||||
... self.stream = stream
|
||||
... return self
|
||||
... def flush(self):
|
||||
... self.stream.flush()
|
||||
... def writeln(self, out=""):
|
||||
... self.write(out + "\n")
|
||||
... def write(self, out):
|
||||
... if out == "ok\n":
|
||||
... out = "maybe\n"
|
||||
... elif out == ".":
|
||||
... out = "?"
|
||||
... self.stream.write(out)
|
||||
|
||||
To activate the plugin, we pass an instance in the addplugins list.
|
||||
|
||||
>>> run(argv=argv + ['--with-maybe'], addplugins=[Maybe()])
|
||||
test.test ... maybe
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
>>> run(argv=[__file__, support, '--with-maybe'], addplugins=[Maybe()])
|
||||
?
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
def test():
|
||||
pass
|
||||
|
||||
def test_fails():
|
||||
assert False, "This test fails"
|
|
@ -0,0 +1,2 @@
|
|||
def test():
|
||||
pass
|
|
@ -0,0 +1,67 @@
|
|||
Finding tests in all modules
|
||||
============================
|
||||
|
||||
Normally, nose only looks for tests in modules whose names match testMatch. By
|
||||
default that means modules with 'test' or 'Test' at the start of the name
|
||||
after an underscore (_) or dash (-) or other non-alphanumeric character.
|
||||
|
||||
If you want to collect tests from all modules, use the ``--all-modules``
|
||||
command line argument to activate the :doc:`allmodules plugin
|
||||
<../../plugins/allmodules>`.
|
||||
|
||||
.. Note ::
|
||||
|
||||
The function :func:`nose.plugins.plugintest.run` reformats test result
|
||||
output to remove timings, which will vary from run to run, and
|
||||
redirects the output to stdout.
|
||||
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
|
||||
..
|
||||
|
||||
>>> import os
|
||||
>>> support = os.path.join(os.path.dirname(__file__), 'support')
|
||||
>>> argv = [__file__, '-v', support]
|
||||
|
||||
The target directory contains a test module and a normal module.
|
||||
|
||||
>>> support_files = [d for d in os.listdir(support)
|
||||
... if not d.startswith('.')
|
||||
... and d.endswith('.py')]
|
||||
>>> support_files.sort()
|
||||
>>> support_files
|
||||
['mod.py', 'test.py']
|
||||
|
||||
When run without ``--all-modules``, only the test module is examined for tests.
|
||||
|
||||
>>> run(argv=argv)
|
||||
test.test ... ok
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
When ``--all-modules`` is active, both modules are examined.
|
||||
|
||||
>>> from nose.plugins.allmodules import AllModules
|
||||
>>> argv = [__file__, '-v', '--all-modules', support]
|
||||
>>> run(argv=argv, plugins=[AllModules()]) # doctest: +REPORT_NDIFF
|
||||
mod.test ... ok
|
||||
mod.test_fails ... FAIL
|
||||
test.test ... ok
|
||||
<BLANKLINE>
|
||||
======================================================================
|
||||
FAIL: mod.test_fails
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: This test fails
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 3 tests in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (failures=1)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
Doctest Fixtures
|
||||
----------------
|
||||
|
||||
Doctest files, like other tests, can be made more efficient or meaningful or
|
||||
at least easier to write by judicious use of fixtures. nose supports limited
|
||||
fixtures for use with doctest files.
|
||||
|
||||
Module-level fixtures
|
||||
=====================
|
||||
|
||||
Fixtures for a doctest file may define any or all of the following methods for
|
||||
module-level setup:
|
||||
|
||||
* setup
|
||||
* setup_module
|
||||
* setupModule
|
||||
* setUpModule
|
||||
|
||||
Each module-level setup function may optionally take a single argument, the
|
||||
fixtures module itself.
|
||||
|
||||
Example::
|
||||
|
||||
def setup_module(module):
|
||||
module.called[:] = []
|
||||
|
||||
Similarly, module-level teardown methods are available, which also optionally
|
||||
take the fixtures module as an argument:
|
||||
|
||||
* teardown
|
||||
* teardown_module
|
||||
* teardownModule
|
||||
* tearDownModule
|
||||
|
||||
Example::
|
||||
|
||||
def teardown_module(module):
|
||||
module.called[:] = []
|
||||
module.done = True
|
||||
|
||||
Module-level setup executes **before any tests are loaded** from the doctest
|
||||
file. This is the right place to raise :class:`nose.plugins.skip.SkipTest`,
|
||||
for example.
|
||||
|
||||
Test-level fixtures
|
||||
===================
|
||||
|
||||
In addition to module-level fixtures, *test*-level fixtures are
|
||||
supported. Keep in mind that in the doctest lexicon, the *test* is the *entire
|
||||
doctest file* -- not each individual example within the file. So, like the
|
||||
module-level fixtures, test-level fixtures execute *once per file*. The
|
||||
differences are that:
|
||||
|
||||
- test-level fixtures execute **after** tests have been loaded, but **before**
|
||||
any tests have executed.
|
||||
- test-level fixtures receive the doctest :class:`doctest.DocFileCase` loaded
|
||||
from the file as their one *required* argument.
|
||||
|
||||
**setup_test(test)** is called before the test is run.
|
||||
|
||||
Example::
|
||||
|
||||
def setup_test(test):
|
||||
called.append(test)
|
||||
test.globs['count'] = len(called)
|
||||
setup_test.__test__ = False
|
||||
|
||||
**teardown_test(test)** is alled after the test, unless setup raised an
|
||||
uncaught exception. The argument is the :class:`doctest.DocFileCase` object,
|
||||
*not* a unittest.TestCase.
|
||||
|
||||
Example::
|
||||
|
||||
def teardown_test(test):
|
||||
pass
|
||||
teardown_test.__test__ = False
|
||||
|
||||
Bottom line: setup_test, teardown_test have access to the *doctest test*,
|
||||
while setup, setup_module, etc have access to the *fixture*
|
||||
module. setup_module runs before tests are loaded, setup_test after.
|
||||
|
||||
.. note ::
|
||||
|
||||
As in the examples, it's a good idea to tag your setup_test/teardown_test
|
||||
functions with ``__test__ = False`` to avoid them being collected as tests.
|
||||
|
||||
Lastly, the fixtures for a doctest file may supply a **globs(globs)**
|
||||
function. The dict returned by this function will be passed to the doctest
|
||||
runner as the globals available to the test. You can use this, for example, to
|
||||
easily inject a module's globals into a doctest that has been moved from the
|
||||
module to a separate file.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
This doctest has some simple fixtures:
|
||||
|
||||
.. include :: doctest_fixtures_fixtures.py
|
||||
:literal:
|
||||
|
||||
The ``globs`` defined in the fixtures make the variable ``something``
|
||||
available in all examples.
|
||||
|
||||
>>> something
|
||||
'Something?'
|
||||
|
||||
The ``count`` variable is injected by the test-level fixture.
|
||||
|
||||
>>> count
|
||||
1
|
||||
|
||||
.. warning ::
|
||||
|
||||
This whole file is one doctest test. setup_test doesn't do what you think!
|
||||
It exists to give you access to the test case and examples, but it runs
|
||||
*once*, before all of them, not before each.
|
||||
|
||||
>>> count
|
||||
1
|
||||
|
||||
Thus, ``count`` stays 1 throughout the test, no matter how many examples it
|
||||
includes.
|
|
@ -0,0 +1,17 @@
|
|||
called = []
|
||||
|
||||
def globs(globs):
|
||||
globs['something'] = 'Something?'
|
||||
return globs
|
||||
|
||||
def setup_module(module):
|
||||
module.called[:] = []
|
||||
|
||||
def setup_test(test):
|
||||
called.append(test)
|
||||
test.globs['count'] = len(called)
|
||||
setup_test.__test__ = False
|
||||
|
||||
def teardown_test(test):
|
||||
pass
|
||||
teardown_test.__test__ = False
|
|
@ -0,0 +1,3 @@
|
|||
[DEFAULT]
|
||||
can_frobnicate = 1
|
||||
likes_cheese = 0
|
|
@ -0,0 +1,166 @@
|
|||
Running Initialization Code Before the Test Run
|
||||
-----------------------------------------------
|
||||
|
||||
Many applications, especially those using web frameworks like Pylons_
|
||||
or Django_, can't be tested without first being configured or
|
||||
otherwise initialized. Plugins can fulfill this requirement by
|
||||
implementing :meth:`begin() <nose.plugins.base.IPluginInterface.begin>`.
|
||||
|
||||
In this example, we'll use a very simple example: a widget class that
|
||||
can't be tested without a configuration.
|
||||
|
||||
Here's the widget class. It's configured at the class or instance
|
||||
level by setting the ``cfg`` attribute to a dictionary.
|
||||
|
||||
>>> class ConfigurableWidget(object):
|
||||
... cfg = None
|
||||
... def can_frobnicate(self):
|
||||
... return self.cfg.get('can_frobnicate', True)
|
||||
... def likes_cheese(self):
|
||||
... return self.cfg.get('likes_cheese', True)
|
||||
|
||||
The tests verify that the widget's methods can be called without
|
||||
raising any exceptions.
|
||||
|
||||
>>> import unittest
|
||||
>>> class TestConfigurableWidget(unittest.TestCase):
|
||||
... longMessage = False
|
||||
... def setUp(self):
|
||||
... self.widget = ConfigurableWidget()
|
||||
... def test_can_frobnicate(self):
|
||||
... """Widgets can frobnicate (or not)"""
|
||||
... self.widget.can_frobnicate()
|
||||
... def test_likes_cheese(self):
|
||||
... """Widgets might like cheese"""
|
||||
... self.widget.likes_cheese()
|
||||
... def shortDescription(self): # 2.7 compat
|
||||
... try:
|
||||
... doc = self._testMethodDoc
|
||||
... except AttributeError:
|
||||
... # 2.4 compat
|
||||
... doc = self._TestCase__testMethodDoc
|
||||
... return doc and doc.split("\n")[0].strip() or None
|
||||
|
||||
The tests are bundled into a suite that we can pass to the test runner.
|
||||
|
||||
>>> def suite():
|
||||
... return unittest.TestSuite([
|
||||
... TestConfigurableWidget('test_can_frobnicate'),
|
||||
... TestConfigurableWidget('test_likes_cheese')])
|
||||
|
||||
When we run tests without first configuring the ConfigurableWidget,
|
||||
the tests fail.
|
||||
|
||||
.. Note ::
|
||||
|
||||
The function :func:`nose.plugins.plugintest.run` reformats test result
|
||||
output to remove timings, which will vary from run to run, and
|
||||
redirects the output to stdout.
|
||||
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
|
||||
..
|
||||
|
||||
>>> argv = [__file__, '-v']
|
||||
>>> run(argv=argv, suite=suite()) # doctest: +REPORT_NDIFF
|
||||
Widgets can frobnicate (or not) ... ERROR
|
||||
Widgets might like cheese ... ERROR
|
||||
<BLANKLINE>
|
||||
======================================================================
|
||||
ERROR: Widgets can frobnicate (or not)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: 'NoneType' object has no attribute 'get'
|
||||
<BLANKLINE>
|
||||
======================================================================
|
||||
ERROR: Widgets might like cheese
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError: 'NoneType' object has no attribute 'get'
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 2 tests in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (errors=2)
|
||||
|
||||
To configure the widget system before running tests, write a plugin
|
||||
that implements :meth:`begin() <nose.plugins.base.IPluginInterface.begin>`
|
||||
and initializes the system with a hard-coded configuration. (Later, we'll
|
||||
write a better plugin that accepts a command-line argument specifying the
|
||||
configuration file.)
|
||||
|
||||
>>> from nose.plugins import Plugin
|
||||
>>> class ConfiguringPlugin(Plugin):
|
||||
... enabled = True
|
||||
... def configure(self, options, conf):
|
||||
... pass # always on
|
||||
... def begin(self):
|
||||
... ConfigurableWidget.cfg = {}
|
||||
|
||||
Now configure and execute a new test run using the plugin, which will
|
||||
inject the hard-coded configuration.
|
||||
|
||||
>>> run(argv=argv, suite=suite(),
|
||||
... plugins=[ConfiguringPlugin()]) # doctest: +REPORT_NDIFF
|
||||
Widgets can frobnicate (or not) ... ok
|
||||
Widgets might like cheese ... ok
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 2 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
This time the tests pass, because the widget class is configured.
|
||||
|
||||
But the ConfiguringPlugin is pretty lame -- the configuration it
|
||||
installs is hard coded. A better plugin would allow the user to
|
||||
specify a configuration file on the command line:
|
||||
|
||||
>>> class BetterConfiguringPlugin(Plugin):
|
||||
... def options(self, parser, env={}):
|
||||
... parser.add_option('--widget-config', action='store',
|
||||
... dest='widget_config', default=None,
|
||||
... help='Specify path to widget config file')
|
||||
... def configure(self, options, conf):
|
||||
... if options.widget_config:
|
||||
... self.load_config(options.widget_config)
|
||||
... self.enabled = True
|
||||
... def begin(self):
|
||||
... ConfigurableWidget.cfg = self.cfg
|
||||
... def load_config(self, path):
|
||||
... from ConfigParser import ConfigParser
|
||||
... p = ConfigParser()
|
||||
... p.read([path])
|
||||
... self.cfg = dict(p.items('DEFAULT'))
|
||||
|
||||
To use the plugin, we need a config file.
|
||||
|
||||
>>> import os
|
||||
>>> cfg_path = os.path.join(os.path.dirname(__file__), 'example.cfg')
|
||||
>>> cfg_file = open(cfg_path, 'w')
|
||||
>>> bytes = cfg_file.write("""\
|
||||
... [DEFAULT]
|
||||
... can_frobnicate = 1
|
||||
... likes_cheese = 0
|
||||
... """)
|
||||
>>> cfg_file.close()
|
||||
|
||||
Now we can execute a test run using that configuration, after first
|
||||
resetting the widget system to an unconfigured state.
|
||||
|
||||
>>> ConfigurableWidget.cfg = None
|
||||
>>> argv = [__file__, '-v', '--widget-config', cfg_path]
|
||||
>>> run(argv=argv, suite=suite(),
|
||||
... plugins=[BetterConfiguringPlugin()]) # doctest: +REPORT_NDIFF
|
||||
Widgets can frobnicate (or not) ... ok
|
||||
Widgets might like cheese ... ok
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 2 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
.. _Pylons: http://pylonshq.com/
|
||||
.. _Django: http://www.djangoproject.com/
|
|
@ -0,0 +1,10 @@
|
|||
--- init_plugin.rst.orig 2010-08-31 10:36:54.000000000 -0700
|
||||
+++ init_plugin.rst 2010-08-31 10:37:30.000000000 -0700
|
||||
@@ -143,6 +143,7 @@
|
||||
... can_frobnicate = 1
|
||||
... likes_cheese = 0
|
||||
... """)
|
||||
+ 46
|
||||
|
||||
Now we can execute a test run using that configuration, after first
|
||||
resetting the widget system to an unconfigured state.
|
|
@ -0,0 +1 @@
|
|||
pass
|
|
@ -0,0 +1,3 @@
|
|||
def test_spam():
|
||||
assert True
|
||||
|
|
@ -0,0 +1 @@
|
|||
pass
|
|
@ -0,0 +1,3 @@
|
|||
def test_eggs():
|
||||
assert True
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
Excluding Unwanted Packages
|
||||
---------------------------
|
||||
|
||||
Normally, nose discovery descends into all packages. Plugins can
|
||||
change this behavior by implementing :meth:`IPluginInterface.wantDirectory()`.
|
||||
|
||||
In this example, we have a wanted package called ``wanted_package``
|
||||
and an unwanted package called ``unwanted_package``.
|
||||
|
||||
>>> import os
|
||||
>>> support = os.path.join(os.path.dirname(__file__), 'support')
|
||||
>>> support_files = [d for d in os.listdir(support)
|
||||
... if not d.startswith('.')]
|
||||
>>> support_files.sort()
|
||||
>>> support_files
|
||||
['unwanted_package', 'wanted_package']
|
||||
|
||||
When we run nose normally, tests are loaded from both packages.
|
||||
|
||||
.. Note ::
|
||||
|
||||
The function :func:`nose.plugins.plugintest.run` reformats test result
|
||||
output to remove timings, which will vary from run to run, and
|
||||
redirects the output to stdout.
|
||||
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
|
||||
..
|
||||
|
||||
>>> argv = [__file__, '-v', support]
|
||||
>>> run(argv=argv) # doctest: +REPORT_NDIFF
|
||||
unwanted_package.test_spam.test_spam ... ok
|
||||
wanted_package.test_eggs.test_eggs ... ok
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 2 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
To exclude the tests in the unwanted package, we can write a simple
|
||||
plugin that implements :meth:`IPluginInterface.wantDirectory()` and returns ``False`` if
|
||||
the basename of the directory is ``"unwanted_package"``. This will
|
||||
prevent nose from descending into the unwanted package.
|
||||
|
||||
>>> from nose.plugins import Plugin
|
||||
>>> class UnwantedPackagePlugin(Plugin):
|
||||
... # no command line arg needed to activate plugin
|
||||
... enabled = True
|
||||
... name = "unwanted-package"
|
||||
...
|
||||
... def configure(self, options, conf):
|
||||
... pass # always on
|
||||
...
|
||||
... def wantDirectory(self, dirname):
|
||||
... want = None
|
||||
... if os.path.basename(dirname) == "unwanted_package":
|
||||
... want = False
|
||||
... return want
|
||||
|
||||
In the next test run we use the plugin, and the unwanted package is
|
||||
not discovered.
|
||||
|
||||
>>> run(argv=argv,
|
||||
... plugins=[UnwantedPackagePlugin()]) # doctest: +REPORT_NDIFF
|
||||
wanted_package.test_eggs.test_eggs ... ok
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
|
@ -0,0 +1,160 @@
|
|||
nose.plugins.plugintest, os.environ and sys.argv
|
||||
------------------------------------------------
|
||||
|
||||
:class:`nose.plugins.plugintest.PluginTester` and
|
||||
:func:`nose.plugins.plugintest.run` are utilities for testing nose
|
||||
plugins. When testing plugins, it should be possible to control the
|
||||
environment seen plugins under test, and that environment should never
|
||||
be affected by ``os.environ`` or ``sys.argv``.
|
||||
|
||||
>>> import os
|
||||
>>> import sys
|
||||
>>> import unittest
|
||||
>>> import nose.config
|
||||
>>> from nose.plugins import Plugin
|
||||
>>> from nose.plugins.builtin import FailureDetail, Capture
|
||||
>>> from nose.plugins.plugintest import PluginTester
|
||||
|
||||
Our test plugin takes no command-line arguments and simply prints the
|
||||
environment it's given by nose.
|
||||
|
||||
>>> class PrintEnvPlugin(Plugin):
|
||||
... name = "print-env"
|
||||
...
|
||||
... # no command line arg needed to activate plugin
|
||||
... enabled = True
|
||||
... def configure(self, options, conf):
|
||||
... if not self.can_configure:
|
||||
... return
|
||||
... self.conf = conf
|
||||
...
|
||||
... def options(self, parser, env={}):
|
||||
... print "env:", env
|
||||
|
||||
To test the argv, we use a config class that prints the argv it's
|
||||
given by nose. We need to monkeypatch nose.config.Config, so that we
|
||||
can test the cases where that is used as the default.
|
||||
|
||||
>>> old_config = nose.config.Config
|
||||
>>> class PrintArgvConfig(old_config):
|
||||
...
|
||||
... def configure(self, argv=None, doc=None):
|
||||
... print "argv:", argv
|
||||
... old_config.configure(self, argv, doc)
|
||||
>>> nose.config.Config = PrintArgvConfig
|
||||
|
||||
The class under test, PluginTester, is designed to be used by
|
||||
subclassing.
|
||||
|
||||
>>> class Tester(PluginTester):
|
||||
... activate = "-v"
|
||||
... plugins = [PrintEnvPlugin(),
|
||||
... FailureDetail(),
|
||||
... Capture(),
|
||||
... ]
|
||||
...
|
||||
... def makeSuite(self):
|
||||
... return unittest.TestSuite(tests=[])
|
||||
|
||||
For the purposes of this test, we need a known ``os.environ`` and
|
||||
``sys.argv``.
|
||||
|
||||
>>> old_environ = os.environ
|
||||
>>> old_argv = sys.argv
|
||||
>>> os.environ = {"spam": "eggs"}
|
||||
>>> sys.argv = ["spamtests"]
|
||||
|
||||
PluginTester always uses the [nosetests, self.activate] as its argv.
|
||||
If ``env`` is not overridden, the default is an empty ``env``.
|
||||
|
||||
>>> tester = Tester()
|
||||
>>> tester.setUp()
|
||||
argv: ['nosetests', '-v']
|
||||
env: {}
|
||||
|
||||
An empty ``env`` is respected...
|
||||
|
||||
>>> class EmptyEnvTester(Tester):
|
||||
... env = {}
|
||||
>>> tester = EmptyEnvTester()
|
||||
>>> tester.setUp()
|
||||
argv: ['nosetests', '-v']
|
||||
env: {}
|
||||
|
||||
... as is a non-empty ``env``.
|
||||
|
||||
>>> class NonEmptyEnvTester(Tester):
|
||||
... env = {"foo": "bar"}
|
||||
>>> tester = NonEmptyEnvTester()
|
||||
>>> tester.setUp()
|
||||
argv: ['nosetests', '-v']
|
||||
env: {'foo': 'bar'}
|
||||
|
||||
|
||||
``nose.plugins.plugintest.run()`` should work analogously.
|
||||
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
>>> run(suite=unittest.TestSuite(tests=[]),
|
||||
... plugins=[PrintEnvPlugin()]) # doctest: +REPORT_NDIFF
|
||||
argv: ['nosetests', '-v']
|
||||
env: {}
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
>>> run(env={},
|
||||
... suite=unittest.TestSuite(tests=[]),
|
||||
... plugins=[PrintEnvPlugin()]) # doctest: +REPORT_NDIFF
|
||||
argv: ['nosetests', '-v']
|
||||
env: {}
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
>>> run(env={"foo": "bar"},
|
||||
... suite=unittest.TestSuite(tests=[]),
|
||||
... plugins=[PrintEnvPlugin()]) # doctest: +REPORT_NDIFF
|
||||
argv: ['nosetests', '-v']
|
||||
env: {'foo': 'bar'}
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
An explicit argv parameter is honoured:
|
||||
|
||||
>>> run(argv=["spam"],
|
||||
... suite=unittest.TestSuite(tests=[]),
|
||||
... plugins=[PrintEnvPlugin()]) # doctest: +REPORT_NDIFF
|
||||
argv: ['spam']
|
||||
env: {}
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
An explicit config parameter with an env is honoured:
|
||||
|
||||
>>> from nose.plugins.manager import PluginManager
|
||||
>>> manager = PluginManager(plugins=[PrintEnvPlugin()])
|
||||
>>> config = PrintArgvConfig(env={"foo": "bar"}, plugins=manager)
|
||||
>>> run(config=config,
|
||||
... suite=unittest.TestSuite(tests=[])) # doctest: +REPORT_NDIFF
|
||||
argv: ['nosetests', '-v']
|
||||
env: {'foo': 'bar'}
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
|
||||
Clean up.
|
||||
|
||||
>>> os.environ = old_environ
|
||||
>>> sys.argv = old_argv
|
||||
>>> nose.config.Config = old_config
|
|
@ -0,0 +1,149 @@
|
|||
When Plugins Fail
|
||||
-----------------
|
||||
|
||||
Plugin methods should not fail silently. When a plugin method raises
|
||||
an exception before or during the execution of a test, the exception
|
||||
will be wrapped in a :class:`nose.failure.Failure` instance and appear as a
|
||||
failing test. Exceptions raised at other times, such as in the
|
||||
preparation phase with ``prepareTestLoader`` or ``prepareTestResult``,
|
||||
or after a test executes, in ``afterTest`` will stop the entire test
|
||||
run.
|
||||
|
||||
>>> import os
|
||||
>>> import sys
|
||||
>>> from nose.plugins import Plugin
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
|
||||
Our first test plugins take no command-line arguments and raises
|
||||
AttributeError in beforeTest and afterTest.
|
||||
|
||||
>>> class EnabledPlugin(Plugin):
|
||||
... """Plugin that takes no command-line arguments"""
|
||||
...
|
||||
... enabled = True
|
||||
...
|
||||
... def configure(self, options, conf):
|
||||
... pass
|
||||
... def options(self, parser, env={}):
|
||||
... pass
|
||||
>>> class FailBeforePlugin(EnabledPlugin):
|
||||
... name = "fail-before"
|
||||
...
|
||||
... def beforeTest(self, test):
|
||||
... raise AttributeError()
|
||||
>>> class FailAfterPlugin(EnabledPlugin):
|
||||
... name = "fail-after"
|
||||
...
|
||||
... def afterTest(self, test):
|
||||
... raise AttributeError()
|
||||
|
||||
Running tests with the fail-before plugin enabled will result in all
|
||||
tests failing.
|
||||
|
||||
>>> support = os.path.join(os.path.dirname(__file__), 'support')
|
||||
>>> suitepath = os.path.join(support, 'test_spam.py')
|
||||
>>> run(argv=['nosetests', suitepath],
|
||||
... plugins=[FailBeforePlugin()])
|
||||
EE
|
||||
======================================================================
|
||||
ERROR: test_spam.test_spam
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError
|
||||
<BLANKLINE>
|
||||
======================================================================
|
||||
ERROR: test_spam.test_eggs
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (errors=2)
|
||||
|
||||
But with the fail-after plugin, the entire test run will fail.
|
||||
|
||||
>>> run(argv=['nosetests', suitepath],
|
||||
... plugins=[FailAfterPlugin()])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AttributeError
|
||||
|
||||
Likewise, since the next plugin fails in a preparatory method, outside
|
||||
of test execution, the entire test run fails when the plugin is used.
|
||||
|
||||
>>> class FailPreparationPlugin(EnabledPlugin):
|
||||
... name = "fail-prepare"
|
||||
...
|
||||
... def prepareTestLoader(self, loader):
|
||||
... raise TypeError("That loader is not my type")
|
||||
>>> run(argv=['nosetests', suitepath],
|
||||
... plugins=[FailPreparationPlugin()])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: That loader is not my type
|
||||
|
||||
|
||||
Even AttributeErrors and TypeErrors are not silently suppressed as
|
||||
they used to be for some generative plugin methods (issue152).
|
||||
|
||||
These methods caught TypeError and AttributeError and did not record
|
||||
the exception, before issue152 was fixed: .loadTestsFromDir(),
|
||||
.loadTestsFromModule(), .loadTestsFromTestCase(),
|
||||
loadTestsFromTestClass, and .makeTest(). Now, the exception is
|
||||
caught, but logged as a Failure.
|
||||
|
||||
>>> class FailLoadPlugin(EnabledPlugin):
|
||||
... name = "fail-load"
|
||||
...
|
||||
... def loadTestsFromModule(self, module):
|
||||
... # we're testing exception handling behaviour during
|
||||
... # iteration, so be a generator function, without
|
||||
... # actually yielding any tests
|
||||
... if False:
|
||||
... yield None
|
||||
... raise TypeError("bug in plugin")
|
||||
>>> run(argv=['nosetests', suitepath],
|
||||
... plugins=[FailLoadPlugin()])
|
||||
..E
|
||||
======================================================================
|
||||
ERROR: Failure: TypeError (bug in plugin)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: bug in plugin
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 3 tests in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (errors=1)
|
||||
|
||||
|
||||
Also, before issue152 was resolved, .loadTestsFromFile() and
|
||||
.loadTestsFromName() didn't catch these errors at all, so the
|
||||
following test would crash nose:
|
||||
|
||||
>>> class FailLoadFromNamePlugin(EnabledPlugin):
|
||||
... name = "fail-load-from-name"
|
||||
...
|
||||
... def loadTestsFromName(self, name, module=None, importPath=None):
|
||||
... if False:
|
||||
... yield None
|
||||
... raise TypeError("bug in plugin")
|
||||
>>> run(argv=['nosetests', suitepath],
|
||||
... plugins=[FailLoadFromNamePlugin()])
|
||||
E
|
||||
======================================================================
|
||||
ERROR: Failure: TypeError (bug in plugin)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: bug in plugin
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (errors=1)
|
|
@ -0,0 +1,5 @@
|
|||
def test_spam():
|
||||
assert True
|
||||
|
||||
def test_eggs():
|
||||
pass
|
|
@ -0,0 +1,57 @@
|
|||
Minimal plugin
|
||||
--------------
|
||||
|
||||
Plugins work as long as they implement the minimal interface required
|
||||
by nose.plugins.base. They do not have to derive from
|
||||
nose.plugins.Plugin.
|
||||
|
||||
>>> class NullPlugin(object):
|
||||
...
|
||||
... enabled = True
|
||||
... name = "null"
|
||||
... score = 100
|
||||
...
|
||||
... def options(self, parser, env):
|
||||
... pass
|
||||
...
|
||||
... def configure(self, options, conf):
|
||||
... pass
|
||||
>>> import unittest
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
>>> run(suite=unittest.TestSuite(tests=[]),
|
||||
... plugins=[NullPlugin()]) # doctest: +REPORT_NDIFF
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
||||
|
||||
Plugins can derive from nose.plugins.base and do nothing except set a
|
||||
name.
|
||||
|
||||
>>> import os
|
||||
>>> from nose.plugins import Plugin
|
||||
>>> class DerivedNullPlugin(Plugin):
|
||||
...
|
||||
... name = "derived-null"
|
||||
|
||||
Enabled plugin that's otherwise empty
|
||||
|
||||
>>> class EnabledDerivedNullPlugin(Plugin):
|
||||
...
|
||||
... enabled = True
|
||||
... name = "enabled-derived-null"
|
||||
...
|
||||
... def options(self, parser, env=os.environ):
|
||||
... pass
|
||||
...
|
||||
... def configure(self, options, conf):
|
||||
... if not self.can_configure:
|
||||
... return
|
||||
... self.conf = conf
|
||||
>>> run(suite=unittest.TestSuite(tests=[]),
|
||||
... plugins=[DerivedNullPlugin(), EnabledDerivedNullPlugin()])
|
||||
... # doctest: +REPORT_NDIFF
|
||||
----------------------------------------------------------------------
|
||||
Ran 0 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK
|
|
@ -0,0 +1,26 @@
|
|||
import os
|
||||
import unittest
|
||||
from nose.plugins import Plugin
|
||||
from nose.plugins.plugintest import PluginTester
|
||||
from nose.plugins.manager import ZeroNinePlugin
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
support = os.path.join(os.path.dirname(os.path.dirname(here)), 'support')
|
||||
|
||||
|
||||
class EmptyPlugin(Plugin):
|
||||
pass
|
||||
|
||||
class TestEmptyPlugin(PluginTester, unittest.TestCase):
|
||||
activate = '--with-empty'
|
||||
plugins = [ZeroNinePlugin(EmptyPlugin())]
|
||||
suitepath = os.path.join(here, 'empty_plugin.rst')
|
||||
|
||||
def test_empty_zero_nine_does_not_crash(self):
|
||||
print self.output
|
||||
assert "'EmptyPlugin' object has no attribute 'loadTestsFromPath'" \
|
||||
not in self.output
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
Failure of Errorclasses
|
||||
-----------------------
|
||||
|
||||
Errorclasses (skips, deprecations, etc.) define whether or not they
|
||||
represent test failures.
|
||||
|
||||
>>> import os
|
||||
>>> import sys
|
||||
>>> from nose.plugins.plugintest import run_buffered as run
|
||||
>>> from nose.plugins.skip import Skip
|
||||
>>> from nose.plugins.deprecated import Deprecated
|
||||
>>> support = os.path.join(os.path.dirname(__file__), 'support')
|
||||
>>> sys.path.insert(0, support)
|
||||
>>> from errorclass_failure_plugin import Todo, TodoPlugin, \
|
||||
... NonFailureTodoPlugin
|
||||
>>> todo_test = os.path.join(support, 'errorclass_failing_test.py')
|
||||
>>> misc_test = os.path.join(support, 'errorclass_tests.py')
|
||||
|
||||
nose.plugins.errorclass.ErrorClass has an argument ``isfailure``. With a
|
||||
true isfailure, when the errorclass' exception is raised by a test,
|
||||
tracebacks are printed.
|
||||
|
||||
>>> run(argv=["nosetests", "-v", "--with-todo", todo_test],
|
||||
... plugins=[TodoPlugin()]) # doctest: +REPORT_NDIFF
|
||||
errorclass_failing_test.test_todo ... TODO: fix me
|
||||
errorclass_failing_test.test_2 ... ok
|
||||
<BLANKLINE>
|
||||
======================================================================
|
||||
TODO: errorclass_failing_test.test_todo
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
Todo: fix me
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 2 tests in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (TODO=1)
|
||||
|
||||
|
||||
Also, ``--stop`` stops the test run.
|
||||
|
||||
>>> run(argv=["nosetests", "-v", "--with-todo", "--stop", todo_test],
|
||||
... plugins=[TodoPlugin()]) # doctest: +REPORT_NDIFF
|
||||
errorclass_failing_test.test_todo ... TODO: fix me
|
||||
<BLANKLINE>
|
||||
======================================================================
|
||||
TODO: errorclass_failing_test.test_todo
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
Todo: fix me
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (TODO=1)
|
||||
|
||||
|
||||
With a false .isfailure, errorclass exceptions raised by tests are
|
||||
treated as "ignored errors." For ignored errors, tracebacks are not
|
||||
printed, and the test run does not stop.
|
||||
|
||||
>>> run(argv=["nosetests", "-v", "--with-non-failure-todo", "--stop",
|
||||
... todo_test],
|
||||
... plugins=[NonFailureTodoPlugin()]) # doctest: +REPORT_NDIFF
|
||||
errorclass_failing_test.test_todo ... TODO: fix me
|
||||
errorclass_failing_test.test_2 ... ok
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 2 tests in ...s
|
||||
<BLANKLINE>
|
||||
OK (TODO=1)
|
||||
|
||||
|
||||
Exception detail strings of errorclass errors are always printed when
|
||||
-v is in effect, regardless of whether the error is ignored. Note
|
||||
that exception detail strings may have more than one line.
|
||||
|
||||
>>> run(argv=["nosetests", "-v", "--with-todo", misc_test],
|
||||
... plugins=[TodoPlugin(), Skip(), Deprecated()])
|
||||
... # doctest: +REPORT_NDIFF
|
||||
errorclass_tests.test_todo ... TODO: fix me
|
||||
errorclass_tests.test_2 ... ok
|
||||
errorclass_tests.test_3 ... SKIP: skipety-skip
|
||||
errorclass_tests.test_4 ... SKIP
|
||||
errorclass_tests.test_5 ... DEPRECATED: spam
|
||||
eggs
|
||||
<BLANKLINE>
|
||||
spam
|
||||
errorclass_tests.test_6 ... DEPRECATED: spam
|
||||
<BLANKLINE>
|
||||
======================================================================
|
||||
TODO: errorclass_tests.test_todo
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
Todo: fix me
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 6 tests in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (DEPRECATED=2, SKIP=2, TODO=1)
|
||||
|
||||
Without -v, the exception detail strings are only displayed if the
|
||||
error is not ignored (otherwise, there's no traceback).
|
||||
|
||||
>>> run(argv=["nosetests", "--with-todo", misc_test],
|
||||
... plugins=[TodoPlugin(), Skip(), Deprecated()])
|
||||
... # doctest: +REPORT_NDIFF
|
||||
T.SSDD
|
||||
======================================================================
|
||||
TODO: errorclass_tests.test_todo
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
Todo: fix me
|
||||
<BLANKLINE>
|
||||
----------------------------------------------------------------------
|
||||
Ran 6 tests in ...s
|
||||
<BLANKLINE>
|
||||
FAILED (DEPRECATED=2, SKIP=2, TODO=1)
|
||||
|
||||
>>> sys.path.remove(support)
|
|
@ -0,0 +1,7 @@
|
|||
from errorclass_failure_plugin import Todo
|
||||
|
||||
def test_todo():
|
||||
raise Todo("fix me")
|
||||
|
||||
def test_2():
|
||||
pass
|
|
@ -0,0 +1,16 @@
|
|||
from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
|
||||
|
||||
class Todo(Exception):
|
||||
pass
|
||||
|
||||
class TodoPlugin(ErrorClassPlugin):
|
||||
|
||||
name = "todo"
|
||||
|
||||
todo = ErrorClass(Todo, label='TODO', isfailure=True)
|
||||
|
||||
class NonFailureTodoPlugin(ErrorClassPlugin):
|
||||
|
||||
name = "non-failure-todo"
|
||||
|
||||
todo = ErrorClass(Todo, label='TODO', isfailure=False)
|
|
@ -0,0 +1,20 @@
|
|||
from errorclass_failure_plugin import Todo
|
||||
from nose import SkipTest, DeprecatedTest
|
||||
|
||||
def test_todo():
|
||||
raise Todo('fix me')
|
||||
|
||||
def test_2():
|
||||
pass
|
||||
|
||||
def test_3():
|
||||
raise SkipTest('skipety-skip')
|
||||
|
||||
def test_4():
|
||||
raise SkipTest()
|
||||
|
||||
def test_5():
|
||||
raise DeprecatedTest('spam\neggs\n\nspam')
|
||||
|
||||
def test_6():
|
||||
raise DeprecatedTest('spam')
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue