summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2009-03-08 15:37:33 +1100
committerRobert Collins <robertc@robertcollins.net>2009-03-08 15:37:33 +1100
commitf200c2bcf7eaef2dcad37737ebe9fb5e629c938e (patch)
treeffe2cee5823665318151e0a46ccfbe2741ccd3d7
parent50d71aaaf387ad7dc259eb291d2860a0b946fd8c (diff)
downloadtestscenarios-git-f200c2bcf7eaef2dcad37737ebe9fb5e629c938e.tar.gz
Factor out all the individual components of generate_tests.
-rw-r--r--README12
-rw-r--r--lib/testscenarios/__init__.py4
-rw-r--r--lib/testscenarios/scenarios.py36
-rw-r--r--lib/testscenarios/tests/test_scenarios.py79
4 files changed, 107 insertions, 24 deletions
diff --git a/README b/README
index d13172a..f18a027 100644
--- a/README
+++ b/README
@@ -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)