3

I have developed an application in Python and am using the Cement CLI library. I am using py.test with the CementTestCase. I can capture the output from stdout in the test cases without a problem, using something like this:

with EZOTestApp(argv=['view', 'deploys']) as app:
    old_stdout = sys.stdout
    app.ezo = EZO(app.config["ezo"])
    result = StringIO()
    sys.stdout = result
    app.run()
    output = sys.stdout.getvalue()
    sys.stdout = old_stdout
    assert 'deploy' in output

However, in attempting to trap the stderr output from the Cement logging extension using the same mechanism captures nothing (re: replacing 'stdout' with 'stderr' in the above code). I saw a method for iterating through the standard Python logging handlers for finding the output, and I suspect something similar would be used the Cement logging extension to capture stderr, but I'm having trouble figuring it out. Anyone have any insight?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
robin gist
  • 96
  • 1
  • 7

1 Answers1

2

Capturing the stdout or stderr output can be done with the capsys fixture.

You can then make checks like this (example adapted from the docs):

def test_myoutput(capsys):
    print("hello")
    sys.stderr.write("world\n")
    captured = capsys.readouterr()
    assert captured.out == "hello\n"
    assert captured.err == "world\n"

For even more granularity, you can use the caplog fixture. This one will give you access to the log level, the logger, etc., as opposed to the text line only. This depends on the extension you mention relying on the standard lib's logging module though, so it might no be available.

An example of what you can do with that fixture (again, credit goes to the pytest doc):

def test_baz(caplog):
    func_under_test()
    for record in caplog.records:
        assert record.levelname != 'CRITICAL'
    assert 'wally' not in caplog.text
Samuel Dion-Girardeau
  • 2,790
  • 1
  • 29
  • 37
  • thanks Samuel. I was having trouble with parameter passing and had to redo my tests. It works very well now. – robin gist Jun 26 '18 at 04:19