Reputation: 399
I'm writing code that tests via unittest if several elements exist on a certain homepage. After the test I want that the results were saved in a text file. But the results in the text file look like this:
......................
.........
------------------------------------------
Ran 12 tests in 22.562s
OK.
But i want that the output looks like this:
test_test1 (HomepageTest.HomePageTest) ... ok
test_test2 (HomepageTest.HomePageTest) ... ok
test_test3 (HomepageTest.HomePageTest) ... ok
etc....
-------------------------------------------------
Ran 12 tests in ...s
OK
This is the code I use for saving the output into a text file:
class SaveTestResults(object):
def save(self):
self.f = open(log_file, 'w')
runner = unittest.TextTestRunner(self.f)
unittest.main(testRunner = runner, defaultTest ='suite', verbosity = 2)
def main():
STR = SaveTestResults()
STR.save()
if __name__ == '__main__':
main()
What am I missing or doing wrong?
Upvotes: 3
Views: 6304
Reputation: 16700
If the output you wish to save in a file corresponds to what is printed out to the console, you have two main options.
Then just redirect the output to a file:
python script.py > output.txt
However, the output will not be printed out to the console anymore.
If you want to keep the console output, use the tee
unix command:
python script.py | tee output.txt
You can achieve more or less the same thing using exclusively Python.
You need to set the value of sys.stdout
to the file descriptor where you want the output to be written.
import sys
sys.stdout = open("output.txt", 'w')
run_tests()
This will set the output stream stdout
to the given file for the whole script.
I would suggest defining a decorator instead:
def redirect_to_file(func):
def decorated(*args, **kwargs):
actualStdout = sys.stdout
sys.stdout = open("log.txt", 'a')
result = func(*args, **kwargs)
sys.stdout = actualStdout
return result
return decorated
Then, just decorate the functions whose you want to write the output to a file:
@redirect_to_file
def run_test():
...
If you want a similar behaviour to tee
, have a look at this post.
The idea is to define a Tee
class that holds the two desired streams:
class Tee:
def __init__(self, stream1, stream2):
self.stream1 = stream1
self.stream2 = stream2
def write(self, data):
self.stream1.write(data)
self.stream2.write(data)
def close(self):
self.stream1.close()
self.stream2.close()
Then, set sys.stdout
to a Tee
instance whose one of the stream is the actual stdout
:
tee = Tee(sys.stdout, open("output.txt", 'w'))
sys.stdout = tee
Don't forget to close the tee
instance at the end of your script; else, the data written to output.txt
will not be saved:
tee.close()
Upvotes: 3