__init__.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. """
  2. Writing Plugins
  3. ---------------
  4. nose supports plugins for test collection, selection, observation and
  5. reporting. There are two basic rules for plugins:
  6. * Plugin classes should subclass :class:`nose.plugins.Plugin`.
  7. * Plugins may implement any of the methods described in the class
  8. :doc:`IPluginInterface <interface>` in nose.plugins.base. Please note that
  9. this class is for documentary purposes only; plugins may not subclass
  10. IPluginInterface.
  11. Hello World
  12. ===========
  13. Here's a basic plugin. It doesn't do much so read on for more ideas or dive
  14. into the :doc:`IPluginInterface <interface>` to see all available hooks.
  15. .. code-block:: python
  16. import logging
  17. import os
  18. from nose.plugins import Plugin
  19. log = logging.getLogger('nose.plugins.helloworld')
  20. class HelloWorld(Plugin):
  21. name = 'helloworld'
  22. def options(self, parser, env=os.environ):
  23. super(HelloWorld, self).options(parser, env=env)
  24. def configure(self, options, conf):
  25. super(HelloWorld, self).configure(options, conf)
  26. if not self.enabled:
  27. return
  28. def finalize(self, result):
  29. log.info('Hello pluginized world!')
  30. Registering
  31. ===========
  32. .. Note::
  33. Important note: the following applies only to the default
  34. plugin manager. Other plugin managers may use different means to
  35. locate and load plugins.
  36. For nose to find a plugin, it must be part of a package that uses
  37. setuptools_, and the plugin must be included in the entry points defined
  38. in the setup.py for the package:
  39. .. code-block:: python
  40. setup(name='Some plugin',
  41. # ...
  42. entry_points = {
  43. 'nose.plugins.0.10': [
  44. 'someplugin = someplugin:SomePlugin'
  45. ]
  46. },
  47. # ...
  48. )
  49. Once the package is installed with install or develop, nose will be able
  50. to load the plugin.
  51. .. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
  52. Registering a plugin without setuptools
  53. =======================================
  54. It is currently possible to register a plugin programmatically by
  55. creating a custom nose runner like this :
  56. .. code-block:: python
  57. import nose
  58. from yourplugin import YourPlugin
  59. if __name__ == '__main__':
  60. nose.main(addplugins=[YourPlugin()])
  61. Defining options
  62. ================
  63. All plugins must implement the methods ``options(self, parser, env)``
  64. and ``configure(self, options, conf)``. Subclasses of nose.plugins.Plugin
  65. that want the standard options should call the superclass methods.
  66. nose uses optparse.OptionParser from the standard library to parse
  67. arguments. A plugin's ``options()`` method receives a parser
  68. instance. It's good form for a plugin to use that instance only to add
  69. additional arguments that take only long arguments (--like-this). Most
  70. of nose's built-in arguments get their default value from an environment
  71. variable.
  72. A plugin's ``configure()`` method receives the parsed ``OptionParser`` options
  73. object, as well as the current config object. Plugins should configure their
  74. behavior based on the user-selected settings, and may raise exceptions
  75. if the configured behavior is nonsensical.
  76. Logging
  77. =======
  78. nose uses the logging classes from the standard library. To enable users
  79. to view debug messages easily, plugins should use ``logging.getLogger()`` to
  80. acquire a logger in the ``nose.plugins`` namespace.
  81. Recipes
  82. =======
  83. * Writing a plugin that monitors or controls test result output
  84. Implement any or all of ``addError``, ``addFailure``, etc., to monitor test
  85. results. If you also want to monitor output, implement
  86. ``setOutputStream`` and keep a reference to the output stream. If you
  87. want to prevent the builtin ``TextTestResult`` output, implement
  88. ``setOutputSteam`` and *return a dummy stream*. The default output will go
  89. to the dummy stream, while you send your desired output to the real stream.
  90. Example: `examples/html_plugin/htmlplug.py`_
  91. * Writing a plugin that handles exceptions
  92. Subclass :doc:`ErrorClassPlugin <errorclasses>`.
  93. Examples: :doc:`nose.plugins.deprecated <deprecated>`,
  94. :doc:`nose.plugins.skip <skip>`
  95. * Writing a plugin that adds detail to error reports
  96. Implement ``formatError`` and/or ``formatFailure``. The error tuple
  97. you return (error class, error message, traceback) will replace the
  98. original error tuple.
  99. Examples: :doc:`nose.plugins.capture <capture>`,
  100. :doc:`nose.plugins.failuredetail <failuredetail>`
  101. * Writing a plugin that loads tests from files other than python modules
  102. Implement ``wantFile`` and ``loadTestsFromFile``. In ``wantFile``,
  103. return True for files that you want to examine for tests. In
  104. ``loadTestsFromFile``, for those files, return an iterable
  105. containing TestCases (or yield them as you find them;
  106. ``loadTestsFromFile`` may also be a generator).
  107. Example: :doc:`nose.plugins.doctests <doctests>`
  108. * Writing a plugin that prints a report
  109. Implement ``begin`` if you need to perform setup before testing
  110. begins. Implement ``report`` and output your report to the provided stream.
  111. Examples: :doc:`nose.plugins.cover <cover>`, :doc:`nose.plugins.prof <prof>`
  112. * Writing a plugin that selects or rejects tests
  113. Implement any or all ``want*`` methods. Return False to reject the test
  114. candidate, True to accept it -- which means that the test candidate
  115. will pass through the rest of the system, so you must be prepared to
  116. load tests from it if tests can't be loaded by the core loader or
  117. another plugin -- and None if you don't care.
  118. Examples: :doc:`nose.plugins.attrib <attrib>`,
  119. :doc:`nose.plugins.doctests <doctests>`, :doc:`nose.plugins.testid <testid>`
  120. More Examples
  121. =============
  122. See any builtin plugin or example plugin in the examples_ directory in
  123. the nose source distribution. There is a list of third-party plugins
  124. `on jottit`_.
  125. .. _examples/html_plugin/htmlplug.py: http://python-nose.googlecode.com/svn/trunk/examples/html_plugin/htmlplug.py
  126. .. _examples: http://python-nose.googlecode.com/svn/trunk/examples
  127. .. _on jottit: http://nose-plugins.jottit.com/
  128. """
  129. from nose.plugins.base import Plugin
  130. from nose.plugins.manager import *
  131. from nose.plugins.plugintest import PluginTester
  132. if __name__ == '__main__':
  133. import doctest
  134. doctest.testmod()