2016-11-13 83 views
0

在测试中,我将stderr重定向到文件中,并尝试以尾巴式方式读取它。 因此,这里是重定向:Python尾状文件读取

class RedirectedEnv(object): 
    def __init__(self, stderr=None): 
     self._stderr = stderr or sys.stderr 

    def __enter__(self): 
     self.old_stderr = sys.stderr 
     self.old_stderr.flush() 
     self.old_exit = getattr(sys, 'exit') 
     sys.stderr = self._stderr 

     def mock_exit(): 
      raise Exception 
     sys.exit = mock_exit 

    def __exit__(self, exc_type, exc_val, exc_tb): 
     self._stderr.flush() 
     sys.stderr = self.old_stderr 
     sys.exit = self.old_exit 

     self._stderr.close() 

和它的用法:

def test_invalid_args(self): 
    with RedirectedEnv(stderr=tempfile.NamedTemporaryFile()): 
     for args in [['-id', '123456789.00'], ['-i'], ['-i', '0'], ['-i', '../some_invalid_path/not_exist.json']]: 
      try: 
       self.parser.parse(args) 
      except Exception: 
       sys.stderr.flush() 
       self.assertTrue(sys.stderr.readlines()[0].startswith("usage:")) <<-- here I need help 

是否有某种优雅的方式来做到这一点? (不要弄得enumeratetell()seek())也许有一些FIFO queue与文件接口?

+0

修复类定义中的缩进 – Leva7

+0

为什么'seek'乱七八糟?不应该'try'在每个循环中截断文件,并且不应该将异常寻找到文件的前面并读取一行?你的测试案例有点奇怪,它捕获了所有的异常,但似乎没有区分选项列表何时应该引发异常和何时不应该引发异常。这些测试中的一些应该通过而其他测试失败? – tdelaney

+0

所有应该失败。我嘲笑sys.exit以防止argparser退出解释器,检查正确的使用信息。也许这不是最好的方法)我用“wb +”打开文件,它添加内容到最后,而不是重写它,所以我不能只求偏移量= 0。我错过了什么吗? – Constantine

回答

1

您可以为每个测试创建一个新文件,然后在前面寻找它的价值。由于您不使用文件名,因此我转移到了TemporaryFile

def test_invalid_args(self): 
    for args in [['-id', '123456789.00'], ['-i'], ['-i', '0'], ['-i', '../some_invalid_path/not_exist.json']]: 
     with RedirectedEnv(stderr=tempfile.TemporaryFile()): 
      try: 
       self.parser.parse(args) 
       raise AssertionError("should have failed") 
      except Exception: 
       sys.stderr.seek(0) 
       self.assertTrue(sys.stderr.readline().startswith("usage:")) 
+0

谢谢,那正是我想要的。紧凑和富有表现力的,imho。 – Constantine