2

How do I unit test my script for incorrect command line arguments?

For example,

my_script.py -t

should give an error since -t flag is not present, as shown in the code below:

parser = OptionParser()

parser.add_option("-d",
              action="callback",
              callback=get_bios_difference,
              help="Check difference between two files"
              )

(options, args) = parser.parse_args()

if len(sys.argv) == 1:  # if only 1 argument, it's the script name
   parser.print_help()
   exit()
Steve
  • 101
  • 1
  • 7

2 Answers2

0

First, you need a unit to test:

def parse_options(args=None):
    # Duplicating the default behavior of OptionParser.parse_args
    if args is None:
        args = sys.argv[1:]

    parser = OptionParser()

    parser.add_option("-d",
                  action="callback",
                  callback=get_bios_difference,
                  help="Check difference between two files"
                  )

    (options, args) = parser.parse_args(args)

    if not args:
       parser.print_help()
       exit()

Note that we explicitly pass args to parse_args, rather than let it assume sys.argv is to be parsed.

In production, you can call parse_options() and it will work as before. For testing, you can call parse_options([]) or parse_options(["-t"]) or whatever other combination of arguments you want to test.


All that said, you should be using argparse instead of optparse (which has been deprecated for years) in new code.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • I wrote the code. But what am I asserting? When I run my_script.py -t . (which is an invalid argument) the terminal gives me an error my_script.py: error: no such option: -t – Steve Mar 21 '18 at 23:00
  • You want to assert that it raises `SystemExit`; the parser just calls `optparse.error`, which ultimately just calls `sys.exit`. – chepner Mar 22 '18 at 02:50
0

OptionParser

Deprecated since version 2.7: The optparse module is deprecated and will not be developed further; development will continue with the argparse module.

your questions has nothing to do with unittest? there is no need to assert, the nargs=2 defined 2 items needed for --d.

argparse will check the number of args for you, here is parameter.py

import argparse
from pprint import pprint

def get_parser():
    parser = argparse.ArgumentParser(description='example of argparse')

    parser.add_argument('--d', type=str, nargs=2, help='2 files')
    return parser

if __name__ == '__main__':
    parser = get_parser()
    args = parser.parse_args(sys.argv[1:])
    pprint(args)

run with 2 files:

parameter.py --d a b
Namespace(d=['a', 'b'])

When run with 1 parameter

parameter.py --d a
parameter.py: error: argument --d: expected 2 argument(s)
Gang
  • 2,658
  • 3
  • 17
  • 38