代码之家  ›  专栏  ›  技术社区  ›  Luis Uzher

如何在python中使用nosetests,同时传递/接受argparse的参数?

  •  5
  • Luis Uzher  · 技术社区  · 9 年前

    我想用 nose coverage 在我的项目中。当我用鼻子 --with-coverage 参数,我的程序参数解析模块变得疯狂,因为根据它,“--withcoverage”不是一个真正的参数。

    如何关闭argparse,但仅在测试期间?Nose说我所有的测试都失败了,因为这场糟糕的争论。

    4 回复  |  直到 9 年前
        1
  •  5
  •   TCAllen07    9 年前

    事实上,前几天我自己也遇到了这个问题。您不需要“禁用”解析模块或任何东西。您可以做的是更改使用 argparse 忽略它收到的那些它不认识的论点。这样,其他脚本仍然可以使用它们(例如,如果命令行调用将次要参数传递给另一个程序执行)。

    如果没有你的代码,我会假设你使用的是标准 parse_args() 方法 argparse.ArgumentParser 例子替换为 parse_known_args() 相反

    然后,每当您随后引用解析的参数时 Namespace 对象,您需要指定和元素,特别是0。虽然 parse_args() 仅返回args对象, 解析已知参数() 返回元组:第一个元素是已解析的 已知的 参数,而后一个元素包含被忽略的无法识别的参数(如果需要,稍后可以在Python代码中使用/传递这些参数)。

    以下是我自己项目的示例更改:

    class RunArgs(object):
        '''
        A placeholder for processing arguments passed to program execution.
        '''
    
        def __init__(self):
            self.getArgs()
            #self.pause = self.args.pause  # old assignment
            self.pause = self.args[0].pause  # new assignment
            #...
    
        def __repr__(self):
            return "<RunArgs(t=%s, #=%s, v=%s)>" % (str(x) for x in (self.pause,self.numreads,self.verbose))
    
        def getArgs(self):
            global PAUSE_TIME
            global NUM_READS
            parser = argparse.ArgumentParser()
            parser.add_argument('-p', '--pause', required=False, 
                type=self.checkPauseArg, action='store', default=PAUSE_TIME)
            parser.add_argument('-n', '--numreads', required=False, 
                type=self.checkNumArg, action='store', default=NUM_READS)
            parser.add_argument('-v', '--verbose', required=False,
                action='store_true')
            #self.args = parser.parse_args()  # old parse call
            self.args = parser.parse_known_args()  # new parse call
            #...
    
        2
  •  2
  •   Hayk    9 年前

    我已经读到你可以使用 nose-testconfig ,或以其他方式使用 mock 代替 调用(而不是测试它)。虽然我同意@Ned Batchelder的观点,但这就需要质疑问题的结构。

        3
  •  1
  •   alecxe    9 年前

    作为解决方法,您可以使用 .noserc or nose.cfg 在当前工作目录中:

    [nosetests]
    verbosity=3
    with-coverage=1
    

    不过,我同意 parse_known_args() 是更好的解决方案。

        4
  •  0
  •   Ned Batchelder    9 年前

    听起来你有测试运行你的代码,然后你的代码使用argparse,它隐式地从sys.argv中提取参数。这是一种糟糕的代码结构方式。测试中的代码应该以其他方式将参数传递给它,以便您可以控制它看到的参数。

    这就是为什么全局变量不好的一个例子。sys.argv是全局的,由整个进程共享。通过依赖全局性,您限制了代码的模块性,因此也限制了可测试性。