Inleiding tot Mocking in Python

Mocking is een bibliotheek voor testen in Python. Hiermee kunt u delen van uw te testen systeem vervangen door schijnobjecten en beweringen doen over hoe ze zijn gebruikt. Deze tutorial zal in detail bespreken wat mocking is en hoe het te gebruiken in Python-applicaties.

Wat is spot?

Mocking is een bibliotheek voor testen in Python waarmee je delen van je geteste systeem kunt vervangen door mock-objecten en beweringen kunt doen over hoe ze zijn gebruikt.

In Python wordt spot uitgevoerd door onderdelen van je systeem te vervangen door mock-objecten met behulp van de module unittest.mock. Deze module bevat een aantal nuttige klassen en functies, namelijk de patchfunctie (als decorateur en contextmanager) en de klasse MagicMock. Deze twee componenten zijn erg belangrijk voor het bereiken van spot in Python.

Een mock-functie-aanroep retourneert meestal onmiddellijk een vooraf gedefinieerde waarde. De attributen en methoden van een onechte object worden ook in de test gedefinieerd, zonder het echte object te creëren.

Met mocking kunt u ook vooraf gedefinieerde waarden naar elke functieaanroep retourneren bij het schrijven van tests. Dit geeft u meer controle tijdens het testen.

voorwaarden

Mock is beschikbaar in Python 3, maar als je hieronder een Python-versie gebruikt
3.3, je kunt nog steeds gebruiken unittest.mock door het als een aparte bibliotheek te importeren, zoals zo.

$ pip install mock

Voordelen van Mocking

Enkele van de voordelen van spot zijn:

  1. Te veel afhankelijkheden vermijden. Bespotten vermindert de afhankelijkheid van functies. Als u bijvoorbeeld een functie A-klasse hebt die afhankelijk is van een functie B, moet u een paar eenheidsonderzoeken schrijven met betrekking tot de functies die worden geleverd door functie B. Laten we zeggen dat de code in de toekomst groter wordt en u meer functies hebt, dwz A hangt ervan af op B, B hangt af van C, en C hangt af van D. Als een fout wordt ingevoerd in Z, mislukken al uw unittests.
  2. Verminderde overbelasting. Dit is van toepassing op resource-intensieve functies. Een schijn van die functie zou tijdens het testen het gebruik van onnodige bronnen verminderen, waardoor de testruntijd zou afnemen.
  3. Omzeil tijdsbeperkingen in functies. Dit is van toepassing op geplande activiteiten. Stel je een proces voor dat gepland is om elk uur uit te voeren. In een dergelijke situatie kunt u met het bespotten van de tijdbron in feite een dergelijke logica testen zodat uw test niet uren hoeft te lopen, wachtend op de tijd die verstrijkt.

Gebruik

Gebruik van bespotten is eenvoudig als:

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

Hier importeren we de mock-module, maken we een mock-object en geven we retourwaarden op. Wanneer het spotobject wordt aangeroepen, willen we dat het een aantal waarden kan retourneren. In ons geval willen we dat het nep-object een waarde van 10 retourneert. Als we het nep-object met de argumenten aanroepen (1, 4, foo = 'balk'), het resultaat is de waarde 10, die werd gedefinieerd als een retourwaarde.

Je kunt uitzonderingen ook binnen moppen als volgt verhogen:

>>> mock = Mock (side_effect = KeyError ('foobar')) >>> mock () Traceback (meest recente oproep laatste): ... KeyError: 'foobar'

De bijwerkingen argument stelt u in staat om bepaalde dingen uit te voeren, zoals het verhogen van een uitzondering wanneer een mock wordt aangeroepen.

Voorbeeld

Overweeg deze eenvoudige functie:

import requests def api (): response = requests.get ('https://www.google.com/') antwoord terugsturen

Deze functie voert een API-aanvraag uit op de Google-webpagina en retourneert een antwoord.

De bijbehorende eenvoudige testcase is als volgt:

import unittest van hoofd import api klasse TetsApi (unittest.TestCase): def test_api (self): assert api () == 200

Het uitvoeren van de bovenstaande test zou een uitvoer moeten geven zoals:

---------------------------------------------------------------------- Ran 1-test in 3.997s OK 

