如何在 python 中使用 nosetests 同时还为 argparse 使用 passing/accepting 参数?
How to use nosetests in python while also passing/accepting arguments for argparse?
我想在我的项目中使用 nose
和 coverage
。当我 运行 使用 --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 的观点,但它会质疑问题的结构。
我想在我的项目中使用 nose
和 coverage
。当我 运行 使用 --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 的观点,但它会质疑问题的结构。