0

I would like to get the test results from my unit tests and then log them. Having some trouble figuring out the best way to do it. Ideally I think I would like to get them from the tearDown method, and then log them there, so that each test is logging it's result as it finishes, but I can't seem to get it to work.

Here is some example code that you can run:

import unittest

class sample_tests(unittest.TestCase):

    def test_it(self):
        self.assertTrue(1==2)


    def tearDown(self):
        print("Get test results and log them here")
        print(unittest.TestResult())


if __name__=='__main__':
    #unittest.main()
    suite = unittest.TestSuite()
    suite.addTest(sample_tests("test_it"))
    runner = unittest.TextTestRunner()
    result = runner.run(suite)
    print(result.failures)

When you run this you will get the following output:

Get test results and log them here
<unittest.result.TestResult run=0 errors=0 failures=0>
F
======================================================================
FAIL: test_it (__main__.sample_tests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".\sample.py", line 6, in test_it
    self.assertTrue(1==2)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 1 test in 0.005s

FAILED (failures=1)
[(<__main__.sample_tests testMethod=test_it>, 'Traceback (most recent call last):\n  File ".\\sample.py", line 6, in test_it\n    self.assertTrue(1==2)\nAssertionError: False is not true\n')]
PS C:\Users\cn187366\Documents\Python_Test\ETL_Test_Framework>

As you can see, the tear down method is not returning the expected results and I think it is because I'm not referencing the test runner which contains the TestResults object.

EDIT I've found a solution here: Getting Python's unittest results in a tearDown() method

Here is the actual code that does what I wanted:

def tearDown(self):
    print("Get test results and log them here")

    if hasattr(self,'_outcome'):
        result = self.defaultTestResult()
        self._feedErrorsToResult(result,self._outcome.errors)
        print(result)
Dr.Tautology
  • 416
  • 1
  • 8
  • 19

2 Answers2

2

You can stream to a file with stream=file-name.log. For more detail, check the unittest.TextTestRunner class.

if __name__ == '__main__':
  suite = unittest.TestLoader().loadTestsFromTestCase(YourTestClass)
  with open('test_result.out', 'w') as f:
    unittest.TextTestRunner(stream=f, verbosity=2).run(suite)
Mesut GUNES
  • 7,089
  • 2
  • 32
  • 49
0

This should work!

import xmlrunner
with open('test-reports/result.xml', 'wb') as output:
    unittest.main(testRunner=xmlrunner.XMLTestRunner(output=output),
              failfast=False, buffer=False, catchbreak=False)

Alternative:

def tearDown(self)
    super(sample_tests, self).tearDown()
    with open('result.txt', 'w+') as output:
        test_failed = self._outcomes.errors
        output.write(test_failed)
Kshitij Saxena
  • 930
  • 8
  • 19
  • Unfortunately I cannot install external libraries in my environment. – Dr.Tautology Sep 11 '19 at 12:34
  • Okay, I tried out your alternative, but what is self.test_failed? I just get an attribute error on that. AttributeError: 'sample_tests' object has no attribute 'test_failed' – Dr.Tautology Sep 11 '19 at 13:05
  • This still givesn attribute error. AttributeError: 'sample_tests' object has no attribute '_outcomes'. I've found a solution, but thanks for your help. – Dr.Tautology Sep 11 '19 at 13:17