How to assert output with nosetest/unittest in python?

后端 未结 12 1499
野趣味
野趣味 2020-11-28 02:56

I\'m writing tests for a function like next one:

def foo():
    print \'hello world!\'

So when I want to test this function the code will b

12条回答
  •  不知归路
    2020-11-28 03:22

    I use this context manager to capture output. It ultimately uses the same technique as some of the other answers by temporarily replacing sys.stdout. I prefer the context manager because it wraps all the bookkeeping into a single function, so I don't have to re-write any try-finally code, and I don't have to write setup and teardown functions just for this.

    import sys
    from contextlib import contextmanager
    from StringIO import StringIO
    
    @contextmanager
    def captured_output():
        new_out, new_err = StringIO(), StringIO()
        old_out, old_err = sys.stdout, sys.stderr
        try:
            sys.stdout, sys.stderr = new_out, new_err
            yield sys.stdout, sys.stderr
        finally:
            sys.stdout, sys.stderr = old_out, old_err
    

    Use it like this:

    with captured_output() as (out, err):
        foo()
    # This can go inside or outside the `with` block
    output = out.getvalue().strip()
    self.assertEqual(output, 'hello world!')
    

    Furthermore, since the original output state is restored upon exiting the with block, we can set up a second capture block in the same function as the first one, which isn't possible using setup and teardown functions, and gets wordy when writing try-finally blocks manually. That ability came in handy when the goal of a test was to compare the results of two functions relative to each other rather than to some precomputed value.

提交回复
热议问题