Bennie
Bennie

Reputation: 509

Capture the run time from running a unittest TestCase into a Python variable

I have several Python files, each containing a Python function and a TestCase, similar to the one below. I want to have a separate python script which will execute each file and capture the output. As it happens, all of the tests will be passing and the output will be similar to below "Ran x tests in x seconds" but this output is stderr, NOT stdout.

I would like to be able to append each output to a list.

From a bash shell i can simply use:

$ python combine.py &> result.txt

which would save the output to a file(not ideal, but at least something I can then retrieve), so I've tried using:

os.system('python combine.py &> result.txt')

..that just prints it to the terminal though.

There may be a simpler way, such as calling a TestCase method directly rather than executing the whole file, which may actually be a better solution, but I have not been able to figure out a way to do that either.

The ultimate goal is to execute the unittests in each of several files, and return a list of them. such as ['Ran 3 tests in 0.3 seconds', 'Ran 2 tests in 0.6 seconds', etc..]

# combine.py

def combine(*args): 
    result = []
    args = list(args)
    while len(args):
        for arg in args:
            try:
                result.append(arg.pop(0))
            except IndexError:
                a = args.index(arg)
                args.pop(a)
    return result



from unittest import TestCase, main

class CombineTests(TestCase):


    def runTest(self):
        result = ['a', 1, 'one', 'b', 2, 'two', 'c', 3, 4]
        self.assertEquals(combine(['a','b','c'], [1,2,3,4],['one','two']), result)

if __name__ == '__main__': main()

output (stderr):

Ran 5 tests in 0.002s

OK

Upvotes: 1

Views: 1294

Answers (1)

ebyerly
ebyerly

Reputation: 672

The unittest module's main method had two options I think you'll find helpful:

main(module='test_module', exit=False)

The returned value of this execution is a TestProgram class object. You can run the below in an interactive interpreter.

import unittest
import datetime

def fnc(a, b):
    return a + b

class MyTest(unittest.TestCase):
    def test_one(self):
        self.assertEqual(fnc(1,1), 2)

start = datetime.datetime.now()
tmp = unittest.main(module = '__main__', exit = False)
end = datetime.datetime.now()
duraction = end - start
print(duration)

There may be a way to extract the runtime from the object saved here into tmp, but I'm not sure what it would be. You can loop through your modules, swapping their value in for '__main__' in the call to unittest.main(), and capture the runtime duration.

Upvotes: 3

Related Questions