Supposons qu'il existe un tel analyseur.
main.py
__version__ = '0.0.1'
def prepare_parser():
parser = ArgumentParser(description=(__doc__),
formatter_class=RawDescriptionHelpFormatter)
parser.add_argument('-d', '--debug', action='store_true',
help='Show debug log')
parser.add_argument('-v', '--version', action='version',
version=__version__,
help='Show version and exit')
return parser
Supposons que vous souhaitiez tester que cette partie de version peut être utilisée correctement.
Le problème est que `` parser.parse_args (['-v']) '' fera voler SystemExit à ce stade.
>>> from main import prepare_parser
>>> parser = prepare_parser()
>>> args = parser.parse_args(['-v'])
0.0.1
$ <--L'interpréteur s'est terminé car la sortie système vole.
Ceci est une spécification de l'action de version d'argparse.
'version' - This expects a version= keyword argument in the add_argument() call, and prints version information and exits when invoked:
https://docs.python.org/3.6/library/argparse.html#action
Je ne veux pas que `` sys.exit () '' vole avec désinvolture au milieu d'un test unitaire. En outre, je veux confirmer que la version est sortie correctement.
Il peut y avoir un correctif (https://docs.python.jp/3/library/unittest.mock-examples.html#patch-decorators), mais si possible, je voudrais traiter le contenu d'argparse comme une boîte noire.
Essayez ce qui suit.
tests.py
from contextlib import contextmanager
from io import StringIO
import unittest
import sys
from main import prepare_parser, __version__
@contextmanager
def capture_stdout(command, *args, **kwargs):
out, sys.stdout = sys.stdout, StringIO()
try:
command(*args, **kwargs)
finally:
sys.stdout.seek(0)
yield sys.stdout.read()
sys.stdout = out
class MyTest(unittest.TestCase):
def test_version(self):
parser = prepare_parser()
with self.assertRaises(SystemExit):
with capture_stdout(parser.parse_args, ['-v']) as output:
self.assertIsNotNone(output)
self.assertEqual(__version__, output.rstrip())
with self.assertRaises(SystemExit):
with capture_stdout(parser.parse_args,
['--version']) as output:
self.assertIsNotNone(output)
self.assertEqual(__version__, output.rstrip())
if __name__ == '__main__':
unittest.main()
En demandant au gestionnaire de contexte de fournir la chaîne qui a été envoyée à stdout lorsque l'exception a été ignorée, en espérant que `` SystemExit '' serait ignoré.
Je suis venu pour pouvoir tester.
Lors de la mise en commentaire de la partie facultative qui analyse `` -v '', etc.
$ python tests.py
usage: tests.py [-h] [-d]
tests.py: error: unrecognized arguments: -v
F
======================================================================
FAIL: test_version (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests.py", line 26, in test_version
self.assertEqual(__version__, output.rstrip())
AssertionError: '0.0.1' != ''
- 0.0.1
+
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Si vous commentez dans
$ python tests.py
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Je ne pense pas que ce soit le genre de test que je veux faire. Ce test est-il vulnérable ...? Je ne suis pas sûr.
Y a-t-il un meilleur moyen?
Recommended Posts