I would like to set
sys.argv
so I can unit test passing in different combinations. The following doesn't work:
#!/usr/bin/env python import argparse, sys def test_parse_args(): global sys.argv sys.argv = ["prog", "-f", "/home/fenton/project/setup.py"] setup = get_setup_file() assert setup == "/home/fenton/project/setup.py" def get_setup_file(): parser = argparse.ArgumentParser() parser.add_argument('-f') args = parser.parse_args() return args.file if __name__ == '__main__': test_parse_args()
Then running the file:
pscripts % ./test.py File "./test.py", line 4 global sys.argv ^ SyntaxError: invalid syntax pscripts %
To use, sys. argv in a Python script, we need to impo r t the sys module into the script. Like we import all modules, "import sys" does the job. Ideally, we want this at the top of the script, but anywhere before we use the sys.
argv() is an array for command line arguments in Python. To employ this module named “ sys ” is used. sys. argv is similar to an array and the values are also retrieved like Python array.
The command to run the tests is python -m unittest filename.py . In our case, the command to run the tests is python -m unittest test_utils.py .
Changing sys.argv at runtime is a pretty fragile way of testing. You should use mock's patch functionality, which can be used as a context manager to substitute one object (or attribute, method, function, etc.) with another, within a given block of code.
The following example uses patch()
to effectively "replace" sys.argv
with the specified return value (testargs
).
try: # python 3.4+ should use builtin unittest.mock not mock package from unittest.mock import patch except ImportError: from mock import patch def test_parse_args(): testargs = ["prog", "-f", "/home/fenton/project/setup.py"] with patch.object(sys, 'argv', testargs): setup = get_setup_file() assert setup == "/home/fenton/project/setup.py"
test_argparse.py
, the official argparse
unittest file, uses several means of setting/using argv
:
parser.parse_args(args)
where args
is a list of 'words', e.g. ['--foo','test']
or --foo test'.split()
.
old_sys_argv = sys.argv sys.argv = [old_sys_argv[0]] + args try: return parser.parse_args() finally: sys.argv = old_sys_argv
This pushes the args onto sys.argv
.
I just came across a case (using mutually_exclusive_groups
) where ['--foo','test']
produces different behavior than '--foo test'.split()
. It's a subtle point involving the id
of strings like test
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With