Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse commandline args in unittest python

I am creating a test case in python using unittest module.

I did create a parsing argument list that i want to get from user. But when i use that argument while executing the python script, it gives error: "option -i not recognized Usage: testing.py [options] [test] [...]"

code snippet:

class Testclass(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print "Hello Class"

    def test_addnum(self):
        print "Execute the test case"
        #parser = parse_args(['-i'])
        print 'simple_value     =', args.inputfile

    def parse_args():
        parser = argparse.ArgumentParser()
        parser.add_argument('-i', help='input file', dest='inputfile')
        ns, args = parser.parse_known_args(namespace=unittest)
        #args = parser.parse_args()
        return ns, sys.argv[:1] + args

if __name__ == '__main__':
    unittest.main()

The error m getting on executing the above script with -i somefile.txt is:

option -i not recognized
Usage: testing.py [options] [test] [...]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output
  -f, --failfast   Stop on first failure
  -c, --catch      Catch control-C and display results
  -b, --buffer     Buffer stdout and stderr during test runs

Examples:
  testing.py                               - run default set of tests
  testing.py MyTestSuite                   - run suite 'MyTestSuite'
  testing.py MyTestCase.testSomething      - run MyTestCase.testSomething
  testing.py MyTestCase                    - run all 'test*' test methods
                                               in MyTestCase

Any help would be appreciated.

like image 946
Nikita Avatar asked Dec 07 '25 17:12

Nikita


1 Answers

This script captures the -i command, while still allowing unittest.main to do its own commandline parsing:

import unittest

class Testclass(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print "Hello Class"

    def test_addnum(self):
        print "Execute the test case"
        #parser = parse_args(['-i'])
        print 'simple_value     =', args.inputfile

import argparse
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', help='input file', dest='inputfile')
    ns, args = parser.parse_known_args(namespace=unittest)
    #args = parser.parse_args()
    return ns, sys.argv[:1] + args

if __name__ == '__main__':
    import sys
    args, argv = parse_args()   # run this first
    print(args, argv)
    sys.argv[:] = argv       # create cleans argv for main()
    unittest.main()

produces:

1113:~/mypy$ python stack44236745.py -i testname -v
(<module 'unittest' from '/usr/lib/python2.7/unittest/__init__.pyc'>, ['stack44236745.py', '-v'])
Hello Class
test_addnum (__main__.Testclass) ... Execute the test case
simple_value     = testname
ok

----------------------------------------------------------------------
Ran 1 test in 0.000s
OK

It looks rather kludgy, but does seem to work.

The idea is to run your own parser first, capturing the -i input, and putting the rest back into sys.argv. Your definition of parse_args suggests that you are already trying to do that.

like image 120
hpaulj Avatar answered Dec 09 '25 12:12

hpaulj