summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2009-03-08 15:08:51 +1100
committerRobert Collins <robertc@robertcollins.net>2009-03-08 15:08:51 +1100
commit50d71aaaf387ad7dc259eb291d2860a0b946fd8c (patch)
tree0fbe4c89aa858130419ea4fa3c9594a6037e49c3
parentef3a10eaef1ac7140beaa154cf0bf9dbc0e76306 (diff)
downloadtestscenarios-git-50d71aaaf387ad7dc259eb291d2860a0b946fd8c.tar.gz
Write generate_scenarios.
-rw-r--r--lib/testscenarios/__init__.py6
-rw-r--r--lib/testscenarios/scenarios.py50
-rw-r--r--lib/testscenarios/testcase.py11
-rw-r--r--lib/testscenarios/tests/__init__.py1
-rw-r--r--lib/testscenarios/tests/test_scenarios.py100
5 files changed, 161 insertions, 7 deletions
diff --git a/lib/testscenarios/__init__.py b/lib/testscenarios/__init__.py
index 57b49b4..4e0bf5d 100644
--- a/lib/testscenarios/__init__.py
+++ b/lib/testscenarios/__init__.py
@@ -29,9 +29,15 @@ See the README for a manual, and the docstrings on individual functions and
methods for details.
"""
+__all__ = [
+ 'TestWithScenarios',
+ 'generate_scenarios',
+ ]
+
import unittest
+from testscenarios.scenarios import generate_scenarios
from testscenarios.testcase import TestWithScenarios
diff --git a/lib/testscenarios/scenarios.py b/lib/testscenarios/scenarios.py
new file mode 100644
index 0000000..bbc73ad
--- /dev/null
+++ b/lib/testscenarios/scenarios.py
@@ -0,0 +1,50 @@
+# testscenarios: extensions to python unittest to allow declarative
+# dependency injection ('scenarios') by tests.
+# Copyright (C) 2009 Robert Collins <robertc@robertcollins.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+__all__ = [
+ 'generate_scenarios',
+ ]
+
+import unittest
+
+from testtools.testcase import clone_test_with_new_id
+from testtools import iterate_tests
+
+def generate_scenarios(test_or_suite):
+ """Yield the tests in test_or_suite with scenario multiplication done.
+
+ TestCase objects with no scenarios specified are yielded unaltered. Tests
+ with scenarios are not yielded at all, instead the results of multiplying
+ them by the scenarios they specified gets yielded.
+
+ :param test_or_suite: A TestCase or TestSuite.
+ :return: A generator of tests - objects satisfying the TestCase protocol.
+ """
+ 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 + ')')
+ newtest.scenarios = None
+ for key, value in parameters.iteritems():
+ setattr(newtest, key, value)
+ yield newtest
+ else:
+ yield test
diff --git a/lib/testscenarios/testcase.py b/lib/testscenarios/testcase.py
index ec27e39..712d543 100644
--- a/lib/testscenarios/testcase.py
+++ b/lib/testscenarios/testcase.py
@@ -25,6 +25,8 @@ import unittest
from testtools.testcase import clone_test_with_new_id
+from testscenarios.scenarios import generate_scenarios
+
class TestWithScenarios(unittest.TestCase):
"""A TestCase with support for scenarios via a scenarios attribute.
@@ -38,13 +40,8 @@ class TestWithScenarios(unittest.TestCase):
def run(self, result=None):
scenarios = getattr(self, 'scenarios', None)
if scenarios:
- for name, parameters in scenarios:
- newtest = clone_test_with_new_id(self,
- self.id() + '(' + name + ')')
- newtest.scenarios = None
- for key, value in parameters.iteritems():
- setattr(newtest, key, value)
- newtest.run(result)
+ for test in generate_scenarios(self):
+ test.run(result)
return
else:
return super(TestWithScenarios, self).run(result)
diff --git a/lib/testscenarios/tests/__init__.py b/lib/testscenarios/tests/__init__.py
index 1777e74..9bce8a3 100644
--- a/lib/testscenarios/tests/__init__.py
+++ b/lib/testscenarios/tests/__init__.py
@@ -34,6 +34,7 @@ def test_suite():
def load_tests(standard_tests, module, loader):
test_modules = [
'testcase',
+ 'scenarios',
]
prefix = "testscenarios.tests.test_"
test_mod_names = [prefix + test_module for test_module in test_modules]
diff --git a/lib/testscenarios/tests/test_scenarios.py b/lib/testscenarios/tests/test_scenarios.py
new file mode 100644
index 0000000..b019d97
--- /dev/null
+++ b/lib/testscenarios/tests/test_scenarios.py
@@ -0,0 +1,100 @@
+# testscenarios: extensions to python unittest to allow declarative
+# dependency injection ('scenarios') by tests.
+# Copyright (C) 2009 Robert Collins <robertc@robertcollins.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+import unittest
+
+import testscenarios
+from testscenarios.scenarios import generate_scenarios
+from testtools.tests.helpers import LoggingResult
+
+
+class TestGenerateScenarios(unittest.TestCase):
+
+ def test_generate_scenarios_preserves_normal_test(self):
+ class ReferenceTest(unittest.TestCase):
+ def test_pass(self):
+ pass
+ test = ReferenceTest("test_pass")
+ self.assertEqual([test], list(generate_scenarios(test)))
+
+ def test_normal_test_with_one_scenario(self):
+ class ReferenceTest(unittest.TestCase):
+ scenarios = [('demo', {})]
+ def test_pass(self):
+ pass
+ test = ReferenceTest("test_pass")
+ tests = list(generate_scenarios(test))
+ self.assertEqual(
+ 'testscenarios.tests.test_scenarios.ReferenceTest.test_pass(demo)',
+ tests[0].id())
+
+ def test_normal_test_two_scenarios(self):
+ class ReferenceTest(unittest.TestCase):
+ scenarios = [('1', {}), ('2', {})]
+ def test_pass(self):
+ pass
+ test = ReferenceTest("test_pass")
+ tests = list(generate_scenarios(test))
+ self.assertEqual(
+ 'testscenarios.tests.test_scenarios.ReferenceTest.test_pass(1)',
+ tests[0].id())
+ self.assertEqual(
+ '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 = [
+ ('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))
+ for adapted in tests:
+ self.assertEqual(None, adapted.scenarios)
+
+ def test_multiple_tests(self):
+ class Reference1(unittest.TestCase):
+ scenarios = [('1', {}), ('2', {})]
+ def test_something(self):
+ pass
+ class Reference2(unittest.TestCase):
+ scenarios = [('3', {}), ('4', {})]
+ def test_something(self):
+ pass
+ suite = unittest.TestSuite()
+ suite.addTest(Reference1("test_something"))
+ suite.addTest(Reference2("test_something"))
+ tests = list(generate_scenarios(suite))
+ self.assertEqual(4, len(tests))