使docopt解析单元测试中包含空格的参数



我在获取docopt以将包含空格的参数解析到适当的字典对象中以用于单元测试时遇到问题。

以下是我目前用于构建docopt解析的参数列表的代码:

testargs = []
def clear_args():
    testargs[:] = []
    return
def add_testfiles(file1='defaultfile1.txt', file2='defaultfile2.txt'):
    clear_args()
    testargs.append('--debug')
    testargs.append(file1)
    testargs.append(file2)
    return
def parse_args(optlist):
    argstr = ' '.join(optlist)
    return docopt(downpost.__doc__, argv=argstr)

我为之编写单元测试的代码有两个测试,它们分别给出了以下参数:

-t <title>  # <title> can be any string (with spaces) inside quotation marks
"A Filename with Spaces.txt"  # any filename as long as it's in quotation marks

例如,要添加-t参数,我会这样做:

def test_exampleunittest(self):
    add_testfiles()
    testargs.append('-t "This is the title I want"')
    self.args = parse_args(testargs)
    self.post = myPythonScript.process(self.args)
    self.assertEqual(self.post['Subject'], 'This is the title I want')

如果我用上述参数运行我自己测试的脚本,它们会被接受,没有任何问题,并且输出是预期的。

然而,如果我运行使用包含空格的参数的单元测试,我会得到以下结果:

DocoptExit: Usage: myPythonScript [options] <file_1> <file_2>

其他需要相同dict对象(包含相同参数)的单元测试也可以正常工作。

我应该在代码中更改什么以使docopt像往常一样解析参数?

docopt将argv参数作为字符串或列表。

  • 如果它是一个列表,它将把列表中的每个项解释为一个单独的参数
  • 如果它是一个字符串,它将使用.split()将该字符串拆分为一个列表。这样你就可以去掉所有的空白

因此,为了使测试正常工作,您应该传递一个列表,而不是将其连接到字符串argstr = ' '.join(testargs)中。

这种混淆可能是由于向argv传递字符串是未记录的。事实上,它不是API的一部分,只是一个实现细节。您不应该依赖于docopt argv接受字符串这一事实——这可能会消失。但是docopt将始终接受argv的列表。