Advertisement
Guest User

JUnit annotations

a guest
Nov 8th, 2013
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.28 KB | None | 0 0
  1. from operator import itemgetter
  2. from functools import wraps
  3. import unittest
  4.  
  5.  
  6. BEFORE, AFTER, TEST = range(3)
  7.  
  8.  
  9. # NOTE: sequence is negative for LIFO sorting
  10. def before(f, __state=[0]):
  11.     # Annotate function, since it is still a plain function
  12.     f.annotate_call_when = BEFORE, __state[0]
  13.     __state[0] -= 1
  14.  
  15.     return f
  16.  
  17. def after(f, __state=[0]):
  18.     # Annotate function, since it is still a plain function
  19.     f.annotate_call_when = AFTER, __state[0]
  20.     __state[0] -= 1
  21.  
  22.     return f
  23.  
  24. def test(f):
  25.     # Annotate function, since it is still a plain function
  26.     f.annotate_call_when = TEST, 0
  27.  
  28.     return f
  29.  
  30.  
  31. class JUnitAnnotations(type):
  32.     def __new__(cls, name, bases, ns):
  33.         def collect(ns):
  34.             for name, value in ns.iteritems():
  35.                 annotation, n = getattr(
  36.                     value, "annotate_call_when", (None, 0))
  37.                 if annotation == BEFORE:
  38.                     call_before.append((value, n))
  39.                 elif annotation == AFTER:
  40.                     call_after.append((value, n))
  41.                 elif annotation == TEST:
  42.                     call_test.append((name, value))
  43.  
  44.         def test_wrapper(test, call_before, call_after):
  45.             @wraps(test)
  46.             def wrapped(self):
  47.                 for fixture, n in call_before:
  48.                     fixture(self)
  49.  
  50.                 test(self)
  51.  
  52.                 for fixture, n in call_after:
  53.                     fixture(self)
  54.  
  55.             return wrapped
  56.  
  57.         call_before = []
  58.         call_after = []
  59.         call_test = []
  60.  
  61.         # Collect all annotations
  62.         collect(ns)
  63.         for parent in bases:
  64.             collect(parent.__dict__)
  65.  
  66.         # Before and After functions must be called LIFO
  67.         # The order is correct for base classes, since base classes
  68.         # methods calls the after and before decorators first.
  69.         call_before.sort(key=itemgetter(1))
  70.         call_after.sort(key=itemgetter(1))
  71.  
  72.         # Wrap each annotated Test so that Before and After fixtures are
  73.         # executed correctly
  74.         for name, fun in call_test:
  75.             ns[name] = test_wrapper(
  76.                 fun, call_before, call_after)
  77.  
  78.         # Let it be
  79.         return super(JUnitAnnotations, cls).__new__(cls, name, bases, ns)
  80.  
  81.  
  82. class AnnotatedTestCase(unittest.TestCase):
  83.     __metaclass__ = JUnitAnnotations
  84.  
  85.  
  86. class TestCaseBase(AnnotatedTestCase):
  87.     @before
  88.     def fixture_base_before_1(self):
  89.         print "fixture base before 1"
  90.  
  91.     @before
  92.     def fixture_base_before_2(self):
  93.         print "fixture base before 2"
  94.  
  95.     @after
  96.     def fixture_base_after_1(self):
  97.         print "fixture base after 1"
  98.  
  99.     @after
  100.     def fixture_base_after_2(self):
  101.         print "fixture base after 2"
  102.  
  103.  
  104. class TestCase(TestCaseBase):
  105.     @before
  106.     def fixture_before_1(self):
  107.         print "fixture before 1"
  108.  
  109.     @before
  110.     def fixture_before_2(self):
  111.         print "fixture before 2"
  112.  
  113.     @after
  114.     def fixture_after_1(self):
  115.         print "fixture after 1"
  116.  
  117.     @after
  118.     def fixture_after_2(self):
  119.         print "fixture after 2"
  120.  
  121.     @test
  122.     def test(self):
  123.         print "test"
  124.  
  125.     # internal
  126.     def runTest(self):
  127.         pass
  128.  
  129.  
  130. if __name__ == '__main__':
  131.     t = TestCase()
  132.  
  133.     t.test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement