structured_example.py (2550B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import argparse 6 import sys 7 import traceback 8 import types 9 10 from mozlog import commandline, get_default_logger 11 12 13 class TestAssertion(Exception): 14 pass 15 16 17 def assert_equals(a, b): 18 if a != b: 19 raise TestAssertion("%r not equal to %r" % (a, b)) 20 21 22 def expected(status): 23 def inner(f): 24 def test_func(): 25 f() 26 27 test_func.__name__ = f.__name__ 28 test_func._expected = status 29 return test_func 30 31 return inner 32 33 34 def test_that_passes(): 35 assert_equals(1, int("1")) 36 37 38 def test_that_fails(): 39 assert_equals(1, int("2")) 40 41 42 def test_that_has_an_error(): 43 assert_equals(2, 1 + "1") 44 45 46 @expected("FAIL") 47 def test_expected_fail(): 48 assert_equals(2 + 2, 5) 49 50 51 class TestRunner: 52 def __init__(self): 53 self.logger = get_default_logger(component="TestRunner") 54 55 def gather_tests(self): 56 for item in globals().values(): 57 if isinstance(item, types.FunctionType) and item.__name__.startswith( 58 "test_" 59 ): 60 yield item.__name__, item 61 62 def run(self): 63 tests = list(self.gather_tests()) 64 65 self.logger.suite_start(tests=[name for name, func in tests]) 66 self.logger.info("Running tests") 67 for name, func in tests: 68 self.run_test(name, func) 69 self.logger.suite_end() 70 71 def run_test(self, name, func): 72 self.logger.test_start(name) 73 status = None 74 message = None 75 expected = func._expected if hasattr(func, "_expected") else "PASS" 76 try: 77 func() 78 except TestAssertion as e: 79 status = "FAIL" 80 message = str(e) 81 except Exception: 82 status = "ERROR" 83 message = traceback.format_exc() 84 else: 85 status = "PASS" 86 self.logger.test_end(name, status=status, expected=expected, message=message) 87 88 89 def get_parser(): 90 parser = argparse.ArgumentParser() 91 return parser 92 93 94 def main(): 95 parser = get_parser() 96 commandline.add_logging_group(parser) 97 98 args = parser.parse_args() 99 100 logger = commandline.setup_logging("structured-example", args, {"raw": sys.stdout}) 101 102 runner = TestRunner() 103 try: 104 runner.run() 105 except Exception: 106 logger.critical("Error during test run:\n%s" % traceback.format_exc()) 107 108 109 if __name__ == "__main__": 110 main()