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

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

"""nose unittest.TestCase subclasses. It is not necessary to subclass these 

classes when writing tests; they are used internally by nose.loader.TestLoader 

to create test cases from test functions and methods in test classes. 

""" 

import logging 

import sys 

import unittest 

from inspect import isfunction 

from nose.config import Config 

from nose.failure import Failure # for backwards compatibility 

from nose.util import resolve_name, test_address, try_run 

 

log = logging.getLogger(__name__) 

 

 

__all__ = ['Test'] 

 

 

class Test(unittest.TestCase): 

"""The universal test case wrapper. 

 

When a plugin sees a test, it will always see an instance of this 

class. To access the actual test case that will be run, access the 

test property of the nose.case.Test instance. 

""" 

__test__ = False # do not collect 

def __init__(self, test, config=None, resultProxy=None): 

# sanity check 

if not callable(test): 

raise TypeError("nose.case.Test called with argument %r that " 

"is not callable. A callable is required." 

% test) 

self.test = test 

if config is None: 

config = Config() 

self.config = config 

self.tbinfo = None 

self.capturedOutput = None 

self.resultProxy = resultProxy 

self.plugins = config.plugins 

self.passed = None 

unittest.TestCase.__init__(self) 

 

def __call__(self, *arg, **kwarg): 

return self.run(*arg, **kwarg) 

 

def __str__(self): 

name = self.plugins.testName(self) 

if name is not None: 

return name 

return str(self.test) 

 

def __repr__(self): 

return "Test(%r)" % self.test 

 

def afterTest(self, result): 

"""Called after test is complete (after result.stopTest) 

""" 

try: 

afterTest = result.afterTest 

except AttributeError: 

pass 

else: 

afterTest(self.test) 

 

def beforeTest(self, result): 

"""Called before test is run (before result.startTest) 

""" 

try: 

beforeTest = result.beforeTest 

except AttributeError: 

pass 

else: 

beforeTest(self.test) 

 

def exc_info(self): 

"""Extract exception info. 

""" 

exc, exv, tb = sys.exc_info() 

return (exc, exv, tb) 

 

def id(self): 

"""Get a short(er) description of the test 

""" 

return self.test.id() 

 

def address(self): 

"""Return a round-trip name for this test, a name that can be 

fed back as input to loadTestByName and (assuming the same 

plugin configuration) result in the loading of this test. 

""" 

if hasattr(self.test, 'address'): 

return self.test.address() 

else: 

# not a nose case 

return test_address(self.test) 

 

def _context(self): 

try: 

return self.test.context 

except AttributeError: 

pass 

try: 

return self.test.__class__ 

except AttributeError: 

pass 

try: 

return resolve_name(self.test.__module__) 

except AttributeError: 

pass 

return None 

context = property(_context, None, None, 

"""Get the context object of this test (if any).""") 

 

def run(self, result): 

"""Modified run for the test wrapper. 

 

From here we don't call result.startTest or stopTest or 

addSuccess. The wrapper calls addError/addFailure only if its 

own setup or teardown fails, or running the wrapped test fails 

(eg, if the wrapped "test" is not callable). 

 

Two additional methods are called, beforeTest and 

afterTest. These give plugins a chance to modify the wrapped 

test before it is called and do cleanup after it is 

called. They are called unconditionally. 

""" 

if self.resultProxy: 

result = self.resultProxy(result, self) 

try: 

try: 

self.beforeTest(result) 

self.runTest(result) 

except KeyboardInterrupt: 

raise 

except: 

err = sys.exc_info() 

result.addError(self, err) 

finally: 

self.afterTest(result) 

 

def runTest(self, result): 

"""Run the test. Plugins may alter the test by returning a 

value from prepareTestCase. The value must be callable and 

must accept one argument, the result instance. 

""" 

test = self.test 

plug_test = self.config.plugins.prepareTestCase(self) 

if plug_test is not None: 

test = plug_test 

test(result) 

 

def shortDescription(self): 

desc = self.plugins.describeTest(self) 

if desc is not None: 

return desc 

# work around bug in unittest.TestCase.shortDescription 

# with multiline docstrings. 

test = self.test 

try: 

test._testMethodDoc = test._testMethodDoc.strip()# 2.5 

except AttributeError: 

try: 

# 2.4 and earlier 

test._TestCase__testMethodDoc = \ 

test._TestCase__testMethodDoc.strip() 

except AttributeError: 

pass 

# 2.7 compat: shortDescription() always returns something 

# which is a change from 2.6 and below, and breaks the 

# testName plugin call. 

try: 

desc = self.test.shortDescription() 

except Exception: 

# this is probably caused by a problem in test.__str__() and is 

# only triggered by python 3.1's unittest! 

pass 

try: 

if desc == str(self.test): 

return 

except Exception: 

# If str() triggers an exception then ignore it. 

# see issue 422 

pass 

return desc 

 

 

class TestBase(unittest.TestCase): 

"""Common functionality for FunctionTestCase and MethodTestCase. 

""" 

__test__ = False # do not collect 

 

def id(self): 

return str(self) 

 

def runTest(self): 

self.test(*self.arg) 

 

def shortDescription(self): 

if hasattr(self.test, 'description'): 

return self.test.description 

func, arg = self._descriptors() 

doc = getattr(func, '__doc__', None) 

if not doc: 

doc = str(self) 

return doc.strip().split("\n")[0].strip() 

 

 

