On Thu, Jul 8, 2010 at 07:59, Nick Coghlan <ncogh...@gmail.com> wrote: > On Thu, Jul 8, 2010 at 9:13 AM, Benjamin Peterson <benja...@python.org> wrote: >> 2010/7/7 Nick Coghlan <ncogh...@gmail.com>: >>> On Thu, Jul 8, 2010 at 7:56 AM, Michael Foord <fuzzy...@voidspace.org.uk> >>> wrote: >>>> Using a class decorator to duplicate each _test_ into two test_* methods >>>> sounds like a good approach. >>> >>> Note that parameterised methods have a similar problem to >>> parameterised modules - unittest results are reported in terms of >>> "testmodule.testclass.testfunction", so proper attribution of results >>> in the test output will require additional work. The separate >>> subclasses approach doesn't share this issue, since it changes the >>> value of the second item in accordance with the module under test. >> >> A good parameterized implementation, though, gives the repr() of the >> parameters in failure output. > > That would qualify as "additional work" if your tests aren't already > set up that way (and doesn't cover the case of unexpected exceptions > in a test, where the test method doesn't get to say much about the way > the error is reported). > > I realised during the day that my suggested approach was more > complicated than is actually necessary - once the existing tests have > been moved to a separate module, *that test module* can itself be > imported twice, once with the python version of the module to be > tested and once with the C version. You can then do some hackery to > distinguish the test classes without having to modify the test code > itself (note, the below code should work in theory, but isn't actually > tested): > > ============= > py_module_tests = support.import_fresh_module('moduletester', > fresh=['modulename'], blocked=['_modulename']) > c_module_tests = support.import_fresh_module('moduletester', > fresh=['modulename', '_modulename']) > > test_modules = [py_module_tests, c_module_tests] > suffixes = ["_Py", "_C"] > > for module, suffix in zip(test_modules, suffixes): > for obj in module.itervalues(): > if isinstance(obj, unittest,TestCase): > obj.__name__ += suffix > setattr(module, obj.__name__, obj) > > def test_main(): > for module in test_modules: > module.test_main() > =============
Very cool solution (assuming it works =) ! One issue I see with this is deciding how to organize tests that are specific to one version of a module compared to another. For instance, test_warnings has some tests specific to _warnings because of the hoops it has to jump through in order to get overriding showwarnings and friends to work. I guess I could try to make them generic enough that they don't require a specific module. Otherwise I would insert the module-specific tests into test_warnings to have that module also call gnostic_test_warnings to run the universal tests. _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com