Merge lp:~jml/testtools/run-tests-on-their-own-826179 into lp:~testtools-committers/testtools/trunk

Proposed by Jonathan Lange
Status: Merged
Merged at revision: 228
Proposed branch: lp:~jml/testtools/run-tests-on-their-own-826179
Merge into: lp:~testtools-committers/testtools/trunk
Diff against target: 464 lines (+96/-21)
8 files modified
doc/hacking.rst (+12/-7)
testtools/tests/__init__.py (+1/-14)
testtools/tests/helpers.py (+7/-0)
testtools/tests/test_helpers.py (+3/-0)
testtools/tests/test_matchers.py (+27/-0)
testtools/tests/test_runtest.py (+3/-0)
testtools/tests/test_testcase.py (+32/-0)
testtools/tests/test_testresult.py (+11/-0)
To merge this branch: bzr merge lp:~jml/testtools/run-tests-on-their-own-826179
Reviewer Review Type Date Requested Status
testtools committers Pending
Review via email: mp+71560@code.launchpad.net

Description of the change

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.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

+1

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/hacking.rst'
2--- doc/hacking.rst 2011-07-01 16:50:27 +0000
3+++ doc/hacking.rst 2011-08-15 13:56:22 +0000
4@@ -44,6 +44,12 @@
5
6 You can run tests with ``make check``.
7
8+By default, testtools hides many levels of its own stack when running tests.
9+This is for the convenience of users, who do not care about how, say, assert
10+methods are implemented. However, when writing tests for testtools itself, it
11+is often useful to see all levels of the stack. To do this, add
12+``run_tests_with = FullStackRunTest`` to the top of a test's class definition.
13+
14
15 Documentation
16 -------------
17@@ -71,18 +77,17 @@
18 Tests belong in ``testtools/tests/``.
19
20
21-Commiting to trunk
22-------------------
23+Committing to trunk
24+-------------------
25
26 Testtools is maintained using bzr, with its trunk at lp:testtools. This gives
27 every contributor the ability to commit their work to their own branches.
28 However permission must be granted to allow contributors to commit to the trunk
29 branch.
30
31-Commit access to trunk is obtained by joining the testtools-devs Launchpad
32-team. Membership in this team is contingent on obeying the testtools
33-contribution policy, including assigning copyright of all the work one creates
34-and places in trunk to Jonathan Lange.
35+Commit access to trunk is obtained by joining the testtools-committers
36+Launchpad team. Membership in this team is contingent on obeying the testtools
37+contribution policy, see `Copyright Assignment`_ above.
38
39
40 Code Review
41@@ -93,7 +98,7 @@
42 be reviewed before it can be merged to trunk. It will be reviewed by someone:
43
44 * not the author
45-* a committer (member of the `~testtools-dev`_ team)
46+* a committer (member of the `~testtools-committers`_ team)
47
48 As a special exception, while the testtools committers team is small and prone
49 to blocking, a merge request from a committer that has not been reviewed after
50
51=== modified file 'testtools/tests/__init__.py'
52--- testtools/tests/__init__.py 2011-07-31 13:51:04 +0000
53+++ testtools/tests/__init__.py 2011-08-15 13:56:22 +0000
54@@ -4,19 +4,6 @@
55
56 from unittest import TestSuite
57
58-from testtools.tests.helpers import hide_testtools_stack
59-
60-
61-class FullStackTestSuite(TestSuite):
62- """A version of TestSuite that guarantees full stack is shown."""
63-
64- def run(self, result):
65- was_hidden = hide_testtools_stack(False)
66- try:
67- return super(FullStackTestSuite, self).run(result)
68- finally:
69- hide_testtools_stack(was_hidden)
70-
71
72 def test_suite():
73 from testtools.tests import (
74@@ -54,4 +41,4 @@
75 test_testsuite,
76 ]
77 suites = map(lambda x: x.test_suite(), modules)
78- return FullStackTestSuite(suites)
79+ return TestSuite(suites)
80
81=== modified file 'testtools/tests/helpers.py'
82--- testtools/tests/helpers.py 2011-07-29 17:49:41 +0000
83+++ testtools/tests/helpers.py 2011-08-15 13:56:22 +0000
84@@ -102,3 +102,10 @@
85 return f(*args, **kwargs)
86 finally:
87 hide_testtools_stack(old_should_hide)
88+
89+
90+
91+class FullStackRunTest(runtest.RunTest):
92+
93+ def _run_user(self, fn, *args, **kwargs):
94+ return run_with_stack_hidden(False, fn, *args, **kwargs)
95
96=== modified file 'testtools/tests/test_helpers.py'
97--- testtools/tests/test_helpers.py 2011-07-29 17:49:41 +0000
98+++ testtools/tests/test_helpers.py 2011-08-15 13:56:22 +0000
99@@ -13,6 +13,7 @@
100 Not,
101 )
102 from testtools.tests.helpers import (
103+ FullStackRunTest,
104 hide_testtools_stack,
105 is_stack_hidden,
106 safe_hasattr,
107@@ -212,6 +213,8 @@
108 testtools.testcase,
109 ]
110
111+ run_tests_with = FullStackRunTest
112+
113 def setUp(self):
114 super(TestStackHiding, self).setUp()
115 self.addCleanup(hide_testtools_stack, is_stack_hidden())
116
117=== modified file 'testtools/tests/test_matchers.py'
118--- testtools/tests/test_matchers.py 2011-08-15 13:22:29 +0000
119+++ testtools/tests/test_matchers.py 2011-08-15 13:56:22 +0000
120@@ -45,6 +45,7 @@
121 raises,
122 StartsWith,
123 )
124+from testtools.tests.helpers import FullStackRunTest
125
126 # Silence pyflakes.
127 Matcher
128@@ -52,6 +53,8 @@
129
130 class TestMismatch(TestCase):
131
132+ run_tests_with = FullStackRunTest
133+
134 def test_constructor_arguments(self):
135 mismatch = Mismatch("some description", {'detail': "things"})
136 self.assertEqual("some description", mismatch.describe())
137@@ -66,6 +69,8 @@
138
139 class TestMatchersInterface(object):
140
141+ run_tests_with = FullStackRunTest
142+
143 def test_matches_match(self):
144 matcher = self.matches_matcher
145 matches = self.matches_matches
146@@ -134,6 +139,8 @@
147
148 class TestDocTestMatchesSpecific(TestCase):
149
150+ run_tests_with = FullStackRunTest
151+
152 def test___init__simple(self):
153 matcher = DocTestMatches("foo")
154 self.assertEqual("foo\n", matcher.want)
155@@ -447,6 +454,8 @@
156
157 class TestAnnotatedMismatch(TestCase):
158
159+ run_tests_with = FullStackRunTest
160+
161 def test_forwards_details(self):
162 x = Mismatch('description', {'foo': 'bar'})
163 annotated = AnnotatedMismatch("annotation", x)
164@@ -488,6 +497,8 @@
165
166 class TestRaisesBaseTypes(TestCase):
167
168+ run_tests_with = FullStackRunTest
169+
170 def raiser(self):
171 raise KeyboardInterrupt('foo')
172
173@@ -521,6 +532,8 @@
174
175 class TestRaisesConvenience(TestCase):
176
177+ run_tests_with = FullStackRunTest
178+
179 def test_exc_type(self):
180 self.assertThat(lambda: 1/0, raises(ZeroDivisionError))
181
182@@ -533,6 +546,8 @@
183
184 class DoesNotStartWithTests(TestCase):
185
186+ run_tests_with = FullStackRunTest
187+
188 def test_describe(self):
189 mismatch = DoesNotStartWith("fo", "bo")
190 self.assertEqual("'fo' does not start with 'bo'.", mismatch.describe())
191@@ -540,6 +555,8 @@
192
193 class StartsWithTests(TestCase):
194
195+ run_tests_with = FullStackRunTest
196+
197 def test_str(self):
198 matcher = StartsWith("bar")
199 self.assertEqual("Starts with 'bar'.", str(matcher))
200@@ -565,6 +582,8 @@
201
202 class DoesNotEndWithTests(TestCase):
203
204+ run_tests_with = FullStackRunTest
205+
206 def test_describe(self):
207 mismatch = DoesNotEndWith("fo", "bo")
208 self.assertEqual("'fo' does not end with 'bo'.", mismatch.describe())
209@@ -572,6 +591,8 @@
210
211 class EndsWithTests(TestCase):
212
213+ run_tests_with = FullStackRunTest
214+
215 def test_str(self):
216 matcher = EndsWith("bar")
217 self.assertEqual("Ends with 'bar'.", str(matcher))
218@@ -607,6 +628,8 @@
219
220 class TestMatchesListwise(TestCase):
221
222+ run_tests_with = FullStackRunTest
223+
224 def test_docstring(self):
225 failure_count, output = run_doctest(
226 MatchesListwise, "MatchesListwise")
227@@ -699,6 +722,8 @@
228
229 class TestMatchesSetwise(TestCase):
230
231+ run_tests_with = FullStackRunTest
232+
233 def assertMismatchWithDescriptionMatching(self, value, matcher,
234 description_matcher):
235 mismatch = matcher.match(value)
236@@ -797,6 +822,8 @@
237
238 class TestMismatchDecorator(TestCase):
239
240+ run_tests_with = FullStackRunTest
241+
242 def test_forwards_description(self):
243 x = Mismatch("description", {'foo': 'bar'})
244 decorated = MismatchDecorator(x)
245
246=== modified file 'testtools/tests/test_runtest.py'
247--- testtools/tests/test_runtest.py 2011-07-20 09:42:09 +0000
248+++ testtools/tests/test_runtest.py 2011-08-15 13:56:22 +0000
249@@ -11,10 +11,13 @@
250 )
251 from testtools.matchers import MatchesException, Is, Raises
252 from testtools.testresult.doubles import ExtendedTestResult
253+from testtools.tests.helpers import FullStackRunTest
254
255
256 class TestRunTest(TestCase):
257
258+ run_tests_with = FullStackRunTest
259+
260 def make_case(self):
261 class Case(TestCase):
262 def test(self):
263
264=== modified file 'testtools/tests/test_testcase.py'
265--- testtools/tests/test_testcase.py 2011-08-15 13:22:29 +0000
266+++ testtools/tests/test_testcase.py 2011-08-15 13:56:22 +0000
267@@ -34,6 +34,7 @@
268 )
269 from testtools.tests.helpers import (
270 an_exc_info,
271+ FullStackRunTest,
272 LoggingResult,
273 )
274 try:
275@@ -46,6 +47,8 @@
276
277 class TestPlaceHolder(TestCase):
278
279+ run_test_with = FullStackRunTest
280+
281 def makePlaceHolder(self, test_id="foo", short_description=None):
282 return PlaceHolder(test_id, short_description)
283
284@@ -120,6 +123,8 @@
285
286 class TestErrorHolder(TestCase):
287
288+ run_test_with = FullStackRunTest
289+
290 def makeException(self):
291 try:
292 raise RuntimeError("danger danger")
293@@ -208,6 +213,8 @@
294 class TestEquality(TestCase):
295 """Test ``TestCase``'s equality implementation."""
296
297+ run_test_with = FullStackRunTest
298+
299 def test_identicalIsEqual(self):
300 # TestCase's are equal if they are identical.
301 self.assertEqual(self, self)
302@@ -221,6 +228,8 @@
303 class TestAssertions(TestCase):
304 """Test assertions in TestCase."""
305
306+ run_test_with = FullStackRunTest
307+
308 def raiseError(self, exceptionFactory, *args, **kwargs):
309 raise exceptionFactory(*args, **kwargs)
310
311@@ -527,6 +536,8 @@
312 class TestAddCleanup(TestCase):
313 """Tests for TestCase.addCleanup."""
314
315+ run_test_with = FullStackRunTest
316+
317 class LoggingTest(TestCase):
318 """A test that logs calls to setUp, runTest and tearDown."""
319
320@@ -692,6 +703,8 @@
321
322 class TestWithDetails(TestCase):
323
324+ run_test_with = FullStackRunTest
325+
326 def assertDetailsProvided(self, case, expected_outcome, expected_keys):
327 """Assert that when case is run, details are provided to the result.
328
329@@ -724,6 +737,8 @@
330 class TestExpectedFailure(TestWithDetails):
331 """Tests for expected failures and unexpected successess."""
332
333+ run_test_with = FullStackRunTest
334+
335 def make_unexpected_case(self):
336 class Case(TestCase):
337 def test(self):
338@@ -787,6 +802,8 @@
339 class TestUniqueFactories(TestCase):
340 """Tests for getUniqueString and getUniqueInteger."""
341
342+ run_test_with = FullStackRunTest
343+
344 def test_getUniqueInteger(self):
345 # getUniqueInteger returns an integer that increments each time you
346 # call it.
347@@ -815,6 +832,8 @@
348 class TestCloneTestWithNewId(TestCase):
349 """Tests for clone_test_with_new_id."""
350
351+ run_test_with = FullStackRunTest
352+
353 def test_clone_test_with_new_id(self):
354 class FooTestCase(TestCase):
355 def test_foo(self):
356@@ -842,6 +861,8 @@
357
358 class TestDetailsProvided(TestWithDetails):
359
360+ run_test_with = FullStackRunTest
361+
362 def test_addDetail(self):
363 mycontent = self.get_content()
364 self.addDetail("foo", mycontent)
365@@ -945,6 +966,8 @@
366
367 class TestSetupTearDown(TestCase):
368
369+ run_test_with = FullStackRunTest
370+
371 def test_setUpNotCalled(self):
372 class DoesnotcallsetUp(TestCase):
373 def setUp(self):
374@@ -969,6 +992,8 @@
375 class TestSkipping(TestCase):
376 """Tests for skipping of tests functionality."""
377
378+ run_test_with = FullStackRunTest
379+
380 def test_skip_causes_skipException(self):
381 self.assertThat(lambda:self.skip("Skip this test"),
382 Raises(MatchesException(self.skipException)))
383@@ -1070,6 +1095,8 @@
384
385 class TestOnException(TestCase):
386
387+ run_test_with = FullStackRunTest
388+
389 def test_default_works(self):
390 events = []
391 class Case(TestCase):
392@@ -1104,6 +1131,8 @@
393
394 class TestPatchSupport(TestCase):
395
396+ run_test_with = FullStackRunTest
397+
398 class Case(TestCase):
399 def test(self):
400 pass
401@@ -1161,6 +1190,9 @@
402
403
404 class TestTestCaseSuper(TestCase):
405+
406+ run_test_with = FullStackRunTest
407+
408 def test_setup_uses_super(self):
409 class OtherBaseCase(unittest.TestCase):
410 setup_called = False
411
412=== modified file 'testtools/tests/test_testresult.py'
413--- testtools/tests/test_testresult.py 2011-07-29 17:49:41 +0000
414+++ testtools/tests/test_testresult.py 2011-08-15 13:56:22 +0000
415@@ -45,6 +45,7 @@
416 )
417 from testtools.tests.helpers import (
418 an_exc_info,
419+ FullStackRunTest,
420 LoggingResult,
421 run_with_stack_hidden,
422 )
423@@ -266,24 +267,32 @@
424
425 class TestTestResultContract(TestCase, StartTestRunContract):
426
427+ run_test_with = FullStackRunTest
428+
429 def makeResult(self):
430 return TestResult()
431
432
433 class TestMultiTestResultContract(TestCase, StartTestRunContract):
434
435+ run_test_with = FullStackRunTest
436+
437 def makeResult(self):
438 return MultiTestResult(TestResult(), TestResult())
439
440
441 class TestTextTestResultContract(TestCase, StartTestRunContract):
442
443+ run_test_with = FullStackRunTest
444+
445 def makeResult(self):
446 return TextTestResult(StringIO())
447
448
449 class TestThreadSafeForwardingResultContract(TestCase, StartTestRunContract):
450
451+ run_test_with = FullStackRunTest
452+
453 def makeResult(self):
454 result_semaphore = threading.Semaphore(1)
455 target = TestResult()
456@@ -323,6 +332,8 @@
457 class TestTestResult(TestCase):
458 """Tests for 'TestResult'."""
459
460+ run_tests_with = FullStackRunTest
461+
462 def makeResult(self):
463 """Make an arbitrary result for testing."""
464 return TestResult()

Subscribers

People subscribed via source and target branches