Comment puis-je simuler la saisie de l'utilisateur au milieu d'une fonction appelée par un test d'unité (à l'aide de Python 3's Unitest)? Par exemple, j'ai une fonction et la sortie est basée sur l'entrée: p>
Je voudrais que mon test d'unité exécute foo () code> qui est la sortie que je teste. Dans la fonction
FOO () code>, il demande une entrée utilisateur: p>
x = entrée (msg) code> p>
blockQuote>
Imprimer ("entrée: {0}". Format (x)) CODE> P>
blockQuote>
foo () code>, entrez une entrée et comparez le résultat avec le résultat attendu. P>
3 Réponses :
J'ai régulièrement ce problème lorsque j'essaie de tester le code qui apporte des dialogues pour la saisie de l'utilisateur, et la même solution doit fonctionner pour les deux. Vous devez fournir une nouvelle fonction lié au nom Évidemment, vous pourriez également allumer le contenu du message code> code> si cela était pertinent et renvoyez le type de données de votre choix de votre choix. Vous pouvez également faire quelque chose de plus flexible et général qui permet de réutiliser la même méthode de remplacement dans un certain nombre de situations: p> et ensuite vous injecterais une fonction partielle dans quitter entrée code> dans votre péril de test avec la même signature que la fonction Standard
Fonction CODE> de la fonction qui renvoie simplement une valeur de test sans demander à l'utilisateur. . Selon la manière dont vos tests et vos tests sont configurés, cette injection peut être effectuée de plusieurs manières, donc je laisserai cela comme un exercice pour le lecteur, mais votre méthode de remplacement sera quelque chose de simple comme:
entrée code>: p>
test_input_a code> et
test_input_b code> comme des fonctions qui prennent un seul message
" / Code> Argument, avec l'argument code> Reveal code> déjà lié. p> p>
J'ai fini par faire quelque chose de similaire à cela. J'ai créé une fonction Test_Input "Test_input (MSG)" qui remplacerait le comportement par défaut de l'entrée sur le module que je teste: "module.input = test_input". Je définit la valeur d'entrée simulée avec une variable globale "Sample_Input" défini avant la fonction Test_Input et défini avant chaque cas de test.
Pouvez-vous fournir un exemple de comment faire l'injection avec la fonction foo code> fourni dans la question? Je ne peux pas comprendre comment l'obtenir correctement.
avoir des difficultés à tester certains composants en raison de dépendances, il s'agit généralement d'un signe de mauvais design. Votre fonction FOO code> ne doit pas dépendre de la fonction globale de l'entrée code> code>, mais plutôt d'un paramètre. Ensuite, lorsque vous exécutez le programme dans un environnement de production, vous filez les choses de manière à ce que le
foo code> soit appelé à l'aide de ce que
entrée code> retourne. Donc,
FOO code> devrait lire:
def foo(input):
# do something with input
Peut-être, mais quelque part i>, quelqu'un rassemble cette contribution. Lorsque vous souhaitez tester la méthode qui le faisait, vous devrez soit recourir à des outils de test fonctionnels qui manipulent une interface utilisateur à tester à ce niveau, ou faire une certaine injection. Bien sûr, vous devriez également faire des tests fonctionnels qui manipule l'interface utilisateur, mais il faut utiliser simplement pour tester l'interface utilisateur (par exemple, cette entrée () prend l'entrée que vous avez fournie) et ne pas avoir de défaillances saignées dans la terre des détails de la mise en œuvre non-UI. .
Nick, si le système à tester est une application héritée, dans laquelle le refactoring est très difficile ou qu'il faut du temps pour le faire, mais vous voulez vraiment avoir des tests de caractérisation (qui soutiendrez réellement refactoring), alors oui, je voudrais Utilisez votre méthode. Mais si la demande est en cours de développement, elle devrait être refactable afin que les tests d'unités soient faciles à écrire.
@Nick Bastin: "Peut-être, mais quelque part, quelqu'un rassemble cette entrée. Lorsque vous souhaitez tester la méthode qui fait cela ..." Le foo (entrée) code> est-ce. Il n'y a pas de "quelque part" d'autre que cela doit être testé.
@ S.Lott: Je ne sais pas pourquoi vous pensez que le code qui appelle l'appel d'entrée de la bibliothèque standard n'a pas besoin d'être testé. Oui, dans ce cas super trivial i>, ce code pourrait simplement appeler l'entrée et appeler votre méthode FOO (entrée), mais de nombreuses instances d'interaction utilisateur ne sont-elles pas aussi simples. (Et vous avez évidemment besoin de tester ce code par l'intermédiaire de la manipulation de l'interface utilisateur).
Je pense que la meilleure approche consiste à envelopper la fonction code> d'entrée code> sur une fonction personnalisée et de moquer de ce dernier. Juste comme décrit ici: Python Entrée RAW in Unditest P>