class FunctionTestCase(TestBase): 

"""TestCase wrapper for test functions. 

 

Don't use this class directly; it is used internally in nose to 

create test cases for test functions. 

""" 

__test__ = False # do not collect 

 

def __init__(self, test, setUp=None, tearDown=None, arg=tuple(), 

descriptor=None): 

"""Initialize the MethodTestCase. 

 

Required argument: 

 

* test -- the test function to call. 

 

Optional arguments: 

 

* setUp -- function to run at setup. 

 

* tearDown -- function to run at teardown. 

 

* arg -- arguments to pass to the test function. This is to support 

generator functions that yield arguments. 

 

* descriptor -- the function, other than the test, that should be used 

to construct the test name. This is to support generator functions. 

""" 

 

self.test = test 

self.setUpFunc = setUp 

self.tearDownFunc = tearDown 

self.arg = arg 

self.descriptor = descriptor 

TestBase.__init__(self) 

 

def address(self): 

"""Return a round-trip name for this test, a name that can be 

fed back as input to loadTestByName and (assuming the same 

plugin configuration) result in the loading of this test. 

""" 

if self.descriptor is not None: 

return test_address(self.descriptor) 

else: 

return test_address(self.test) 

 

def _context(self): 

return resolve_name(self.test.__module__) 

context = property(_context, None, None, 

"""Get context (module) of this test""") 

 

def setUp(self): 

"""Run any setup function attached to the test function 

""" 

if self.setUpFunc: 

self.setUpFunc() 

else: 

names = ('setup', 'setUp', 'setUpFunc') 

try_run(self.test, names) 

 

def tearDown(self): 

"""Run any teardown function attached to the test function 

""" 

if self.tearDownFunc: 

self.tearDownFunc() 

else: 

names = ('teardown', 'tearDown', 'tearDownFunc') 

try_run(self.test, names) 

 

def __str__(self): 

func, arg = self._descriptors() 

if hasattr(func, 'compat_func_name'): 

name = func.compat_func_name 

else: 

name = func.__name__ 

name = "%s.%s" % (func.__module__, name) 

if arg: 

name = "%s%s" % (name, arg) 

# FIXME need to include the full dir path to disambiguate 

# in cases where test module of the same name was seen in 

# another directory (old fromDirectory) 

return name 

__repr__ = __str__ 

 

def _descriptors(self): 

"""Get the descriptors of the test function: the function and 

arguments that will be used to construct the test name. In 

most cases, this is the function itself and no arguments. For 

tests generated by generator functions, the original 

(generator) function and args passed to the generated function 

are returned. 

""" 

if self.descriptor: 

return self.descriptor, self.arg 

else: 

return self.test, self.arg 

 

 

class MethodTestCase(TestBase): 

"""Test case wrapper for test methods. 

 

Don't use this class directly; it is used internally in nose to 

create test cases for test methods. 

""" 

__test__ = False # do not collect 

 

def __init__(self, method, test=None, arg=tuple(), descriptor=None): 

"""Initialize the MethodTestCase. 

 

Required argument: 

 

* method -- the method to call, may be bound or unbound. In either 

case, a new instance of the method's class will be instantiated to 

make the call. Note: In Python 3.x, if using an unbound method, you 

must wrap it using pyversion.unbound_method. 

 

Optional arguments: 

 

* test -- the test function to call. If this is passed, it will be 

called instead of getting a new bound method of the same name as the 

desired method from the test instance. This is to support generator 

methods that yield inline functions. 

 

* arg -- arguments to pass to the test function. This is to support 

generator methods that yield arguments. 

 

* descriptor -- the function, other than the test, that should be used 

to construct the test name. This is to support generator methods. 

""" 

self.method = method 

self.test = test 

self.arg = arg 

self.descriptor = descriptor 

if isfunction(method): 

raise ValueError("Unbound methods must be wrapped using pyversion.unbound_method before passing to MethodTestCase") 

self.cls = method.__self__.__class__ 

self.inst = self.cls() 

if self.test is None: 

method_name = self.method.__name__ 

self.test = getattr(self.inst, method_name) 

TestBase.__init__(self) 

 

def __str__(self): 

func, arg = self._descriptors() 

if hasattr(func, 'compat_func_name'): 

name = func.compat_func_name 

else: 

name = func.__name__ 

name = "%s.%s.%s" % (self.cls.__module__, 

self.cls.__name__, 

name) 

if arg: 

name = "%s%s" % (name, arg) 

return name 

__repr__ = __str__ 

 

def address(self): 

"""Return a round-trip name for this test, a name that can be 

fed back as input to loadTestByName and (assuming the same 

plugin configuration) result in the loading of this test. 

""" 

if self.descriptor is not None: 

return test_address(self.descriptor) 

else: 

return test_address(self.method) 

 

def _context(self): 

return self.cls 

context = property(_context, None, None, 

"""Get context (class) of this test""") 

 

def setUp(self): 

try_run(self.inst, ('setup', 'setUp')) 

 

def tearDown(self): 

try_run(self.inst, ('teardown', 'tearDown')) 

 

def _descriptors(self): 

"""Get the descriptors of the test method: the method and 

arguments that will be used to construct the test name. In 

most cases, this is the method itself and no arguments. For 

tests generated by generator methods, the original 

(generator) method and args passed to the generated method  

or function are returned. 

""" 

if self.descriptor: 

return self.descriptor, self.arg 

else: 

return self.method, self.arg