Testing Argparse module: suppress help message

I am writing test cases for implementing argparse. I intend to test the -h function. The following code does this. But it also infers usage for the script. Is there any way to suppress this?

self.assertRaises(SystemExit, arg_parse_obj.parse_known_args, ['-h']) 

Also, can we check if the exception number is abandoned? For example, '-h' throws SystemExit: 0 , while an invalid or insufficient argument args SystemExit: 2 . Is there any way to check the numerical code?

+4
python unit-testing argparse
Sep 06 '13 at 6:55 on
source share
3 answers

When testing for exception codes, use self.assertRaises() as the context manager ; this gives you access to the .code exception, allowing you to test the .code attribute:

 with self.assertRaises(SystemExit) as cm: arg_parse_obj.parse_known_args(['-h']) self.assertEqual(cm.exception.code, 0) 

To "suppress" or test the output, you will need to capture either sys.stdout or sys.stderr , depending on the output of argparse (help text goes to stdout ). You can use the context manager for this:

 from contextlib import contextmanager from StringIO import StringIO @contextmanager def capture_sys_output(): capture_out, capture_err = StringIO(), StringIO() current_out, current_err = sys.stdout, sys.stderr try: sys.stdout, sys.stderr = capture_out, capture_err yield capture_out, capture_err finally: sys.stdout, sys.stderr = current_out, current_err 

and use them like:

 with self.assertRaises(SystemExit) as cm: with capture_sys_output() as (stdout, stderr): arg_parse_obj.parse_known_args(['-h']) self.assertEqual(cm.exception.code, 0) self.assertEqual(stderr.getvalue(), '') self.assertEqual(stdout.getvalue(), 'Some help value printed') 

Context managers are nested here, but in Python 2.7 and later you can also combine them into one line; however, this may result in exceeding the recommended limit of 79 characters.

+15
Sep 06 '13 at 7:14
source share

Mock can do this by providing you with the same functions as Martijn Pieters answer, but without having to write your own function:

 from unittest.mock import MagicMock, patch argparse_mock = MagicMock() with patch('argparse.ArgumentParser._print_message', argparse_mock): with self.assertRaises(SystemExit) as cm: arg_parse_obj.parse_known_args(['-h']) 
Patch

also works as a decorator. If you have multiple instances where argparse printing should be suppressed, you can do this as a decorator and not use a bunch of nested statements.

+1
Nov 16 '15 at 10:14
source share

Some uses for ['-h'] include:

 parser.print_help() # formats the help, prints it and exits parser.format_help() # format the help without printing or exit parser.exit # can be modified to not exit, such as for a parser subclass parser.error # default print usage and call parser.exit 

This is part of the public API.

The argparse test file ( test_argparse.py ) also gives an idea of ​​how to test things. For many tests, it uses a subclass of ArgumentParser , which has its own error method.

0
Sep 06 '13 at 16:00
source share



All Articles