Introduction à se moquer de Python

Mocking est une bibliothèque de tests en Python. Il vous permet de remplacer des parties de votre système testé par des objets fictifs et de faire des affirmations sur la manière dont elles ont été utilisées. Ce tutoriel expliquera en détail ce qu'est le moquage et comment l'utiliser dans les applications Python..

Qu'est-ce qui se moque?

Mocking est une bibliothèque de tests en Python qui vous permet de remplacer des parties de votre système en cours de test par des objets fantaisie et de faire des affirmations sur la manière dont elles ont été utilisées..

En Python, le mocking est réalisé en remplaçant des parties de votre système par des objets fictifs à l'aide du module unittest.mock. Ce module contient un certain nombre de classes et de fonctions utiles, à savoir la fonction patch (en tant que décorateur et gestionnaire de contexte) et la classe MagicMock. Ces deux composants sont très importants pour réaliser des moqueries en Python..

Un appel de fonction fictif renvoie généralement une valeur prédéfinie immédiatement. Les attributs et les méthodes d'un objet fantaisie sont également définis dans le test, sans créer l'objet réel..

Le mocking vous permet également de renvoyer des valeurs prédéfinies à chaque appel de fonction lors de l'écriture de tests. Cela vous permet d'avoir plus de contrôle lors des tests.

Conditions préalables

Mock est disponible dans Python 3, mais si vous utilisez une version Python ci-dessous
3.3, vous pouvez toujours utiliser unittest.mock en l'important comme une bibliothèque séparée comme si.

$ pip install mock

Avantages de se moquer

Certains des avantages de se moquer incluent:

  1. Eviter trop de dépendances. Le moquage réduit la dépendance des fonctions. Par exemple, si vous avez une fonction A classe qui dépend d'une fonction B, vous devrez écrire quelques tests unitaires couvrant les fonctionnalités fournies par la fonction B. Supposons que le code augmente à l'avenir et que vous ayez plus de fonctions, c'est-à-dire que A dépend sur B, B dépend de C et C dépend de D. Si une erreur est introduite dans Z, tous vos tests unitaires échoueront..
  2. Surcharge réduite. Cela s'applique aux fonctions gourmandes en ressources. Une maquette de cette fonction réduirait l'utilisation inutile de ressources pendant les tests, réduisant ainsi le temps d'exécution des tests..
  3. Contourner les contraintes de temps dans les fonctions. Cela s'applique aux activités planifiées. Imaginez un processus programmé pour s'exécuter toutes les heures. Dans une telle situation, le fait de se moquer de la source de temps vous permet de tester cette logique de manière à ce que votre test ne soit pas exécuté pendant des heures, en attendant que le temps passe..

Usage

L'utilisation de moquer est simple comme:

>>> from mock import Mock >>> mock = Mock (return_values ​​= 10) >>> mock (1,4, foo = 'bar')  >>> mock.return_values ​​10 

Ici, nous importons le module fictif, créons un objet fictif et spécifions des valeurs de retour. Lorsque l'objet fictif est appelé, nous voulons qu'il puisse renvoyer certaines valeurs. Dans notre cas, nous voulons que l'objet simulé renvoie une valeur de 10. Si nous appelons l'objet simulé avec les arguments (1, 4, foo = 'bar'), le résultat sera la valeur 10 définie comme valeur de retour.

Vous pouvez également déclencher des exceptions à l'intérieur de simulacres:

