I am having trouble trying to save -all- of the results shown from pytest to a file (txt, log, doesn't matter). In the test example below, I would like to capture what is shown in console into a text/log file of some sort:
import pytest import os def test_func1(): assert True def test_func2(): assert 0 == 1 if __name__ == '__main__': pytest.main(args=['-sv', os.path.abspath(__file__)])
Console output I'd like to save to a text file:
test-mbp:hi_world ua$ python test_out.py ================================================= test session starts ================================================= platform darwin -- Python 2.7.6 -- py-1.4.28 -- pytest-2.7.1 -- /usr/bin/python rootdir: /Users/tester/PycharmProjects/hi_world, inifile: plugins: capturelog collected 2 items test_out.py::test_func1 PASSED test_out.py::test_func2 FAILED ====================================================== FAILURES ======================================================= _____________________________________________________ test_func2 ______________________________________________________ def test_func2(): > assert 0 == 1 E assert 0 == 1 test_out.py:9: AssertionError ========================================= 1 failed, 1 passed in 0.01 seconds ========================================== test-mbp:hi_world ua$
Live Logs. By setting the log_cli configuration option to true , pytest will output logging records as they are emitted directly into the console. You can specify the logging level for which log records with equal or higher level are printed to the console by passing --log-cli-level .
Pytest does not support this by default, but you can add a custom option to your conftest.py to turn off specific loggers.
All you need to do is include a function with the test_ prefix. Because you can use the assert keyword, you don't need to learn or remember all the different self. assert* methods in unittest , either. If you can write an expression that you expect to evaluate to True , and then pytest will test it for you.
It appears that all of your test output is going stdout, so you simply need to “redirect” your python invocation's output there:
python test_out.py >myoutput.log
You can also “tee” the output to multiple places. E.g., you might want to log to the file yet also see the output on your console. The above example then becomes:
python test_out.py | tee myoutput.log
I derive this from pastebin as suggest by Bruno Oliveira :
#!/usr/bin/env python # -*- coding: utf-8 -*- """ Pytest Plugin that save failure or test session information to a file pass as a command line argument to pytest. It put in a file exactly what pytest return to the stdout. To use it : Put this file in the root of tests/ edit your conftest and insert in the top of the file : pytest_plugins = 'pytest_session_to_file' Then you can launch your test with the new option --session_to_file= like this : py.test --session_to_file=FILENAME Or : py.test -p pytest_session_to_file --session_to_file=FILENAME Inspire by _pytest.pastebin Ref: https://github.com/pytest-dev/pytest/blob/master/_pytest/pastebin.py Version : 0.1 Date : 30 sept. 2015 11:25 Copyright (C) 2015 Richard Vézina <ml.richard.vezinar @ gmail.com> Licence : Public Domain """ import pytest import sys import tempfile def pytest_addoption(parser): group = parser.getgroup("terminal reporting") group._addoption('--session_to_file', action='store', metavar='path', default='pytest_session.txt', help="Save to file the pytest session information") @pytest.hookimpl(trylast=True) def pytest_configure(config): tr = config.pluginmanager.getplugin('terminalreporter') # if no terminal reporter plugin is present, nothing we can do here; # this can happen when this function executes in a slave node # when using pytest-xdist, for example if tr is not None: config._pytestsessionfile = tempfile.TemporaryFile('w+') oldwrite = tr._tw.write def tee_write(s, **kwargs): oldwrite(s, **kwargs) config._pytestsessionfile.write(str(s)) tr._tw.write = tee_write def pytest_unconfigure(config): if hasattr(config, '_pytestsessionfile'): # get terminal contents and delete file config._pytestsessionfile.seek(0) sessionlog = config._pytestsessionfile.read() config._pytestsessionfile.close() del config._pytestsessionfile # undo our patching in the terminal reporter tr = config.pluginmanager.getplugin('terminalreporter') del tr._tw.__dict__['write'] # write summary create_new_file(config=config, contents=sessionlog) def create_new_file(config, contents): """ Creates a new file with pytest session contents. :contents: paste contents :returns: url to the pasted contents """ # import _pytest.config # path = _pytest.config.option.session_to_file # path = 'pytest_session.txt' path = config.option.session_to_file with open(path, 'w') as f: f.writelines(contents) def pytest_terminal_summary(terminalreporter): import _pytest.config tr = terminalreporter if 'failed' in tr.stats: for rep in terminalreporter.stats.get('failed'): try: msg = rep.longrepr.reprtraceback.reprentries[-1].reprfileloc except AttributeError: msg = tr._getfailureheadline(rep) tw = _pytest.config.create_terminal_writer(terminalreporter.config, stringio=True) rep.toterminal(tw) s = tw.stringio.getvalue() assert len(s) create_new_file(config=_pytest.config, contents=s)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With