Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Comment tester la gestion des arguments passé à un script ?

+6 votes

J’ai un script du type :

def main(arg):
    return arg

if __name__ == '__main__':
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument('a')
    args = parser.parse_args()
    main(args.a)

Comment écrire un test unitaire pour vérifier que si j’appelle:

monscript.py aval

J’appelle bien main(aval) ?

Mon fichier de test (py.test):

 import os
 from unittest.mock import MagicMock
 import monmodule


def test_call():
    monmodule.main = MagicMock()
    os.system("python monmodule.py aval")
    monmodule.main.assert_called_with('aval')
demandé 10-Jun-2015 par Ryzz (178 points)

1 Réponse

+8 votes

Dans ton cas il faut isoler le parsing des arguments et la fonction main et le rendre indépendants :

from argparse import ArgumentParser

def parse_arg(args=None):
    parser = ArgumentParser()
    parser.add_argument('a')
    return parser.parse_args(args)

def main(arg):
    return arg

if __name__ == '__main__':
    main(parse_arg(sys.argv))

Dans tes tests:

def test_argparsing():
    args = parse_arg(['./test.py', "foo"])
    assert args.a == 'foo'

def test_main():
    class Foo:
        a = 'foo'
    assert main(Foo().a) == 'foo'
répondu 10-Jun-2015 par Sam (4,980 points)
edité 21-Aou-2015 par Sam

C'est chaud, je comprends la logique mais absolument pas comment designer les tests. J'ai un souci dans le même genre, je vais ouvrir une nouvelle question (celle-ci répond à une de celles que je me posais).

C'est normal, au début on a toujours du mal à imaginer comment on doit tester. La base logique c'est : chaque bout de code qu'on veut tester doit avoir une entrée configurable (avec une valeur par défaut saine) et une sortie facilement récupérable. Ici, au lieu d'utiliser les arguments du script en entrée directement, on fait une fonction qui prend n'importe quelle liste de strings (donc on peut les configurer pendant les tests), mais on lui donne par défaut sys.argv en param. On retourne le parseur afin de pouvoir tester la valeur facilement.

...