>>> mock = Mock (side_effect = KeyError ('foobar'))> >>> mock () Traceback (l'appel le plus récent en dernier):… KeyError: 'foobar'

le Effets secondaires l'argument vous permet d'effectuer certaines tâches, telles que le déclenchement d'une exception lorsqu'un simulacre est appelé.

Exemple

Considérons cette fonction simple:

demandes d'importation def api (): response = requests.get ('https://www.google.com/') renvoie la réponse

Cette fonction effectue une demande d'API sur la page Web de Google et renvoie une réponse..

Le cas de test simple correspondant sera le suivant:

import unittest de la classe principale d'importation API TetsApi (unittest.TestCase): def test_api (self): assert api () == 200

L'exécution du test ci-dessus devrait donner un résultat comme suit:

---------------------------------------------------------------------- A couru 1 test en 3.997s OK 

Introduisons le moquage à cet exemple, et le test résultant avec le module Mock sera comme indiqué ci-dessous:

import unittest from mock import Mock from mock import demande de correctif d'importation demande d'importation de classe unittest TetsApi (unittest.TestCase): def test_api (self): avec patch.object (demandes, 'get') comme get_mock: get_mock.return_value = mock_response = Mock ( ) mock_response.status_code = 200 assert api () == 200

L'exécution du test ci-dessus devrait donner un résultat comme suit:

---------------------------------------------------------------------- A couru 1 test en 0.001s OK

Comme indiqué ci-dessus, le module de mocking prend moins de temps pour effectuer le même appel API que le scénario de test normal..

Exemple plus grand

Supposons que vous avez un script qui interagit avec une API externe et appelle cette API chaque fois qu'une fonction donnée est appelée. Dans cet exemple, nous allons utiliser l'API Twitter pour implémenter un script Python qui sera publié sur la page de profil Twitter..

Nous ne voulons pas poster de messages sur Twitter chaque fois que nous testons le script, et c'est là que Mocking entre en jeu..

Commençons. Nous allons utiliser la bibliothèque python-twitter, et la première chose à faire est de créer un dossier. python_mock et, dans le dossier, créer deux fichiers, à savoir tweet.py et mock_test.py.

Écrivez le code suivant dans le fichier tweet.py.

# Pip installer importation twitter # python-twitter définissent les informations d'authentification consumer_key = 'iYD2sKY4NC8teRb9BUM8UguRa' consumer_secret = 'uW3tHdH6UAqlxA7yxmcr8FSMSzQIBIpcC4NNS7jrvkxREdJ15m' access_token_key = '314746354-Ucq36TRDnfGAxpOVtnK1qZxMfRKzFHFhyRqzNpTx7wZ1qHS0qycy0aNjoMDpKhcfzuLm6uAbhB2LilxZzST8w' access_token_secret = '7wZ1qHS0qycy0aNjoMDpKhcfzuLm6uAbhB2LilxZzST8w' def post_tweet (api, bip): # après le statut tweet = api.PostUpdate (tweet) retourne def main (): api = twitter.Api (consumer_key = consumer_secret = consumer_secret, access_token_key = access_token_key, access_token_secret = access_token_secret) message = raw_input ("Entrez votre tweet:") __name__ == '__main__': main () 

Dans le code ci-dessus, nous importons d’abord la bibliothèque Twitter, puis définissons les informations d’authentification, que vous pouvez facilement obtenir à partir de la page Twitter Apps..

L'API Twitter est exposée via le twitter.Api classe, nous créons donc la classe en passant nos jetons et nos clés secrètes.

le post_tweet la fonction prend un objet d'authentification et le message, puis poste le tweet sur le profil Twitter.

Nous procédons ensuite et simulons l'appel de l'API à Twitter afin que l'API ne publie pas sur Twitter à chaque appel. Allez-y et ouvrez le mock_test.py déposer et ajouter le code suivant.

# mock_test.py #! / usr / bin / env import python unittest depuis import mock Classe d'importation tweet Mock TweetTest (unittest.TestCase): def test_example (self): mock_twitter = Mock () tweet.post_tweet (mock_twitter, "création d'une tâche" Application Manager utilisant Ionic: Partie 1 ") mock_twitter.PostUpdate.assert_called_with (" Création d'une application Gestionnaire de tâches utilisant Ionic: Partie 1 ") si __name__ == '__main__': unittest.main ()

L'exécution du test ci-dessus devrait donner un résultat comme suit:

---------------------------------------------------------------------- A couru 1 test en 0.001s OK 

Conclusion

Ce didacticiel a couvert la plupart des notions de base relatives aux moqueries et à la façon de les utiliser pour effectuer des appels d'API externes. Pour plus d'informations, consultez la documentation officielle moqueuse de Python. Vous pouvez également trouver des ressources supplémentaires sur l'authentification avec l'API Twitter dans ce tutoriel..

De plus, n'hésitez pas à voir ce que nous avons disponible à la vente et à étudier sur le marché Envato, n'hésitez pas à poser des questions et à fournir vos précieux commentaires en utilisant le flux ci-dessous..