Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to globally configure logging for unit tests when executing them in discovery mode?

Within my python package, I use the standard modules logging to create logs, and unittest to create unit tests.

Since the files containing the unit tests are spread across the entire folder structure of the package, I use the test discovery mode to execute the unit tests:

python -m unittest discover \
       --pattern "*_test.py" \
       --start-directory "path/to/package/root"

Unfortunately, this results in a messed up text stream on the console because both log messages and output from the unit test runner are forwarded to stdout.

For single test modules (which I store in separate files <module_name>_test.py), I usually control the logging output globally within the __main__-block:

# In <module_name>_test.py

import logging
import unittest
# ...

if __name__ == "__main__":
    # Forward log messages into a file test.log.
    logging.basicConfig(level=logging.DEBUG,
                        filename="testing/output/test.log")
    unittest.main()

When executing python <module_name>_test.py, this ensures that the log messages are separated from the unit test output.

However, in test discovery mode, the __main__-blocks of my test-modules are never executed. Therefore my question is: How to globally set up logging in test discovery mode? Ideally, I would have to configure the logger only in a single place, and not in all test modules separately. Is this possible?

like image 502
normanius Avatar asked Sep 17 '25 08:09

normanius


1 Answers

The solution was relatively easy after rereading the documentation on unittest discovery more carefully. The functionality is implemented in TestLoader.discover().

To run all unit tests, I wrote a file run_tests.py that looks as follows:

import logging
import unittest

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG,
                        filename="test.log")
    loader = unittest.TestLoader()
    tests = loader.discover(pattern="*_test.py",
                            start_dir="<path/to/package>")
    runner = unittest.runner.TextTestRunner()
    runner.run(tests)
like image 148
normanius Avatar answered Sep 19 '25 22:09

normanius