Search code examples
pythonnosecoverage.py

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


I want to use nose and coverage in my project. 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.

How do I turn the argparse off, but during testing only? Nose says all my tests fail because of the bad argument.


Solution

  • 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. 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. Replace it with parse_known_args() instead.

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

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