这里的窍门是抓住
SystemExit而不是
ArgumentError。这是您改写的测试以捕获
SystemExit:
#!/usr/bin/env python3import argparseimport unittestclass SweepTestCase(unittest.TestCase): """Tests that the merParse class works correctly""" def setUp(self): self.parser=argparse.ArgumentParser() self.parser.add_argument( "-c", "--color", type=str, choices=["yellow", "blue"], required=True) def test_required_unknown(self): """ Try to perform sweep on something that isn't an option. """ args = ["--color", "NADA"] with self.assertRaises(SystemExit): self.parser.parse_args(args)if __name__ == '__main__': unittest.main()
现在可以正常运行,并且测试通过:
$ python scratch.pyusage: scratch.py [-h] -c {yellow,blue}scratch.py: error: argument -c/--color: invalid choice: 'NADA' (choose from 'yellow', 'blue').----------------------------------------------------------------------Ran 1 test in 0.001sOK但是,您可以看到正在打印使用情况消息,因此您的测试输出有些混乱。检查使用消息是否包含“无效选择”也可能很好。
您可以通过打补丁来做到这一点
sys.stderr:
#!/usr/bin/env python3import argparseimport unittestfrom io import StringIOfrom unittest.mock import patchclass SweepTestCase(unittest.TestCase): """Tests that the merParse class works correctly""" def setUp(self): self.parser=argparse.ArgumentParser() self.parser.add_argument( "-c", "--color", type=str, choices=["yellow", "blue"], required=True) @patch('sys.stderr', new_callable=StringIO) def test_required_unknown(self, mock_stderr): """ Try to perform sweep on something that isn't an option. """ args = ["--color", "NADA"] with self.assertRaises(SystemExit): self.parser.parse_args(args) self.assertRegexpMatches(mock_stderr.getvalue(), r"invalid choice")if __name__ == '__main__': unittest.main()现在,您仅看到常规测试报告:
$ python scratch.py.----------------------------------------------------------------------Ran 1 test in 0.002sOK
对于pytest用户,这是不检查消息的等效项。
import argparseimport pytestdef test_required_unknown(): """ Try to perform sweep on something that isn't an option. """ parser=argparse.ArgumentParser() parser.add_argument( "-c", "--color", type=str, choices=["yellow", "blue"], required=True) args = ["--color", "NADA"] with pytest.raises(SystemExit): parser.parse_args(args)
Pytest默认情况下捕获stdout / stderr,因此它不会污染测试报告。
$ pytest scratch.py================================== test session starts ===================================platform linux -- Python 3.6.7, pytest-3.5.0, py-1.7.0, pluggy-0.6.0rootdir: /home/don/.PyCharm2018.3/config/scratches, inifile:collected 1 itemscratch.py . [100%]================================ 1 passed in 0.01 seconds ================================
您还可以使用pytest检查stdout / stderr内容:
import argparseimport pytestdef test_required_unknown(capsys): """ Try to perform sweep on something that isn't an option. """ parser=argparse.ArgumentParser() parser.add_argument( "-c", "--color", type=str, choices=["yellow", "blue"], required=True) args = ["--color", "NADA"] with pytest.raises(SystemExit): parser.parse_args(args) stderr = capsys.readouterr().err assert 'invalid choice' in stderr
和往常一样,我发现pytest更易于使用,但是您可以使它在任何一个中都能工作。



