diff options
author | Martin Pool <mbp@sourcefrog.net> | 2010-10-12 15:50:57 +1100 |
---|---|---|
committer | Martin Pool <mbp@sourcefrog.net> | 2010-10-12 15:50:57 +1100 |
commit | 977abd578ffa376be31e6382d4b0baab1c54ccef (patch) | |
tree | 016d3f96e73dda73e8bec77bf0158a9e21a3d92a | |
parent | 494fcff75bd2df7a42f14fee6d2f82f011f2da3f (diff) | |
download | testscenarios-977abd578ffa376be31e6382d4b0baab1c54ccef.tar.gz |
Add multiply_scenarios
-rw-r--r-- | README | 13 | ||||
-rw-r--r-- | lib/testscenarios/scenarios.py | 25 | ||||
-rw-r--r-- | lib/testscenarios/tests/test_scenarios.py | 30 |
3 files changed, 68 insertions, 0 deletions
@@ -267,3 +267,16 @@ Advice on Writing Scenarios If a parameterised test is because of a bug run without being parameterized, it should fail rather than running with defaults, because this can hide bugs. + + +Producing Scenarios +=================== + +The `multiply_scenarios` function produces the cross-product of the scenarios +passed in:: + + scenarios = multiply_scenarios( + vary_by_http_client(), + vary_by_http_protocol_version(), + ) + diff --git a/lib/testscenarios/scenarios.py b/lib/testscenarios/scenarios.py index 3cf8091..c284afd 100644 --- a/lib/testscenarios/scenarios.py +++ b/lib/testscenarios/scenarios.py @@ -22,6 +22,11 @@ __all__ = [ 'load_tests_apply_scenarios', ] + +from itertools import ( + chain, + product, + ) import unittest from testtools.testcase import clone_test_with_new_id @@ -104,3 +109,23 @@ def load_tests_apply_scenarios(*params): result = loader.suiteClass() result.addTests(generate_scenarios(standard_tests)) return result + + +def multiply_scenarios(*scenarios): + """Multiply two or more iterables of scenarios. + + It is safe to pass scenario generators or iterators. + + :returns: A list of compound scenarios: the cross-product of all + scenarios, with the names concatenated and the parameters + merged together. + """ + r = [] + scenario_lists = map(list, scenarios) + products = product(*scenario_lists) + for combo in products: + names, params = zip(*combo) + for p in params: + d.update(p.iteritems()) + r.append((','.join(names), d)) + return r diff --git a/lib/testscenarios/tests/test_scenarios.py b/lib/testscenarios/tests/test_scenarios.py index 97a2a6b..ecba25c 100644 --- a/lib/testscenarios/tests/test_scenarios.py +++ b/lib/testscenarios/tests/test_scenarios.py @@ -23,6 +23,7 @@ from testscenarios.scenarios import ( apply_scenarios, generate_scenarios, load_tests_apply_scenarios, + multiply_scenarios, ) import testtools from testtools.tests.helpers import LoggingResult @@ -211,3 +212,32 @@ class TestLoadTests(testtools.TestCase): 2, len(result_tests), result_tests) + + +class TestMultiplyScenarios(testtools.TestCase): + + def test_multiply_scenarios(self): + def s(name): + for i in 'ab': + yield i, {name: i} + r = list(multiply_scenarios(s('p'), s('q'))) + self.assertEquals([ + ('a,a', dict(p='a', q='a')), + ('a,b', dict(p='a', q='b')), + ('b,a', dict(p='b', q='a')), + ('b,b', dict(p='b', q='b')), + ], + r) + + def test_multiply_many_scenarios(self): + def s(name): + for i in 'abc': + yield i, {name: i} + r = list(multiply_scenarios(s('p'), s('q'), s('r'), s('t'))) + self.assertEqual( + 3**4, + len(r), + r) + self.assertEqual( + 'a,a,a,a', + r[0][0]) |