diff options
author | John Szakmeister <john@szakmeister.net> | 2014-02-17 10:42:47 -0500 |
---|---|---|
committer | John Szakmeister <john@szakmeister.net> | 2014-02-20 04:59:21 -0500 |
commit | b65c42fd4e8ade68a5db00d8f089cf3285bd127e (patch) | |
tree | 0dfc64116ed49b08c24837c053d72dea9fed1ab9 /functional_tests | |
parent | 129bd91e222a0ef973ea962eb539763748b54a84 (diff) | |
download | nose-b65c42fd4e8ade68a5db00d8f089cf3285bd127e.tar.gz |
Fix #771: attr plugin is broken when parent overrides child method
The issue is when the parent and child have different attributes, and
the parent method was being bypassed because of the attribute selection.
In this case, Nose would incorrectly use the version from the base
class, even though it was supposed to skip the method entirely.
To fix this, we need simply need to stop digging through base classes.
The dir() method returns a flattened set of methods, so there's no need
to iterate through the base classes trying to dig up all the methods.
Moreover, it leads to false positives since we were not keeping track of
methods seen on the parent classes. As a result, we'd incorrectly
select a test for inclusion (using attributes), or we'd pick up a method
that we should've ignored (like runTest in a Twisted test case).
Thanks to Thomas Grainger for providing a test case!
Diffstat (limited to 'functional_tests')
-rw-r--r-- | functional_tests/support/issue771/test.py | 16 | ||||
-rw-r--r-- | functional_tests/test_attribute_plugin.py | 14 | ||||
-rw-r--r-- | functional_tests/test_program.py | 12 |
3 files changed, 32 insertions, 10 deletions
diff --git a/functional_tests/support/issue771/test.py b/functional_tests/support/issue771/test.py new file mode 100644 index 0000000..a81eaa1 --- /dev/null +++ b/functional_tests/support/issue771/test.py @@ -0,0 +1,16 @@ +from nose.plugins.attrib import attr + +from unittest import TestCase + +@attr("b") +def test_b(): + assert 1 == 1 + +class TestBase(TestCase): + def test_a(self): + assert 1 == 1 + +class TestDerived(TestBase): + @attr("a") + def test_a(self): + assert 1 == 1 diff --git a/functional_tests/test_attribute_plugin.py b/functional_tests/test_attribute_plugin.py index a093cd5..249bec5 100644 --- a/functional_tests/test_attribute_plugin.py +++ b/functional_tests/test_attribute_plugin.py @@ -156,6 +156,20 @@ class TestClassAndMethodAttrs(AttributePluginTester): assert 'test_case_three' not in self.output +# Issue #771 +class TestTopLevelNotSelected(AttributePluginTester): + suitepath = os.path.join(support, 'issue771') + args = ["-a", "!a"] + + def verify(self): + # Note: a failure here may mean that the test case selection is broken + # rather than the attribute plugin, but the issue more easily manifests + # itself when using attributes. + assert 'test.test_b ... ok' in self.output + assert 'test_a (test.TestBase) ... ok' in self.output + assert 'TestDerived' not in self.output + + if compat_24: class TestAttributeEval(AttributePluginTester): args = ["-A", "c>20"] diff --git a/functional_tests/test_program.py b/functional_tests/test_program.py index b42b371..6ff600d 100644 --- a/functional_tests/test_program.py +++ b/functional_tests/test_program.py @@ -113,16 +113,8 @@ class TestTestProgram(unittest.TestCase): print "-----" print repr(res) - # some versions of twisted.trial.unittest.TestCase have - # runTest in the base class -- this is wrong! But we have - # to deal with it - if hasattr(TestCase, 'runTest'): - expect = 5 - else: - expect = 4 - self.assertEqual(res.testsRun, expect, - "Expected to run %s tests, ran %s" % - (expect, res.testsRun)) + self.assertEqual(res.testsRun, 4, + "Expected to run 4 tests, ran %s" % (res.testsRun,)) assert not res.wasSuccessful() assert len(res.errors) == 1 |