4

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...

2
  • you have to share to the community the full code of the test, minimum from test fail in order anyone can help you, with only this data is impossible Commented Jul 18, 2017 at 0:09
  • 1
    The code shouldn't really matter for the question, as the question pertains to manipulating and redirecting the 'unittest' module's output. The example fail test I gave is only two lines... def test_fail(self): assertTrue(False) Commented Jul 18, 2017 at 0:13

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

But calling unittest.TextTestRunner(verbosity=3).run( suite ) would still output the stacktraces into terminal, not into file. And you are not using the TestResult you mentioned in your example either.
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.