Laten we de spot met dit voorbeeld introduceren, en de resulterende test met de Mock-module zal zijn zoals hieronder getoond:

import unittest from mock import Mock van mock import patch importeer aanvragen import unittest class TetsApi (unittest.TestCase): def test_api (self): met patch.object (requests, 'get') als get_mock: get_mock.return_value = mock_response = Mock ( ) mock_response.status_code = 200 assert api () == 200

Het uitvoeren van de bovenstaande test zou een uitvoer moeten geven zoals:

---------------------------------------------------------------------- Ran 1-test in 0.001s OK

Zoals hierboven gezien, kost de spotmodule minder tijd om hetzelfde API-gesprek te voeren als de normale testcase.

Groter voorbeeld

Stel dat u een script hebt dat communiceert met een externe API en naar die API belt wanneer een bepaalde functie wordt aangeroepen. In dit voorbeeld gaan we de Twitter API gebruiken om een ​​Python-script te implementeren dat zal posten op de Twitter-profielpagina.

We willen geen berichten plaatsen op Twitter elke keer als we het script testen, en dat is waar Mocking in komt.

Laten we beginnen. We zullen de python-twitter-bibliotheek gebruiken en het eerste dat we zullen doen, is een map maken python_mock en maak in de map twee bestanden, namelijk tweet.py en mock_test.py.

Schrijf de volgende code naar het bestand tweet.py.

# Pip installeren python-twitter import twitter # definiëren authentificatiegeloofsbrieven gebruikerscode = 'iYD2sKY4NC8teRb9BUM8UguRa' consumer_secret = 'uW3tHdH6UAqlxA7yxmcr8FSMSzQIBIpcC4NNS7jrvkxREdJ15m' access_token_key = '314.746.354-Ucq36TRDnfGAxpOVtnK1qZxMfRKzFHFhyRqzNpTx7wZ1qHS0qycy0aNjoMDpKhcfzuLm6uAbhB2LilxZzST8w' access_token_secret = '7wZ1qHS0qycy0aNjoMDpKhcfzuLm6uAbhB2LilxZzST8w' def post_tweet (api, tweet): # bericht tweet status = api.PostUpdate (tweet) return status def main (): api = twitter.Api (consumer_key = consumer_key, consumer_secret = consumer_secret, access_token_key = access_token_key, access_token_secret = access_token_secret) message = raw_input ("Voer je tweet in:") post_tweet (api, bericht) if __name__ == '__main__': main () 

In de bovenstaande code importeren we eerst de Twitter-bibliotheek en definiëren we vervolgens de authenticatiegegevens, die u gemakkelijk kunt ophalen op de Twitter Apps-pagina.

De Twitter API wordt ontsloten via de twitter.Api klasse, dus we maken de klas door onze tokens en geheime sleutels door te geven.

De post_tweet functie neemt een authenticatieobject en het bericht op en plaatst vervolgens de tweet op het Twitter-profiel.

We gaan dan verder en bespotten de API-aanroep naar Twitter, zodat de API niet elke keer naar Twitter wordt gepost als deze wordt gebeld. Ga je gang en open de mock_test.py bestand en voeg de volgende code toe.

# mock_test.py #! / usr / bin / env python import niet mogelijk van mock-import Mock import tweet-class TweetTest (unittest.TestCase): def test_example (self): mock_twitter = Mock () tweet.post_tweet (mock_twitter, "Een taak creëren Manager-app met Ionic: Deel 1 ") mock_twitter.PostUpdate.assert_called_with (" Een Taakbeheer-app maken met Ionic: Deel 1 ") als __name__ == '__main__': unittest.main ()

Het uitvoeren van de bovenstaande test zou een uitvoer moeten geven zoals:

---------------------------------------------------------------------- Ran 1-test in 0.001s OK 

Conclusie

Deze tutorial heeft de meeste basisbeginselen van mocking behandeld en hoe je spot moet gebruiken om externe API-aanroepen uit te voeren. Ga voor meer informatie naar de officiële Python-spotdocumentatie. U kunt ook extra bronnen voor verificatie vinden met de Twitter API in deze zelfstudie.

Aarzel ook niet om te zien wat we beschikbaar hebben voor de verkoop en om te studeren in de Envato-markt, en ga alsjeblieft verder en stel alle vragen en geef waardevolle feedback via de onderstaande feed.