After a little hack, I found something that will pass the test. Suggestions for removing a welcoming greeting.
In my main program, I defined parse_args with some additional key arguments that will only be used for testing.
def parse_args(args, prog = None, usage = None): PARSER = argparse.ArgumentParser(prog=prog, usage=usage) ....
Then, in the test class to test the parser, add these parameters to suppress usage information and error help information as much as possible.
class ArgParseTestCase(unittest.TestCase): def __init__(self, *args, **kwargs): self.testing_params = {'prog':'TESTING', 'usage':''} super(ArgParseTestCase, self).__init__(*args, **kwargs)
In the test file, this context manager defined this answer :
from contextlib import contextmanager from io 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 then modified the test in my question above to be something like:
def test_no_action_error(self): '''Test if no action produces correct error''' with self.assertRaises(SystemExit) as cm, capture_sys_output() as (stdout, stderr): args = parse_args([' '], **self.testing_params) self.assertEqual(2, cm.exception.code) self.assertEqual('usage: \n TESTING: error: No action requested, add -process or -upload', stderr.getvalue())
Now the extra text at the beginning of assertEqual not very ... but the test passes, so I'm happy.