Logging is sometimes a part of your requirements. For example, you might want to issue a
warning anytime some security event occurs. I like to test these events using a
TestingLogger class that can stand in place of a real logger.
First, make your loggers parameters to your functions and classes. Globals make testing difficult.
class Example: def __init__(self, logger): self._logger = logger def do_something(self): self._logger.info("Logged something!")
def example(logger): logger.info("Logged something!")
Now you can use the
TestingLogger during tests. If it quacks like a duck, its a duck. Let’s make a
TestingLogger that quacks like a logger.
class TestingLogger: def __init__(self): self.messages =  def debug(self, message): self._log(message) def info(self, message): self._log(message) def warning(self, message): self._log(message) def error(self, message): self._log(message) def critical(self, message): self._log(message) def exception(self, message): self._log(message) def _log(self, message): self.messages.append(message)
This class implements the methods you will call 99% of the time against a logger. Instead of logging though, it will capture the messages in a
messages list. You can make assertions against this list in your tests.
def test_example_function(): logger = TestingLogger() example(logger) assert "Logged something!" == logger.messages def test_example_class(): logger = TestingLogger() Example(logger).do_something() assert "Logged something!" == logger.messages
You can expand on this idea in many ways:
- Capture the log level if you need to assert against them.
- Inherit from
self.appendto capture logs. Then you can make assertions against the testing logger directly instead of
- Capture the
strvalue of exceptions instead of the instances in
- If passing loggers as parameters is cumbersome, you can create a default when one isn’t specified, giving you flexibility in tests and convenience in the rest of the places.
If you would like to learn more about this testing style, check out the Python architecture book. It is one of the best programming books I have read in a long time.
As an Amazon Associate, I earn from qualifying purchases