Tom Schutte
Tom Schutte

Reputation: 103

python unittest module, log failures to file

I am looking to clean up the normal python unittest output. I want to the console output to still be

test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok
test_fail (__main__.TestFail) ... ERROR

----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK

But for the fail tests I want to capture the detailed output, and put that in a log file. So instead of it being inline with the console output...

======================================================================
FAIL: test_fail (__main__.TestFail)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test.py", line x
    self.assertTrue(False)
AssertionError: False is not True

======================================================================

Gets logged to a file for further investigation, along with any debug level logger output. Is there a way to overload the logger in the unittest.testcase to do what I want?

I should mention I am still very new to python...

Upvotes: 4

Views: 2162

Answers (2)

Hi-Angel
Hi-Angel

Reputation: 5619

The TextTestRunner output can be redirected to a file by providing a stream argument to constructor. Later then, using run() on the suite will return TextTestResult, which you can pretty print. Something like this:

logs_filename = 'logs.txt'

def print_test_results_summary(result):
    n_failed    = len(result.failures) + len(result.unexpectedSuccesses)
    n_crashed   = len(result.errors)
    n_succeeded = result.testsRun - n_failed - n_crashed
    print(f'''See for details {logs_filename} file.
Results: Total: {result.testsRun}, Crashed: {n_crashed}, Failed: {n_failed}, Succeeded: {n_succeeded}''')

with open(logs_filename, 'w') as log_file:
    suite = unittest.defaultTestLoader.loadTestsFromModule(className)
    testResult = unittest.TextTestRunner(log_file, verbosity=3).run(suite)
    print_test_results_summary(testResult)

Upvotes: 0

Tom Schutte
Tom Schutte

Reputation: 103

I ended up being able to get close enough results to what I wanted by using the testResult object. From that object I was able to get tuples with data on different tests that had passed, failed, or had errors. Then it was a simple create a "prettyPrint" method to take this object and print out the contents nicely.

The exact recipe was:

suite = unittest.TestLoader().loadTestsFromModule( className )
testResult = unittest.TextTestRunner(verbosity=3).run( suite ) 

Hopefully this helps anyone else looking to do something similar.

Upvotes: 1

Related Questions