Tutorial :Hide stderr output in unit tests



Question:

I'm writing a few unit tests of some code which uses sys.stderr.write to report errors in input. This is as it should be, but this clobbers the unit test output. Is there any way to tell Python to not output error messages for single commands, à la 2> /dev/null?


Solution:1

I suggest writing a context manager:

import contextlib  import sys    @contextlib.contextmanager  def nostderr():      savestderr = sys.stderr      class Devnull(object):          def write(self, _): pass          def flush(self): pass      sys.stderr = Devnull()      try:          yield      finally:          sys.stderr = savestderr  

Now, wrap any code snippet whose stderr you want suppressed in a with nostderr(): and you have the localized, temporary, guaranteed-reversible stderr suppression that you want.


Solution:2

You could create a dummy file object that did nothing with its output, and set stderr to that:

class NullWriter:      def write(self, s):          pass    sys.stderr = NullWriter()  

If you only want to quiet stderr for a specific duration, you can use a with statement like so:

class Quieter:      def __enter__(self):          self.old_stderr = sys.stderr          sys.stderr = NullWriter()        def __exit__(self, type, value, traceback):          sys.stderr = self.old_stderr    with Quieter():      # Do stuff; stderr will be suppressed, and it will be restored      # when this block exits  

Requires Python 2.6 or higher, or you can use it in Python 2.5 with a from __future__ import with_statement.


Solution:3

class DevNull(object):      def write(self, data): pass    sys.stderr = DevNull()  

To have a less permanent solution, one could figure out something like as follows:

_stderr = None  def quiet():      global _stderr      if _stderr is None:          _stderr = sys.stderr          sys.stderr = DevNull()    def verbose():     global _stderr     if _stderr is not None:         sys.stderr = _stderr        _stderr = None  

Function names can probably be better


Solution:4

Another possibility (besides assigning to sys.stderr) is to structure your code to write errors to a file provided, but to default that file to sys.stderr. Then you can provide a DevNull writer during testing.

If you do want to reassign sys.stderr, you can use the unittest framework to manage it for you:

class DevNull(object):      def write(self, data):           pass    class MyTestCase(unittest.TestCase):      def setUp(self):          self.old_stderr = sys.stderr          sys.stderr = DevNull()        def tearDown(self):          sys.stderr = self.old_stderr  

This way, every test dev-null's stderr, but then restores it at the end of the test.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »