如何在 python 中使用 nosetests 同时还为 argparse 使用 passing/accepting 参数?

How to use nosetests in python while also passing/accepting arguments for argparse?

我想在我的项目中使用 nosecoverage。当我 运行 使用 --with-coverage 参数时,我的程序参数解析模块变得疯狂,因为根据它“--with-coverage”不是真正的参数。

如何仅在测试期间关闭 argparse?鼻子说我所有的测试都失败了,因为争论不好。

实际上,我前几天 运行 自己也参与了这个问题。您不需要 "disable" 您的解析模块或任何东西。您可以做的是更改使用 argparse 的模块以忽略它接收到的那些它无法识别的参数。这样它们仍然可以被其他脚本使用(例如,如果您的命令行调用将辅助参数传递给另一个程序执行)。

如果没有您的代码,我将假定您在 argparse.ArgumentParser 实例上使用标准 parse_args() 方法。将其替换为 parse_known_args()

然后,每当您随后引用解析参数 Namespace 对象时,您都需要指定和元素,特别是 0。而 parse_args() returns 单独的 args 对象, parse_known_args() returns 元组:第一个元素是已解析的 known 参数,后一个元素包含忽略的无法识别的参数(稍后您可以 use/pass在您的 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
        #...

作为变通方法,您可以在当前工作目录中使用 .noserc or nose.cfg,而不是带有命令行参数的 运行 nose:

[nosetests]
verbosity=3
with-coverage=1

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

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

这是全局变量不好的一个例子。 sys.argv是全局的,全进程共享。您已经通过依赖全局限制了代码的模块化,从而限制了代码的可测试性。

我了解到您可以使用 nose-testconfig, or otherwise use mock 替换 调用(未测试)。尽管我同意@Ned Batchelder 的观点,但它会质疑问题的结构。