testtools-dev team mailing list archive
-
testtools-dev team
-
Mailing list archive
-
Message #00918
[Merge] lp:~jml/testtools/run-tests-on-their-own-826179 into lp:testtools
Jonathan Lange has proposed merging lp:~jml/testtools/run-tests-on-their-own-826179 into lp:testtools.
Requested reviews:
testtools committers (testtools-committers)
Related bugs:
Bug #826179 in testtools: "running some tests on their own fails"
https://bugs.launchpad.net/testtools/+bug/826179
For more details, see:
https://code.launchpad.net/~jml/testtools/run-tests-on-their-own-826179/+merge/71560
Here I take the second approach listed in my first bug comment on bug 826179: require an explicit run_tests_with = FullStackRunTest to see the full stack. This meets the debugging need expressed in bug 788974.
In some ways, this is better than the original solution, because not all tests in testtools need to see the full stack.
--
https://code.launchpad.net/~jml/testtools/run-tests-on-their-own-826179/+merge/71560
Your team testtools developers is subscribed to branch lp:testtools.
=== modified file 'doc/hacking.rst'
--- doc/hacking.rst 2011-07-01 16:50:27 +0000
+++ doc/hacking.rst 2011-08-15 13:56:22 +0000
@@ -44,6 +44,12 @@
You can run tests with ``make check``.
+By default, testtools hides many levels of its own stack when running tests.
+This is for the convenience of users, who do not care about how, say, assert
+methods are implemented. However, when writing tests for testtools itself, it
+is often useful to see all levels of the stack. To do this, add
+``run_tests_with = FullStackRunTest`` to the top of a test's class definition.
+
Documentation
-------------
@@ -71,18 +77,17 @@
Tests belong in ``testtools/tests/``.
-Commiting to trunk
-------------------
+Committing to trunk
+-------------------
Testtools is maintained using bzr, with its trunk at lp:testtools. This gives
every contributor the ability to commit their work to their own branches.
However permission must be granted to allow contributors to commit to the trunk
branch.
-Commit access to trunk is obtained by joining the testtools-devs Launchpad
-team. Membership in this team is contingent on obeying the testtools
-contribution policy, including assigning copyright of all the work one creates
-and places in trunk to Jonathan Lange.
+Commit access to trunk is obtained by joining the testtools-committers
+Launchpad team. Membership in this team is contingent on obeying the testtools
+contribution policy, see `Copyright Assignment`_ above.
Code Review
@@ -93,7 +98,7 @@
be reviewed before it can be merged to trunk. It will be reviewed by someone:
* not the author
-* a committer (member of the `~testtools-dev`_ team)
+* a committer (member of the `~testtools-committers`_ team)
As a special exception, while the testtools committers team is small and prone
to blocking, a merge request from a committer that has not been reviewed after
=== modified file 'testtools/tests/__init__.py'
--- testtools/tests/__init__.py 2011-07-31 13:51:04 +0000
+++ testtools/tests/__init__.py 2011-08-15 13:56:22 +0000
@@ -4,19 +4,6 @@
from unittest import TestSuite
-from testtools.tests.helpers import hide_testtools_stack
-
-
-class FullStackTestSuite(TestSuite):
- """A version of TestSuite that guarantees full stack is shown."""
-
- def run(self, result):
- was_hidden = hide_testtools_stack(False)
- try:
- return super(FullStackTestSuite, self).run(result)
- finally:
- hide_testtools_stack(was_hidden)
-
def test_suite():
from testtools.tests import (
@@ -54,4 +41,4 @@
test_testsuite,
]
suites = map(lambda x: x.test_suite(), modules)
- return FullStackTestSuite(suites)
+ return TestSuite(suites)
=== modified file 'testtools/tests/helpers.py'
--- testtools/tests/helpers.py 2011-07-29 17:49:41 +0000
+++ testtools/tests/helpers.py 2011-08-15 13:56:22 +0000
@@ -102,3 +102,10 @@
return f(*args, **kwargs)
finally:
hide_testtools_stack(old_should_hide)
+
+
+
+class FullStackRunTest(runtest.RunTest):
+
+ def _run_user(self, fn, *args, **kwargs):
+ return run_with_stack_hidden(False, fn, *args, **kwargs)
=== modified file 'testtools/tests/test_helpers.py'
--- testtools/tests/test_helpers.py 2011-07-29 17:49:41 +0000
+++ testtools/tests/test_helpers.py 2011-08-15 13:56:22 +0000
@@ -13,6 +13,7 @@
Not,
)
from testtools.tests.helpers import (
+ FullStackRunTest,
hide_testtools_stack,
is_stack_hidden,
safe_hasattr,
@@ -212,6 +213,8 @@
testtools.testcase,
]
+ run_tests_with = FullStackRunTest
+
def setUp(self):
super(TestStackHiding, self).setUp()
self.addCleanup(hide_testtools_stack, is_stack_hidden())
=== modified file 'testtools/tests/test_matchers.py'
--- testtools/tests/test_matchers.py 2011-08-15 13:22:29 +0000
+++ testtools/tests/test_matchers.py 2011-08-15 13:56:22 +0000
@@ -45,6 +45,7 @@
raises,
StartsWith,
)
+from testtools.tests.helpers import FullStackRunTest
# Silence pyflakes.
Matcher
@@ -52,6 +53,8 @@
class TestMismatch(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_constructor_arguments(self):
mismatch = Mismatch("some description", {'detail': "things"})
self.assertEqual("some description", mismatch.describe())
@@ -66,6 +69,8 @@
class TestMatchersInterface(object):
+ run_tests_with = FullStackRunTest
+
def test_matches_match(self):
matcher = self.matches_matcher
matches = self.matches_matches
@@ -134,6 +139,8 @@
class TestDocTestMatchesSpecific(TestCase):
+ run_tests_with = FullStackRunTest
+
def test___init__simple(self):
matcher = DocTestMatches("foo")
self.assertEqual("foo\n", matcher.want)
@@ -447,6 +454,8 @@
class TestAnnotatedMismatch(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_forwards_details(self):
x = Mismatch('description', {'foo': 'bar'})
annotated = AnnotatedMismatch("annotation", x)
@@ -488,6 +497,8 @@
class TestRaisesBaseTypes(TestCase):
+ run_tests_with = FullStackRunTest
+
def raiser(self):
raise KeyboardInterrupt('foo')
@@ -521,6 +532,8 @@
class TestRaisesConvenience(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_exc_type(self):
self.assertThat(lambda: 1/0, raises(ZeroDivisionError))
@@ -533,6 +546,8 @@
class DoesNotStartWithTests(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_describe(self):
mismatch = DoesNotStartWith("fo", "bo")
self.assertEqual("'fo' does not start with 'bo'.", mismatch.describe())
@@ -540,6 +555,8 @@
class StartsWithTests(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_str(self):
matcher = StartsWith("bar")
self.assertEqual("Starts with 'bar'.", str(matcher))
@@ -565,6 +582,8 @@
class DoesNotEndWithTests(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_describe(self):
mismatch = DoesNotEndWith("fo", "bo")
self.assertEqual("'fo' does not end with 'bo'.", mismatch.describe())
@@ -572,6 +591,8 @@
class EndsWithTests(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_str(self):
matcher = EndsWith("bar")
self.assertEqual("Ends with 'bar'.", str(matcher))
@@ -607,6 +628,8 @@
class TestMatchesListwise(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_docstring(self):
failure_count, output = run_doctest(
MatchesListwise, "MatchesListwise")
@@ -699,6 +722,8 @@
class TestMatchesSetwise(TestCase):
+ run_tests_with = FullStackRunTest
+
def assertMismatchWithDescriptionMatching(self, value, matcher,
description_matcher):
mismatch = matcher.match(value)
@@ -797,6 +822,8 @@
class TestMismatchDecorator(TestCase):
+ run_tests_with = FullStackRunTest
+
def test_forwards_description(self):
x = Mismatch("description", {'foo': 'bar'})
decorated = MismatchDecorator(x)
=== modified file 'testtools/tests/test_runtest.py'
--- testtools/tests/test_runtest.py 2011-07-20 09:42:09 +0000
+++ testtools/tests/test_runtest.py 2011-08-15 13:56:22 +0000
@@ -11,10 +11,13 @@
)
from testtools.matchers import MatchesException, Is, Raises
from testtools.testresult.doubles import ExtendedTestResult
+from testtools.tests.helpers import FullStackRunTest
class TestRunTest(TestCase):
+ run_tests_with = FullStackRunTest
+
def make_case(self):
class Case(TestCase):
def test(self):
=== modified file 'testtools/tests/test_testcase.py'
--- testtools/tests/test_testcase.py 2011-08-15 13:22:29 +0000
+++ testtools/tests/test_testcase.py 2011-08-15 13:56:22 +0000
@@ -34,6 +34,7 @@
)
from testtools.tests.helpers import (
an_exc_info,
+ FullStackRunTest,
LoggingResult,
)
try:
@@ -46,6 +47,8 @@
class TestPlaceHolder(TestCase):
+ run_test_with = FullStackRunTest
+
def makePlaceHolder(self, test_id="foo", short_description=None):
return PlaceHolder(test_id, short_description)
@@ -120,6 +123,8 @@
class TestErrorHolder(TestCase):
+ run_test_with = FullStackRunTest
+
def makeException(self):
try:
raise RuntimeError("danger danger")
@@ -208,6 +213,8 @@
class TestEquality(TestCase):
"""Test ``TestCase``'s equality implementation."""
+ run_test_with = FullStackRunTest
+
def test_identicalIsEqual(self):
# TestCase's are equal if they are identical.
self.assertEqual(self, self)
@@ -221,6 +228,8 @@
class TestAssertions(TestCase):
"""Test assertions in TestCase."""
+ run_test_with = FullStackRunTest
+
def raiseError(self, exceptionFactory, *args, **kwargs):
raise exceptionFactory(*args, **kwargs)
@@ -527,6 +536,8 @@
class TestAddCleanup(TestCase):
"""Tests for TestCase.addCleanup."""
+ run_test_with = FullStackRunTest
+
class LoggingTest(TestCase):
"""A test that logs calls to setUp, runTest and tearDown."""
@@ -692,6 +703,8 @@
class TestWithDetails(TestCase):
+ run_test_with = FullStackRunTest
+
def assertDetailsProvided(self, case, expected_outcome, expected_keys):
"""Assert that when case is run, details are provided to the result.
@@ -724,6 +737,8 @@
class TestExpectedFailure(TestWithDetails):
"""Tests for expected failures and unexpected successess."""
+ run_test_with = FullStackRunTest
+
def make_unexpected_case(self):
class Case(TestCase):
def test(self):
@@ -787,6 +802,8 @@
class TestUniqueFactories(TestCase):
"""Tests for getUniqueString and getUniqueInteger."""
+ run_test_with = FullStackRunTest
+
def test_getUniqueInteger(self):
# getUniqueInteger returns an integer that increments each time you
# call it.
@@ -815,6 +832,8 @@
class TestCloneTestWithNewId(TestCase):
"""Tests for clone_test_with_new_id."""
+ run_test_with = FullStackRunTest
+
def test_clone_test_with_new_id(self):
class FooTestCase(TestCase):
def test_foo(self):
@@ -842,6 +861,8 @@
class TestDetailsProvided(TestWithDetails):
+ run_test_with = FullStackRunTest
+
def test_addDetail(self):
mycontent = self.get_content()
self.addDetail("foo", mycontent)
@@ -945,6 +966,8 @@
class TestSetupTearDown(TestCase):
+ run_test_with = FullStackRunTest
+
def test_setUpNotCalled(self):
class DoesnotcallsetUp(TestCase):
def setUp(self):
@@ -969,6 +992,8 @@
class TestSkipping(TestCase):
"""Tests for skipping of tests functionality."""
+ run_test_with = FullStackRunTest
+
def test_skip_causes_skipException(self):
self.assertThat(lambda:self.skip("Skip this test"),
Raises(MatchesException(self.skipException)))
@@ -1070,6 +1095,8 @@
class TestOnException(TestCase):
+ run_test_with = FullStackRunTest
+
def test_default_works(self):
events = []
class Case(TestCase):
@@ -1104,6 +1131,8 @@
class TestPatchSupport(TestCase):
+ run_test_with = FullStackRunTest
+
class Case(TestCase):
def test(self):
pass
@@ -1161,6 +1190,9 @@
class TestTestCaseSuper(TestCase):
+
+ run_test_with = FullStackRunTest
+
def test_setup_uses_super(self):
class OtherBaseCase(unittest.TestCase):
setup_called = False
=== modified file 'testtools/tests/test_testresult.py'
--- testtools/tests/test_testresult.py 2011-07-29 17:49:41 +0000
+++ testtools/tests/test_testresult.py 2011-08-15 13:56:22 +0000
@@ -45,6 +45,7 @@
)
from testtools.tests.helpers import (
an_exc_info,
+ FullStackRunTest,
LoggingResult,
run_with_stack_hidden,
)
@@ -266,24 +267,32 @@
class TestTestResultContract(TestCase, StartTestRunContract):
+ run_test_with = FullStackRunTest
+
def makeResult(self):
return TestResult()
class TestMultiTestResultContract(TestCase, StartTestRunContract):
+ run_test_with = FullStackRunTest
+
def makeResult(self):
return MultiTestResult(TestResult(), TestResult())
class TestTextTestResultContract(TestCase, StartTestRunContract):
+ run_test_with = FullStackRunTest
+
def makeResult(self):
return TextTestResult(StringIO())
class TestThreadSafeForwardingResultContract(TestCase, StartTestRunContract):
+ run_test_with = FullStackRunTest
+
def makeResult(self):
result_semaphore = threading.Semaphore(1)
target = TestResult()
@@ -323,6 +332,8 @@
class TestTestResult(TestCase):
"""Tests for 'TestResult'."""
+ run_tests_with = FullStackRunTest
+
def makeResult(self):
"""Make an arbitrary result for testing."""
return TestResult()
Follow ups