捕获单元测试的默认tqdm输出

时间:2017-08-10 15:29:10

标签: python output tqdm

如何编写单元测试以确保实际调用了tqdm进度条?另外,当我没有指定file kwarg(在这种情况下它应该默认为sys.stderr)时,如何捕获进度条的输出?

我尝试使用contextlib.redirect_stderr来捕获输出,但这不起作用(详见下文)。

这是我要测试的内容。我有一种方法,有时会根据self.use_progress_bar使用进度条。对象将被多次处理,因此我无法拥有进度条。

def awesome_method(self):
    if self.use_progress_bar:
        progress_bar = tqdm.tqdm(total=self.match_generator.size,
                                 desc="Playing matches")

    if self.filename is not None:
        file = open(self.filename, 'w')
        writer = csv.writer(file, lineterminator='\n')

    for chunk in chunks:
        results = self._play_matches(chunk)
        self._write_interactions(results, writer=writer)

        if self.use_progress_bar:
            progress_bar.update(1)

我想写一个单元测试,确认进度条在那里。我尝试过类似的东西:

import unittest
import MyAwesomeClass
from contextlib import redirect_stderr
import io

class TestMyCode(unittest.TestCase):
    def test_progress_bar(self):
        err = io.StringIO()
        with redirect_stderr(err):
            awesomeness = MyAwesomeClass(use_progress_bar=True)
            awesomeness.awesome_method()
        self.assertIn("Playing matches", err.getvalue())

err为空。问题似乎是如果你没有用文件实例化tqdm,它默认为sys.stderr,但不是上下文管理器中的那个。当我尝试运行时:

def action():
err = io.StringIO()
with redirect_stderr(err):
    pbar = tqdm.tqdm(range(5))
    print('pbar: ', pbar.fp)
    print('err: ',err)
    print('stderr:', sys.stderr)
    pbar.update()
    pbar.update()
return err


if __name__ == '__main__':
    err = action()
    print('\nstart\n', err.getvalue(), '\nstop\n')
    print(sys.stderr)

这是输出(减去我无法捕获的pbar输出):

pbar:  <colorama.ansitowin32.StreamWrapper object at 0x0000000002A18D68>
err:  <_io.StringIO object at 0x0000000002A8B318>
stderr: <_io.StringIO object at 0x0000000002A8B318>

start

stop

<colorama.ansitowin32.StreamWrapper object at 0x0000000002A18D68>

所以,在上下文管理器中(实例化进度条),sys.stderr指向err,但tqdm默认值self.fp = sys.stderr仍然抓住真实的sys.stderr即使它在上下文管理器中。为什么?!?!?!?如何在没有设置tqdm对象的file=的情况下测试进度条

0 个答案:

没有答案