如何编写单元测试以确保实际调用了 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
的,即使它在上下文管理器中。为什么?!?!?!?以及如何在不设置file=
tqdm 对象的情况下测试进度条?