diff options
author | Robert Collins <robertc@robertcollins.net> | 2009-03-08 15:37:33 +1100 |
---|---|---|
committer | Robert Collins <robertc@robertcollins.net> | 2009-03-08 15:37:33 +1100 |
commit | f200c2bcf7eaef2dcad37737ebe9fb5e629c938e (patch) | |
tree | ffe2cee5823665318151e0a46ccfbe2741ccd3d7 | |
parent | 50d71aaaf387ad7dc259eb291d2860a0b946fd8c (diff) | |
download | testscenarios-f200c2bcf7eaef2dcad37737ebe9fb5e629c938e.tar.gz |
Factor out all the individual components of generate_tests.
-rw-r--r-- | README | 12 | ||||
-rw-r--r-- | lib/testscenarios/__init__.py | 4 | ||||
-rw-r--r-- | lib/testscenarios/scenarios.py | 36 | ||||
-rw-r--r-- | lib/testscenarios/tests/test_scenarios.py | 79 |
4 files changed, 107 insertions, 24 deletions
@@ -189,3 +189,15 @@ For instance:: >>> class TestHashPerformance(TestCase): >>> >>> scenarios = hash_scenarios + + +Forcing Scenarios ++++++++++++++++++ + +The ``apply_scenarios`` function can be useful to apply scenarios to a test +that has none applied. ``apply_scenarios`` is the workhorse for +``generate_scenarios``, except it takes the scenarios passed in rather than +introspecting the test object to determine the scenarios. The +``apply_scenarios`` function does not reset the test scenarios attribute, +allowing it to be used to layer scenarios without affecting existing scenario +selection. diff --git a/lib/testscenarios/__init__.py b/lib/testscenarios/__init__.py index 4e0bf5d..ac29e0e 100644 --- a/lib/testscenarios/__init__.py +++ b/lib/testscenarios/__init__.py @@ -31,13 +31,15 @@ methods for details. __all__ = [ 'TestWithScenarios', + 'apply_scenario', + 'apply_scenarios', 'generate_scenarios', ] import unittest -from testscenarios.scenarios import generate_scenarios +from testscenarios.scenarios import apply_scenario, generate_scenarios from testscenarios.testcase import TestWithScenarios diff --git a/lib/testscenarios/scenarios.py b/lib/testscenarios/scenarios.py index bbc73ad..eacd9d2 100644 --- a/lib/testscenarios/scenarios.py +++ b/lib/testscenarios/scenarios.py @@ -18,6 +18,8 @@ # __all__ = [ + 'apply_scenario', + 'apply_scenarios', 'generate_scenarios', ] @@ -26,6 +28,34 @@ import unittest from testtools.testcase import clone_test_with_new_id from testtools import iterate_tests + +def apply_scenario((name, parameters), test): + """Apply scenario to test. + + :param scenario: A tuple (name, parameters) to apply to the test. The test + is cloned, its id adjusted to have (name) after it, and the parameters + dict is used to update the new test. + :param test: The test to apply the scenario to. This test is unaltered. + :return: A new test cloned from test, with the scenario applied. + """ + newtest = clone_test_with_new_id(test, + test.id() + '(' + name + ')') + for key, value in parameters.iteritems(): + setattr(newtest, key, value) + return newtest + + +def apply_scenarios(scenarios, test): + """Apply many scenarios to a test. + + :param scenarios: An iterable of scenarios. + :param test: A test to apply the scenarios to. + :return: A generator of tests. + """ + for scenario in scenarios: + yield apply_scenario(scenario, test) + + def generate_scenarios(test_or_suite): """Yield the tests in test_or_suite with scenario multiplication done. @@ -39,12 +69,8 @@ def generate_scenarios(test_or_suite): for test in iterate_tests(test_or_suite): scenarios = getattr(test, 'scenarios', None) if scenarios: - for name, parameters in scenarios: - newtest = clone_test_with_new_id(test, - test.id() + '(' + name + ')') + for newtest in apply_scenarios(scenarios, test): newtest.scenarios = None - for key, value in parameters.iteritems(): - setattr(newtest, key, value) yield newtest else: yield test diff --git a/lib/testscenarios/tests/test_scenarios.py b/lib/testscenarios/tests/test_scenarios.py index b019d97..07db03f 100644 --- a/lib/testscenarios/tests/test_scenarios.py +++ b/lib/testscenarios/tests/test_scenarios.py @@ -20,31 +20,50 @@ import unittest import testscenarios -from testscenarios.scenarios import generate_scenarios +from testscenarios.scenarios import ( + apply_scenario, + apply_scenarios, + generate_scenarios, + ) +import testtools from testtools.tests.helpers import LoggingResult -class TestGenerateScenarios(unittest.TestCase): +class TestGenerateScenarios(testtools.TestCase): + + def hook_apply_scenarios(self): + self.addCleanup(setattr, testscenarios.scenarios, 'apply_scenarios', + apply_scenarios) + log = [] + def capture(scenarios, test): + log.append((scenarios, test)) + return apply_scenarios(scenarios, test) + testscenarios.scenarios.apply_scenarios = capture + return log def test_generate_scenarios_preserves_normal_test(self): class ReferenceTest(unittest.TestCase): def test_pass(self): pass test = ReferenceTest("test_pass") + log = self.hook_apply_scenarios() self.assertEqual([test], list(generate_scenarios(test))) + self.assertEqual([], log) - def test_normal_test_with_one_scenario(self): + def test_tests_with_scenarios_calls_apply_scenarios(self): class ReferenceTest(unittest.TestCase): scenarios = [('demo', {})] def test_pass(self): pass test = ReferenceTest("test_pass") + log = self.hook_apply_scenarios() tests = list(generate_scenarios(test)) self.assertEqual( 'testscenarios.tests.test_scenarios.ReferenceTest.test_pass(demo)', tests[0].id()) + self.assertEqual([([('demo', {})], test)], log) - def test_normal_test_two_scenarios(self): + def test_all_scenarios_yielded(self): class ReferenceTest(unittest.TestCase): scenarios = [('1', {}), ('2', {})] def test_pass(self): @@ -58,20 +77,6 @@ class TestGenerateScenarios(unittest.TestCase): 'testscenarios.tests.test_scenarios.ReferenceTest.test_pass(2)', tests[1].id()) - def test_attributes_set(self): - class ReferenceTest(unittest.TestCase): - scenarios = [ - ('1', {'foo': 1, 'bar': 2}), - ('2', {'foo': 2, 'bar': 4})] - def test_check_foo(self): - pass - test = ReferenceTest("test_check_foo") - tests = list(generate_scenarios(test)) - self.assertEqual(1, tests[0].foo) - self.assertEqual(2, tests[0].bar) - self.assertEqual(2, tests[1].foo) - self.assertEqual(4, tests[1].bar) - def test_scenarios_attribute_cleared(self): class ReferenceTest(unittest.TestCase): scenarios = [ @@ -98,3 +103,41 @@ class TestGenerateScenarios(unittest.TestCase): suite.addTest(Reference2("test_something")) tests = list(generate_scenarios(suite)) self.assertEqual(4, len(tests)) + + +class TestApplyScenario(testtools.TestCase): + + def test_apply_scenario_sets_id_and_attributes(self): + class ReferenceTest(unittest.TestCase): + def test_pass(self): + pass + test = ReferenceTest("test_pass") + result = apply_scenario(('demo', {'foo': 'bar'}), test) + self.assertEqual( + 'testscenarios.tests.test_scenarios.ReferenceTest.test_pass(demo)', + result.id()) + self.assertEqual('bar', result.foo) + + +class TestApplyScenarios(testtools.TestCase): + + def test_calls_apply_scenario(self): + self.addCleanup(setattr, testscenarios.scenarios, 'apply_scenario', + apply_scenario) + log = [] + def capture(scenario, test): + log.append((scenario, test)) + testscenarios.scenarios.apply_scenario = capture + scenarios = ["foo", "bar"] + result = list(apply_scenarios(scenarios, "test")) + self.assertEqual([('foo', 'test'), ('bar', 'test')], log) + + def test_preserves_scenarios_attribute(self): + class ReferenceTest(unittest.TestCase): + scenarios = [('demo', {})] + def test_pass(self): + pass + test = ReferenceTest("test_pass") + tests = list(apply_scenarios(ReferenceTest.scenarios, test)) + self.assertEqual([('demo', {})], ReferenceTest.scenarios) + self.assertEqual(ReferenceTest.scenarios, tests[0].scenarios) |