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?
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With