I talked to Robert Collins, the primary maintainer of this chain of tools, and he suggested I use testtools.TestCase, which supports addFixture() and python-fixtures, which includes FakeLogger. Now, this transition turned out to be a little bit sticky - both testtools.TestCase and testresources.ResouredTestCase inherit from unittest.TestCase, so dual inheritance should have worked, but I was running into this strange problem that resources were never being cleaned up. It turned out that testtools.TestCase calls setUp() but doesn't call tearDown() - it uses addCleanup() for that purpose. As part of the debugging process for this issue, I axed the multiple inheritance an just created a ResourcedTestCase that follows testtools.TestCase norms as follows:
from testresources import setUpResources, tearDownResources, _get_result
import testtools
import fixtures
class ResourcedTestCase(testtools.TestCase):
"""Inherit from testtools.TestCase instead of unittest.TestCase in order
to have self.useFixture()."""
def setUp(self):
# capture output
FORMAT = '%(asctime)s [%(levelname)s] %(name)s %(lineno)d: %(message)s'
self.useFixture(fixtures.FakeLogger(format=FORMAT))
# capture stdout
stdout = self.useFixture(fixtures.StringStream('stdout')).stream
self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
# capture stderr
stderr = self.useFixture(fixtures.StringStream('stderr')).stream
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
super(ResourcedTestCase, self).setUp()
setUpResources(self, self.resources, _get_result)
self.addCleanup(tearDownResources, self, self.resources, _get_result)
With this new base class, my tests now capture logging, stdout, and stderr under both testr and nose, with and without nose-testresources.