Skip to content

Commit

Permalink
Add a warnings module capture fixure
Browse files Browse the repository at this point in the history
Capturing the warnings module output (which is typically used
for deprecating code or functions or modules) is quite useful and
is a frequent operation that can be required to perform. So provide
a fixture that is similar (but not the same) as the warnings
``catch_warnings`` context manager that can be used to gather all
warnings emitted and allows people to later analyze them to ensure
they are as they expect.
  • Loading branch information
Joshua Harlow committed May 4, 2015
1 parent d47cc58 commit a48a685
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ fixtures release notes
NEXT
~~~~

* Add warnings module fixture for capturing warnings. (Joshua Harlow)

1.1.0
~~~~~

Expand Down
2 changes: 2 additions & 0 deletions fixtures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
'TestWithFixtures',
'Timeout',
'TimeoutException',
'WarningsCapture',
'__version__',
'version',
]
Expand Down Expand Up @@ -96,6 +97,7 @@
TempHomeDir,
Timeout,
TimeoutException,
WarningsCapture,
)
from fixtures.testcase import TestWithFixtures

Expand Down
4 changes: 4 additions & 0 deletions fixtures/_fixtures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
'TempHomeDir',
'Timeout',
'TimeoutException',
'WarningsCapture',
]


Expand Down Expand Up @@ -72,3 +73,6 @@
Timeout,
TimeoutException,
)
from fixtures._fixtures.warnings import (
WarningsCapture,
)
41 changes: 41 additions & 0 deletions fixtures/_fixtures/warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# fixtures: Fixtures with cleanups for testing and convenience.
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.

from __future__ import absolute_import

__all__ = [
'WarningsCapture',
]

import warnings

import fixtures


class WarningsCapture(fixtures.Fixture):
"""Capture warnings.
While ``WarningsCapture`` is active, warnings will be captured by
the fixture (so that they can be later analyzed).
:attribute captures: A list of warning capture ``WarningMessage`` objects.
"""

def _showwarning(self, *args, **kwargs):
self.captures.append(warnings.WarningMessage(*args, **kwargs))

def setUp(self):
super(WarningsCapture, self).setUp()
patch = fixtures.MonkeyPatch("warnings.showwarning", self._showwarning)
self.useFixture(patch)
self.captures = []
49 changes: 49 additions & 0 deletions fixtures/tests/_fixtures/test_warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# fixtures: Fixtures with cleanups for testing and convenience.
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.

import warnings

import testtools

import fixtures


class TestWarnings(testtools.TestCase, fixtures.TestWithFixtures):

def test_capture_reuse(self):
w = fixtures.WarningsCapture()
with w:
warnings.warn("test", DeprecationWarning)
self.assertEqual(1, len(w.captures))
with w:
self.assertEqual([], w.captures)

def test_capture_message(self):
w = self.useFixture(fixtures.WarningsCapture())
warnings.warn("hi", DeprecationWarning)
self.assertEqual(1, len(w.captures))
self.assertEqual("hi", str(w.captures[0].message))

def test_capture_category(self):
w = self.useFixture(fixtures.WarningsCapture())
categories = [
DeprecationWarning, Warning, UserWarning,
SyntaxWarning, RuntimeWarning,
UnicodeWarning, FutureWarning,
]
for category in categories:
warnings.warn("test", category)
self.assertEqual(len(categories), len(w.captures))
for i, category in enumerate(categories):
c = w.captures[i]
self.assertEqual(category, c.category)

0 comments on commit a48a685

Please sign in to comment.