[Tutor] redirecting testing output to file, using two different options

Peter Otten __peter__ at web.de
Thu May 17 04:29:24 EDT 2018


Yosef Levy wrote:

> Hello All,
> 
> I have testing environment.
> Code is written under Python 2.6.
> testing output should be redirected to log file.
> I am using two different file handling, in order to log output:
> 
> 
> 
> 1. logging module:
> 
> import unittest2
> import logging
> import sys
> 
> class TestMyEnvClass (unittest2.TestCase):
>     def setUp (self):
>         pass
>     def testMyEnv (self):
>         logging.debug  ( "In testMyEnv.." )
>     def tearDown (self):
>         pass
> 
> if __name__ == "__main__":
>     logging.basicConfig( filename='log_file.txt', stream=sys.stderr,
> level=logging.DEBUG)
>     logging.getLogger( "TestMyEnvClass.testMyEnv" ).setLevel(
>     logging.DEBUG
> )
>     unittest2.main()
> 
> 
> running:
> python test.py
> 
> output:
> # cat log_file.txt
> DEBUG:root:In testMyEnv..
> #
> 
> 
> 
> 
> 
> 2. but if I want to redirect assert messages to file, I have to:
> 
> import unittest2
> 
> class TestMyEnvClass (unittest2.TestCase):
>     def setUp (self):
>         pass
>     def testMyEnv (self):
>         res = True
>         self.assertEqual(res, True, 'Testing my environment..')
>     def tearDown (self):
>         pass
> 
> if __name__ == "__main__":
>     f = open('log_file.txt', "a")
>     runner = unittest2.TextTestRunner(f)
>     unittest2.main(testRunner=runner)
>     f.close ()
> 
> 
> 
> running:
> # python test2.py
> 
> output:
> # cat log_file.txt
> .
> ----------------------------------------------------------------------
> Ran 1 test in 0.000s
> 
> OK
> 
> 
> 
> Question:
> Is the a way to 'merge' the above two different ways output to file?
> Or, is there a way to redirect assert messages to logging module methods?

You can either write a file-like object that uses Logger methods under the 
hood or write your own test runner that uses Logger methods.
A basic example targeting Python 3:

$ cat log_unittest.py     
import logging
import unittest
import os

logger = logging.getLogger()


class TestMyEnvClass (unittest.TestCase):
    def setUp(self):
        pass

    def testMyEnv(self):
        res = os.environ.get("res") == "1"
        self.assertEqual(res, True, 'Testing my environment..')

    def tearDown(self):
        pass


class LogStream:
    def __init__(self, logger):
        self.logger = logger

    def writeln(self, s=""):
        self.logger.info(s)

    def write(self, s):
        self.logger.info(s)

    def flush(self):
        pass


class MyTextTestRunner(unittest.TextTestRunner):
    def __init__(self, logger):
        super().__init__(None)
        self.stream = LogStream(logger)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    logging.info("hello world")

    runner = MyTextTestRunner(logger)
    unittest.main(testRunner=runner)
$ res=1 python3 log_unittest.py
INFO:root:hello world
INFO:root:.
INFO:root:
INFO:root:----------------------------------------------------------------------
INFO:root:Ran 1 test in 0.000s
INFO:root:
INFO:root:OK
INFO:root:

$ res=0 python3 log_unittest.py
INFO:root:hello world
INFO:root:F
INFO:root:
INFO:root:======================================================================
INFO:root:FAIL: testMyEnv (__main__.TestMyEnvClass)
INFO:root:----------------------------------------------------------------------
INFO:root:Traceback (most recent call last):
  File "log_unittest.py", line 14, in testMyEnv
    self.assertEqual(res, True, 'Testing my environment..')
AssertionError: False != True : Testing my environment..

INFO:root:----------------------------------------------------------------------
INFO:root:Ran 1 test in 0.001s
INFO:root:
INFO:root:FAILED
INFO:root: (failures=1)

If you want more control you have to rewrite more code ;)



More information about the Tutor mailing list