From 863cade82b52552076802812fb998aa76c06ffb3 Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Sun, 17 Oct 2010 16:53:21 +0100 Subject: [PATCH] Extend the decorator to take kwargs and pass them on. Documentation, and rename to grammatically correct run_test_with. --- testtools/__init__.py | 4 ++-- testtools/testcase.py | 24 ++++++++++++++++++++---- testtools/tests/test_runtest.py | 25 +++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/testtools/__init__.py b/testtools/__init__.py index c13947b..06e9eef 100644 --- a/testtools/__init__.py +++ b/testtools/__init__.py @@ -11,7 +11,7 @@ __all__ = [ 'MultipleExceptions', 'MultiTestResult', 'PlaceHolder', - 'run_tests_with', + 'run_test_with', 'TestCase', 'TestResult', 'TextTestResult', @@ -34,7 +34,7 @@ from testtools.testcase import ( PlaceHolder, TestCase, clone_test_with_new_id, - run_tests_with, + run_test_with, skip, skipIf, skipUnless, diff --git a/testtools/testcase.py b/testtools/testcase.py index 4ba57e6..ebfd337 100644 --- a/testtools/testcase.py +++ b/testtools/testcase.py @@ -6,7 +6,7 @@ __metaclass__ = type __all__ = [ 'clone_test_with_new_id', 'MultipleExceptions', - 'run_tests_with', + 'run_test_with', 'skip', 'skipIf', 'skipUnless', @@ -62,9 +62,25 @@ except ImportError: """ -def run_tests_with(test_runner): +def run_test_with(test_runner, **kwargs): + """Decorate a test as using a specific `RunTest`. + + e.g. + @run_test_with(CustomRunner, timeout=42) + def test_foo(self): + self.assertTrue(True) + + :param test_runner: A `RunTest` factory that takes a test case and an + optional list of exception handlers. See `RunTest`. + :param **kwargs: Keyword arguments to pass on as extra arguments to + `test_runner`. + :return: A decorator to be used for marking a test as needing a special + runner. + """ + def make_test_runner(case, handlers=None): + return test_runner(case, handlers=handlers, **kwargs) def decorator(f): - f._run_tests_with = test_runner + f._run_test_with = make_test_runner return f return decorator @@ -109,7 +125,7 @@ class TestCase(unittest.TestCase): # TestCase is safe to use with clone_test_with_new_id. self.__details = None test_method = self._get_test_method() - self.__RunTest = getattr(test_method, '_run_tests_with', runTest) + self.__RunTest = getattr(test_method, '_run_test_with', runTest) self.__exception_handlers = [] self.exception_handlers = [ (self.skipException, self._report_skip), diff --git a/testtools/tests/test_runtest.py b/testtools/tests/test_runtest.py index ad2a3d9..c3c3d81 100644 --- a/testtools/tests/test_runtest.py +++ b/testtools/tests/test_runtest.py @@ -4,7 +4,7 @@ from testtools import ( ExtendedToOriginalDecorator, - run_tests_with, + run_test_with, RunTest, TestCase, TestResult, @@ -208,8 +208,9 @@ class TestTestCaseSupportForRunTest(TestCase): self.assertThat(from_run_test, Is(CustomRunTest.marker)) def test_decorator_for_run_test(self): + # Individual test methods can be marked as needing a special runner. class SomeCase(TestCase): - @run_tests_with(CustomRunTest) + @run_test_with(CustomRunTest) def test_foo(self): pass result = TestResult() @@ -217,6 +218,26 @@ class TestTestCaseSupportForRunTest(TestCase): from_run_test = case.run(result) self.assertThat(from_run_test, Is(CustomRunTest.marker)) + def test_extended_decorator_for_run_test(self): + # Individual test methods can be marked as needing a special runner. + # Extra arguments can be passed to the decorator which will then be + # passed on to the RunTest object. + marker = object() + class FooRunTest(RunTest): + def __init__(self, case, handlers=None, bar=None): + super(FooRunTest, self).__init__(case, handlers) + self.bar = bar + def run(self, result=None): + return self.bar + class SomeCase(TestCase): + @run_test_with(FooRunTest, bar=marker) + def test_foo(self): + pass + result = TestResult() + case = SomeCase('test_foo') + from_run_test = case.run(result) + self.assertThat(from_run_test, Is(marker)) + def test_suite(): from unittest import TestLoader