summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2012-04-04 22:02:46 +1200
committerRobert Collins <robertc@robertcollins.net>2012-04-04 22:02:46 +1200
commit45564bb7c1ee43448c09f72097988756ff56e8fc (patch)
treebdc9b6527007c760b5e1a3d767b293493bf413e6 /lib
parente1339ea008f571b21ad13c5d69926ed6d66bb290 (diff)
parentda26369a7f2c602587f01f122a79e0903815f78e (diff)
downloadtestscenarios-45564bb7c1ee43448c09f72097988756ff56e8fc.tar.gz
* New function ``per_module_scenarios`` for tests that should be applied across
multiple modules providing the same interface, some of which may not be available at run time. (Martin Pool, Robert Collins)
Diffstat (limited to 'lib')
-rw-r--r--lib/testscenarios/scenarios.py37
-rw-r--r--lib/testscenarios/tests/__init__.py3
-rw-r--r--lib/testscenarios/tests/test_scenarios.py22
3 files changed, 59 insertions, 3 deletions
diff --git a/lib/testscenarios/scenarios.py b/lib/testscenarios/scenarios.py
index 80847d6..9538b33 100644
--- a/lib/testscenarios/scenarios.py
+++ b/lib/testscenarios/scenarios.py
@@ -2,7 +2,7 @@
# dependency injection ('scenarios') by tests.
#
# Copyright (c) 2009, Robert Collins <robertc@robertcollins.net>
-# Copyright (c) 2010 Martin Pool <mbp@sourcefrog.net>
+# Copyright (c) 2010, 2011 Martin Pool <mbp@sourcefrog.net>
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
@@ -27,6 +27,7 @@ from itertools import (
chain,
product,
)
+import sys
import unittest
from testtools.testcase import clone_test_with_new_id
@@ -129,3 +130,37 @@ def multiply_scenarios(*scenarios):
scenario_parameters.update(parameter)
result.append((scenario_name, scenario_parameters))
return result
+
+
+def per_module_scenarios(attribute_name, modules):
+ """Generate scenarios for available implementation modules.
+
+ This is typically used when there is a subsystem implemented, for
+ example, in both Python and C, and we want to apply the same tests to
+ both, but the C module may sometimes not be available.
+
+ Note: if the module can't be loaded, the sys.exc_info() tuple for the
+ exception raised during import of the module is used instead of the module
+ object. A common idiom is to check in setUp for that and raise a skip or
+ error for that case. No special helpers are supplied in testscenarios as
+ yet.
+
+ :param attribute_name: A name to be set in the scenario parameter
+ dictionary (and thence onto the test instance) pointing to the
+ implementation module (or import exception) for this scenario.
+
+ :param modules: An iterable of (short_name, module_name), where
+ the short name is something like 'python' to put in the
+ scenario name, and the long name is a fully-qualified Python module
+ name.
+ """
+ scenarios = []
+ for short_name, module_name in modules:
+ try:
+ mod = __import__(module_name, {}, {}, [''])
+ except:
+ mod = sys.exc_info()
+ scenarios.append((
+ short_name,
+ {attribute_name: mod}))
+ return scenarios
diff --git a/lib/testscenarios/tests/__init__.py b/lib/testscenarios/tests/__init__.py
index e5e2bbe..6230212 100644
--- a/lib/testscenarios/tests/__init__.py
+++ b/lib/testscenarios/tests/__init__.py
@@ -38,5 +38,6 @@ def load_tests(standard_tests, module, loader):
test_mod_names = [prefix + test_module for test_module in test_modules]
standard_tests.addTests(loader.loadTestsFromNames(test_mod_names))
doctest.set_unittest_reportflags(doctest.REPORT_ONLY_FIRST_FAILURE)
- standard_tests.addTest(doctest.DocFileSuite("../../../README"))
+ standard_tests.addTest(
+ doctest.DocFileSuite("../../../README", optionflags=doctest.ELLIPSIS))
return standard_tests
diff --git a/lib/testscenarios/tests/test_scenarios.py b/lib/testscenarios/tests/test_scenarios.py
index 063df51..97aa17f 100644
--- a/lib/testscenarios/tests/test_scenarios.py
+++ b/lib/testscenarios/tests/test_scenarios.py
@@ -2,7 +2,7 @@
# dependency injection ('scenarios') by tests.
#
# Copyright (c) 2009, Robert Collins <robertc@robertcollins.net>
-# Copyright (c) 2010 Martin Pool <mbp@sourcefrog.net>
+# Copyright (c) 2010, 2011 Martin Pool <mbp@sourcefrog.net>
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
@@ -239,3 +239,23 @@ class TestMultiplyScenarios(testtools.TestCase):
self.assertEqual(
'a,a,a,a',
scenarios[0][0])
+
+
+class TestPerModuleScenarios(testtools.TestCase):
+
+ def test_per_module_scenarios(self):
+ """Generate scenarios for available modules"""
+ s = testscenarios.scenarios.per_module_scenarios(
+ 'the_module', [
+ ('Python', 'testscenarios'),
+ ('unittest', 'unittest'),
+ ('nonexistent', 'nonexistent'),
+ ])
+ self.assertEqual('nonexistent', s[-1][0])
+ self.assertIsInstance(s[-1][1]['the_module'], tuple)
+ s[-1][1]['the_module'] = None
+ self.assertEqual(s, [
+ ('Python', {'the_module': testscenarios}),
+ ('unittest', {'the_module': unittest}),
+ ('nonexistent', {'the_module': None}),
+ ])