''' A simplified version of the unittest module, adapted to run unit tests on data sets instead of code. @author: olivier.massot, 2018 ''' import inspect import sys UNKNOWN = 0 SUCCESS = 1 FAILURE = 2 ERROR = 3 _result_to_str = {UNKNOWN: 'Inconnu', SUCCESS: 'Succès', FAILURE: 'Echec', ERROR: 'Erreur'} class TestError(): def __init__(self, message, info = {}, critical=False): self.message = message self.info = info self.critical = critical def __repr__(self): return f"TestError" class TestResult(): def __init__(self, test): self._test = test self._name = "" self._status = UNKNOWN self.errors = [] self._exc_info = None @property def name(self): return self._name or self._test.__name__[5:] @property def title(self): return self._test.__doc__.split("\n")[0].strip() @property def description(self): return self._test.__doc__.strip() @property def status(self): return self._status @property def status_str(self): return _result_to_str[self._status] def __repr__(self): return f"TestResult" def log_error(self, message, info={}): self._status = FAILURE error = TestError(message, info) self.errors.append(error) def handle_exception(self): self._status = ERROR error = TestError("Une erreur inconnue s'est produite, veuillez consulter les fichiers de journalisation.", {"exc_info": sys.exc_info()}) self.errors.append(error) class BaseChecker(): def __init__(self): self._test_running = None def setUp(self): pass def tearDown(self): pass def log_error(self, message, **info): self._test_running.log_error(message, info) def run(self): tests_results = [] for mname, m in inspect.getmembers(self, predicate=inspect.ismethod): if mname[:5] == 'test_': r = TestResult(m) self._test_running = r self.setUp() try: m() except: r.handle_exception() self.tearDown() tests_results.append(r) if any(err.critical for err in r.errors): break return tests_results if __name__ == '__main__': class ExampleChecker(BaseChecker): def test_a(self): """ Test 1 """ for i in range(10): self.log_error(f"error-{i}", {"i": i}) def test_b(self): """ Test 2 some longer description """ return ch = ExampleChecker() results = ch.run() for r in results: print(r) for e in r.errors: print(e)