1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

""" 

Writing Plugins 

--------------- 

 

nose supports plugins for test collection, selection, observation and 

reporting. There are two basic rules for plugins: 

 

* Plugin classes should subclass :class:`nose.plugins.Plugin`. 

 

* Plugins may implement any of the methods described in the class 

:doc:`IPluginInterface <interface>` in nose.plugins.base. Please note that 

this class is for documentary purposes only; plugins may not subclass 

IPluginInterface. 

 

Hello World 

=========== 

 

Here's a basic plugin. It doesn't do much so read on for more ideas or dive 

into the :doc:`IPluginInterface <interface>` to see all available hooks. 

 

.. code-block:: python 

 

import logging 

import os 

 

from nose.plugins import Plugin 

 

log = logging.getLogger('nose.plugins.helloworld') 

 

class HelloWorld(Plugin): 

name = 'helloworld' 

 

def options(self, parser, env=os.environ): 

super(HelloWorld, self).options(parser, env=env) 

 

def configure(self, options, conf): 

super(HelloWorld, self).configure(options, conf) 

if not self.enabled: 

return 

 

def finalize(self, result): 

log.info('Hello pluginized world!') 

 

Registering 

=========== 

 

.. Note:: 

Important note: the following applies only to the default 

plugin manager. Other plugin managers may use different means to 

locate and load plugins. 

 

For nose to find a plugin, it must be part of a package that uses 

setuptools_, and the plugin must be included in the entry points defined 

in the setup.py for the package: 

 

.. code-block:: python 

 

setup(name='Some plugin', 

# ... 

entry_points = { 

'nose.plugins.0.10': [ 

'someplugin = someplugin:SomePlugin' 

] 

}, 

# ... 

) 

 

Once the package is installed with install or develop, nose will be able 

to load the plugin. 

 

.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools 

 

Registering a plugin without setuptools 

======================================= 

 

It is currently possible to register a plugin programmatically by 

creating a custom nose runner like this : 

 

.. code-block:: python 

 

import nose 

from yourplugin import YourPlugin 

 

if __name__ == '__main__': 

nose.main(addplugins=[YourPlugin()]) 

 

Defining options 

================ 

 

All plugins must implement the methods ``options(self, parser, env)`` 

and ``configure(self, options, conf)``. Subclasses of nose.plugins.Plugin 

that want the standard options should call the superclass methods. 

 

nose uses optparse.OptionParser from the standard library to parse 

arguments. A plugin's ``options()`` method receives a parser 

instance. It's good form for a plugin to use that instance only to add 

additional arguments that take only long arguments (--like-this). Most 

of nose's built-in arguments get their default value from an environment 

variable. 

 

A plugin's ``configure()`` method receives the parsed ``OptionParser`` options 

object, as well as the current config object. Plugins should configure their 

behavior based on the user-selected settings, and may raise exceptions 

if the configured behavior is nonsensical. 

 

Logging 

======= 

 

nose uses the logging classes from the standard library. To enable users 

to view debug messages easily, plugins should use ``logging.getLogger()`` to 

acquire a logger in the ``nose.plugins`` namespace. 

 

Recipes 

======= 

 

* Writing a plugin that monitors or controls test result output 

 

Implement any or all of ``addError``, ``addFailure``, etc., to monitor test 

results. If you also want to monitor output, implement 

``setOutputStream`` and keep a reference to the output stream. If you 

want to prevent the builtin ``TextTestResult`` output, implement 

``setOutputSteam`` and *return a dummy stream*. The default output will go 

to the dummy stream, while you send your desired output to the real stream. 

 

Example: `examples/html_plugin/htmlplug.py`_ 

 

* Writing a plugin that handles exceptions 

 

Subclass :doc:`ErrorClassPlugin <errorclasses>`. 

 

Examples: :doc:`nose.plugins.deprecated <deprecated>`, 

:doc:`nose.plugins.skip <skip>` 

 

* Writing a plugin that adds detail to error reports 

 

Implement ``formatError`` and/or ``formatFailure``. The error tuple 

you return (error class, error message, traceback) will replace the 

original error tuple. 

 

Examples: :doc:`nose.plugins.capture <capture>`, 

:doc:`nose.plugins.failuredetail <failuredetail>` 

 

* Writing a plugin that loads tests from files other than python modules 

 

Implement ``wantFile`` and ``loadTestsFromFile``. In ``wantFile``, 

return True for files that you want to examine for tests. In 

``loadTestsFromFile``, for those files, return an iterable 

containing TestCases (or yield them as you find them; 

``loadTestsFromFile`` may also be a generator). 

 

Example: :doc:`nose.plugins.doctests <doctests>` 

 

* Writing a plugin that prints a report 

 

Implement ``begin`` if you need to perform setup before testing 

begins. Implement ``report`` and output your report to the provided stream. 

 

Examples: :doc:`nose.plugins.cover <cover>`, :doc:`nose.plugins.prof <prof>` 

 

* Writing a plugin that selects or rejects tests 

 

Implement any or all ``want*`` methods. Return False to reject the test 

candidate, True to accept it -- which means that the test candidate 

will pass through the rest of the system, so you must be prepared to 

load tests from it if tests can't be loaded by the core loader or 

another plugin -- and None if you don't care. 

 

Examples: :doc:`nose.plugins.attrib <attrib>`, 

:doc:`nose.plugins.doctests <doctests>`, :doc:`nose.plugins.testid <testid>` 

 

 

More Examples 

============= 

 

See any builtin plugin or example plugin in the examples_ directory in 

the nose source distribution. There is a list of third-party plugins 

`on jottit`_. 

 

.. _examples/html_plugin/htmlplug.py: http://python-nose.googlecode.com/svn/trunk/examples/html_plugin/htmlplug.py 

.. _examples: http://python-nose.googlecode.com/svn/trunk/examples 

.. _on jottit: http://nose-plugins.jottit.com/ 

 

""" 

from nose.plugins.base import Plugin 

from nose.plugins.manager import * 

from nose.plugins.plugintest import PluginTester 

 

if __name__ == '__main__': 

import doctest 

doctest.testmod()