Wspomaganie testów za pomocą ludibrio
W testach zakładamy jakieś testowe dane wejściowe dla których określamy oczekiwane poprawne dane wyjściowe. Problem pojawia się gdy nie możemy ustawić wszystkich danych wejściowych - np. gdy kod pobiera dane z zewnętrznego API, albo generuje losowe dane i je dalej przetwarza, formatuje. Pomocna do testowania takich "trudnych" przypadków może być biblioteka ludibrio.
Instalacja jest standardowa - pip install ludibrio. Sama biblioteka pozwala na tworzenie moków, czy "stubowania" różnych klas, funkcji - tworzenie obiektów, które udają oryginały, lecz zachowują się w zaprogramowany przez nas sposób. Np. random.randint zwraca losową liczbę z podanego przedziału. Stub zdefiniowany za pomocą ludibrio może sprawić że random.randint zwracać będzie określoną przez nas wartość umożliwiając przetestowanie kodu.
Oto przykładowa funkcja:import random
def make_magic_number():
number = random.randint(1, 100000)
# some magic we would need to test
return '%010d' % number
from ludibrio import Stub
import random
def make_magic_number():
number = random.randint(1, 100000)
# some magic we would need to test
return '%010d' % number
with Stub() as random.randint:
random.randint(1, 100000) >> 5
print make_magic_number()
Stub spowoduje że wywołanie random.randint(1, 100000) (i tylko takie) zwróci podaną przez nas wartość 5. Dzięki temu możemy w teście przewidzieć poprawną wartość jaką funkcja powinna zwrócić.
Podobnie ma się sprawa z kodem pobierającym jakieś dane poprzez sieć. Pobierając np. listę zdjęć z Flickra, listę klipów wideo z YouTube itp. nie jesteśmy w stanie przewidzieć jakie dane otrzymamy - pojawią się nowe zdjęcia i klipy. Ludibrio może nam pomóc - może spowodować że samo pobieranie zwróci nasze dane. Dzięki temu możemy przetestować kod parsujący i przetwarzający pobrane dane. Oto przykład:
# -*- coding: utf-8 -*-
import json
from ludibrio import Stub
import urllib2
url = 'http://www.flickr.com/services/rest/?method=flickr.photos.search&format=json&text=python&api_key=API_KEY'
def get_python_images(url):
handle = urllib2.urlopen(url)
data = handle.read()
# a bit of black magic that could use some tests
data = data.replace('jsonFlickrApi(', '')[:-1]
parsed_data = json.loads(data)
return parsed_data
fake_response = 'jsonFlickrApi({"photos":{"page":1, "pages":666, "perpage":66, "total":"6666", "photo":[{"id":"123", "owner":"1111111@N06", "secret":"abcabc", "server":"1", "farm":1, "title":"Test Python", "ispublic":1, "isfriend":0, "isfamily":0}]}, "stat":"ok"})'
with Stub() as urllib2.urlopen:
urllib2.urlopen(url).read() >> fake_response
print get_python_images(url)
Comment article