nontrivial.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. """Tools not exempt from being descended into in tracebacks"""
  2. import time
  3. __all__ = ['make_decorator', 'raises', 'set_trace', 'timed', 'with_setup',
  4. 'TimeExpired', 'istest', 'nottest']
  5. class TimeExpired(AssertionError):
  6. pass
  7. def make_decorator(func):
  8. """
  9. Wraps a test decorator so as to properly replicate metadata
  10. of the decorated function, including nose's additional stuff
  11. (namely, setup and teardown).
  12. """
  13. def decorate(newfunc):
  14. if hasattr(func, 'compat_func_name'):
  15. name = func.compat_func_name
  16. else:
  17. name = func.__name__
  18. newfunc.__dict__ = func.__dict__
  19. newfunc.__doc__ = func.__doc__
  20. newfunc.__module__ = func.__module__
  21. if not hasattr(newfunc, 'compat_co_firstlineno'):
  22. newfunc.compat_co_firstlineno = func.func_code.co_firstlineno
  23. try:
  24. newfunc.__name__ = name
  25. except TypeError:
  26. # can't set func name in 2.3
  27. newfunc.compat_func_name = name
  28. return newfunc
  29. return decorate
  30. def raises(*exceptions):
  31. """Test must raise one of expected exceptions to pass.
  32. Example use::
  33. @raises(TypeError, ValueError)
  34. def test_raises_type_error():
  35. raise TypeError("This test passes")
  36. @raises(Exception)
  37. def test_that_fails_by_passing():
  38. pass
  39. If you want to test many assertions about exceptions in a single test,
  40. you may want to use `assert_raises` instead.
  41. """
  42. valid = ' or '.join([e.__name__ for e in exceptions])
  43. def decorate(func):
  44. name = func.__name__
  45. def newfunc(*arg, **kw):
  46. try:
  47. func(*arg, **kw)
  48. except exceptions:
  49. pass
  50. except:
  51. raise
  52. else:
  53. message = "%s() did not raise %s" % (name, valid)
  54. raise AssertionError(message)
  55. newfunc = make_decorator(func)(newfunc)
  56. return newfunc
  57. return decorate
  58. def set_trace():
  59. """Call pdb.set_trace in the calling frame, first restoring
  60. sys.stdout to the real output stream. Note that sys.stdout is NOT
  61. reset to whatever it was before the call once pdb is done!
  62. """
  63. import pdb
  64. import sys
  65. stdout = sys.stdout
  66. sys.stdout = sys.__stdout__
  67. pdb.Pdb().set_trace(sys._getframe().f_back)
  68. def timed(limit):
  69. """Test must finish within specified time limit to pass.
  70. Example use::
  71. @timed(.1)
  72. def test_that_fails():
  73. time.sleep(.2)
  74. """
  75. def decorate(func):
  76. def newfunc(*arg, **kw):
  77. start = time.time()
  78. result = func(*arg, **kw)
  79. end = time.time()
  80. if end - start > limit:
  81. raise TimeExpired("Time limit (%s) exceeded" % limit)
  82. return result
  83. newfunc = make_decorator(func)(newfunc)
  84. return newfunc
  85. return decorate
  86. def with_setup(setup=None, teardown=None):
  87. """Decorator to add setup and/or teardown methods to a test function::
  88. @with_setup(setup, teardown)
  89. def test_something():
  90. " ... "
  91. Note that `with_setup` is useful *only* for test functions, not for test
  92. methods or inside of TestCase subclasses.
  93. """
  94. def decorate(func, setup=setup, teardown=teardown):
  95. if setup:
  96. if hasattr(func, 'setup'):
  97. _old_s = func.setup
  98. def _s():
  99. setup()
  100. _old_s()
  101. func.setup = _s
  102. else:
  103. func.setup = setup
  104. if teardown:
  105. if hasattr(func, 'teardown'):
  106. _old_t = func.teardown
  107. def _t():
  108. _old_t()
  109. teardown()
  110. func.teardown = _t
  111. else:
  112. func.teardown = teardown
  113. return func
  114. return decorate
  115. def istest(func):
  116. """Decorator to mark a function or method as a test
  117. """
  118. func.__test__ = True
  119. return func
  120. def nottest(func):
  121. """Decorator to mark a function or method as *not* a test
  122. """
  123. func.__test__ = False
  124. return func