简体   繁体   English

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

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

I want to use nose and coverage in my project. 我想在我的项目中使用nosecoverage When I run nose with --with-coverage argument, my programs argument-parsing module goes nuts because "--with-coverage" isn't a real argument according to it. 当我使用--with-coverage参数运行nose时,我的程序参数解析模块变得疯狂,因为“--with-coverage”根据它不是一个真正的参数。

How do I turn the argparse off, but during testing only? 如何关闭argparse,但仅在测试期间? Nose says all my tests fail because of the bad argument. Nose说我的所有测试都因为不好的论点而失败。

I actually just ran into this issue myself the other day. 实际上我前几天就遇到过这个问题。 You don't need to "disable" your parsing module or anything. 您不需要“禁用”您的解析模块或任何东西。 What you can do is change the module that uses argparse to ignore those arguments it receives that it doesn't recognize. 您可以做的是更改使用argparse的模块,以忽略它接收到的无法识别的参数。 That way they can still be used by other scripts (for example if your command-line call passes secondary arguments to another program execution). 这样,它们仍然可以被其他脚本使用(例如,如果您的命令行调用将辅助参数传递给另一个程序执行)。

Without your code, I'll assume you're using the standard parse_args() method on your argparse.ArgumentParser instance. 没有你的代码,我假设你在argparse.ArgumentParser实例上使用标准的parse_args()方法。 Replace it with parse_known_args() instead. parse_known_args()替换它。

Then, whenever you subsequently reference the parsed-arguments Namespace object, you'll need to specify and element, specifically 0. While parse_args() returns the args object alone, parse_known_args() returns tuple: the first element is the parsed known arguments, and the latter element contains the ignored unrecognized arguments (which you can later use/pass in your Python code, if necessary). 然后,每当你随后引用解析参数Namespace对象时,你需要指定和元素,特别是0.虽然parse_args()返回args对象, parse_known_args()返回tuple:第一个元素是已解析的已知参数,而后一个元素包含忽略的无法识别的参数(如果需要,您可以在以后使用/传递Python代码)。

Here's the example change from my own project: 以下是我自己项目的示例更改:

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
        #...

I've read that you can use nose-testconfig , or otherwise use mock to replace the call (not test it). 我已经读过你可以使用nose-testconfig ,或者用mock替换这个调用(不测试它)。 Though I'd agree with @Ned Batchelder, it begs questioning the structure of the problem. 虽然我同意@Ned Batchelder,但它会质疑问题的结构。

As a workaround, instead of running nose with command-line arguments, you can have a .noserc or nose.cfg in the current working directory: 作为一种变通方法,您可以在当前工作目录中使用.nosercnose.cfg ,而不是使用命令行参数运行鼻子:

[nosetests]
verbosity=3
with-coverage=1

Though, I agree that parse_known_args() is a better solution. 虽然,我同意parse_known_args()是一个更好的解决方案。

It sounds like you have tests that run your code, and then your code uses argparse which implicitly pulls arguments from sys.argv. 听起来你有运行你的代码的测试,然后你的代码使用argparse隐含地从sys.argv中提取参数。 This is a bad way to structure your code. 这是构建代码的不好方法。 Your code under test should be getting arguments passed to it some other way so that you can control what arguments it sees. 您正在测试的代码应该是以其他方式传递给它的参数,以便您可以控制它看到的参数。

This is an example of why global variables are bad. 这是全局变量为什么不好的一个例子。 sys.argv is a global, shared by the entire process. sys.argv是一个全局的,由整个过程共享。 You've limited the modularity, and therefore the testability, of your code by relying on that global. 您依靠全局限制了代码的模块性,从而限制了可测试性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM