* `testools.TestCase.useFixture` has been added to glue with fixtures nicely.
(Robert Collins)
This commit is contained in:
10
MANUAL
10
MANUAL
@@ -116,6 +116,16 @@ instead. ``skipTest`` was previously known as ``skip`` but as Python 2.7 adds
|
||||
``skipTest`` support, the ``skip`` name is now deprecated (but no warning
|
||||
is emitted yet - some time in the future we may do so).
|
||||
|
||||
TestCase.useFixture
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``useFixture(fixture)`` calls setUp on the fixture, schedules a cleanup to
|
||||
clean it up, and schedules a cleanup to attach all details held by the
|
||||
fixture to the details dict of the test case. The fixture object should meet
|
||||
the ``fixtures.Fixture`` protocol (version 0.3.4 or newer). This is useful
|
||||
for moving code out of setUp and tearDown methods and into composable side
|
||||
classes.
|
||||
|
||||
|
||||
New assertion methods
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
3
NEWS
3
NEWS
@@ -24,6 +24,9 @@ Improvements
|
||||
* addUnexpectedSuccess is translated to addFailure for test results that don't
|
||||
know about addUnexpectedSuccess. (Jonathan Lange, #654474)
|
||||
|
||||
* ``testools.TestCase.useFixture`` has been added to glue with fixtures nicely.
|
||||
(Robert Collins)
|
||||
|
||||
|
||||
0.9.7
|
||||
~~~~~
|
||||
|
||||
11
README
11
README
@@ -19,14 +19,21 @@ is copyright Steve Purcell and the Python Software Foundation, it is
|
||||
distributed under the same license as Python, see LICENSE for details.
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
Required Dependencies
|
||||
---------------------
|
||||
|
||||
* Python 2.4+ or 3.0+
|
||||
|
||||
Optional Dependencies
|
||||
---------------------
|
||||
|
||||
If you would like to use our undocumented, unsupported Twisted support, then
|
||||
you will need Twisted.
|
||||
|
||||
If you want to use ``fixtures`` then you can either install fixtures (e.g. from
|
||||
https://launchpad.net/python-fixtures or http://pypi.python.org/pypi/fixtures)
|
||||
or alternatively just make sure your fixture objects obey the same protocol.
|
||||
|
||||
|
||||
Bug reports and patches
|
||||
-----------------------
|
||||
|
||||
@@ -538,6 +538,35 @@ class TestCase(unittest.TestCase):
|
||||
"""
|
||||
return self._get_test_method()()
|
||||
|
||||
def useFixture(self, fixture):
|
||||
"""Use fixture in a test case.
|
||||
|
||||
The fixture will be setUp, and self.addCleanup(fixture.cleanUp) called.
|
||||
|
||||
:param fixture: The fixture to use.
|
||||
:return: The fixture, after setting it up and scheduling a cleanup for
|
||||
it.
|
||||
"""
|
||||
fixture.setUp()
|
||||
self.addCleanup(fixture.cleanUp)
|
||||
self.addCleanup(self._gather_details, fixture.getDetails)
|
||||
return fixture
|
||||
|
||||
def _gather_details(self, getDetails):
|
||||
"""Merge the details from getDetails() into self.getDetails()."""
|
||||
details = getDetails()
|
||||
my_details = self.getDetails()
|
||||
for name, content_object in details.items():
|
||||
new_name = name
|
||||
disambiguator = itertools.count(1)
|
||||
while new_name in my_details:
|
||||
new_name = '%s-%d' % (name, advance_iterator(disambiguator))
|
||||
name = new_name
|
||||
content_bytes = list(content_object.iter_bytes())
|
||||
content_callback = lambda:content_bytes
|
||||
self.addDetail(name,
|
||||
content.Content(content_object.content_type, content_callback))
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.__setup_called = True
|
||||
|
||||
@@ -6,6 +6,9 @@ from pprint import pformat
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import fixtures
|
||||
from fixtures.tests.helpers import LoggingFixture
|
||||
|
||||
from testtools import (
|
||||
ErrorHolder,
|
||||
MultipleExceptions,
|
||||
@@ -13,6 +16,7 @@ from testtools import (
|
||||
TestCase,
|
||||
clone_test_with_new_id,
|
||||
content,
|
||||
content_type,
|
||||
skip,
|
||||
skipIf,
|
||||
skipUnless,
|
||||
@@ -1122,6 +1126,59 @@ class TestPatchSupport(TestCase):
|
||||
self.assertIs(marker, value)
|
||||
|
||||
|
||||
class TestFixtureSupport(TestCase):
|
||||
|
||||
def test_useFixture(self):
|
||||
fixture = LoggingFixture()
|
||||
class SimpleTest(TestCase):
|
||||
def test_foo(self):
|
||||
self.useFixture(fixture)
|
||||
result = unittest.TestResult()
|
||||
SimpleTest('test_foo').run(result)
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
self.assertEqual(['setUp', 'cleanUp'], fixture.calls)
|
||||
|
||||
def test_useFixture_cleanups_raise_caught(self):
|
||||
calls = []
|
||||
def raiser(ignored):
|
||||
calls.append('called')
|
||||
raise Exception('foo')
|
||||
fixture = fixtures.FunctionFixture(lambda:None, raiser)
|
||||
class SimpleTest(TestCase):
|
||||
def test_foo(self):
|
||||
self.useFixture(fixture)
|
||||
result = unittest.TestResult()
|
||||
SimpleTest('test_foo').run(result)
|
||||
self.assertFalse(result.wasSuccessful())
|
||||
self.assertEqual(['called'], calls)
|
||||
|
||||
def test_useFixture_details_captured(self):
|
||||
class DetailsFixture(fixtures.Fixture):
|
||||
def setUp(self):
|
||||
fixtures.Fixture.setUp(self)
|
||||
self.addCleanup(delattr, self, 'content')
|
||||
self.content = ['content available until cleanUp']
|
||||
self.addDetail('content',
|
||||
content.Content(content_type.UTF8_TEXT, self.get_content))
|
||||
def get_content(self):
|
||||
return self.content
|
||||
fixture = DetailsFixture()
|
||||
class SimpleTest(TestCase):
|
||||
def test_foo(self):
|
||||
self.useFixture(fixture)
|
||||
# Add a colliding detail (both should show up)
|
||||
self.addDetail('content',
|
||||
content.Content(content_type.UTF8_TEXT, lambda:['foo']))
|
||||
result = ExtendedTestResult()
|
||||
SimpleTest('test_foo').run(result)
|
||||
self.assertEqual('addSuccess', result._events[-2][0])
|
||||
details = result._events[-2][2]
|
||||
self.assertEqual(['content', 'content-1'], sorted(details.keys()))
|
||||
self.assertEqual('foo', ''.join(details['content'].iter_text()))
|
||||
self.assertEqual('content available until cleanUp',
|
||||
''.join(details['content-1'].iter_text()))
|
||||
|
||||
|
||||
def test_suite():
|
||||
from unittest import TestLoader
|
||||
return TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
Reference in New Issue
Block a user