2011-07-15 13 views
7

Dostaję się do testowania w Pythonie i zadałem sobie pytanie, jak przetestować tę metodę.W jaki sposób testujesz funkcję za pomocą której pobiera dane przez urllib2?

def get_response(self, url, params): 
    encoded_params = urllib.urlencode(params) 
    request = urllib2.Request(BASE_URL, headers=HEADERS) 
    response = urllib2.urlopen(request, encoded_params) 
    return response 

Jak najlepiej można to osiągnąć za pomocą doctest lub unpittest? Pomyślałem o przekazaniu adresu URL testu i niektórych parametrów testowych, które istnieją w świecie rzeczywistym i sprawdzeniu, czy response.read() zwraca oczekiwane dane. Ale jakoś mi się wydaje, że tak nie powinno być. Jakieś sugestie? Byłbym wdzięczny za sugestie dotyczące postępowania z takimi przypadkami w kontekście pisania wiadomości tekstowych.

+0

Najpierw zdefiniuj kontrakt, którego powinna przestrzegać metoda. Kontury postu testujące * zaakceptowaną odpowiedź *, ale teraz, jak należy rozwiązywać awarie. Testowanie rzeczywistych * danych * brzmi jednak bardziej jak test integracyjny. –

+2

Zajrzyj do kodu naukowego scikit (licencjonowanego przez BSD), który dokładnie to robi; [testcases] (https://github.com/scikit-learn/scikit-learn/blob/master/scikits/learn/datasets/tests/test_mldata.py), ['mock_urllib2'] (https://github.com /scikit-learn/scikit-learn/blob/master/scikits/learn/utils/testing.py#L55). –

Odpowiedz

3

Jest to dobra okazja do skorzystania z fałszywej platformy testowej, takiej jak minimock.

BASE_URL='http://google.com' 
HEADERS = {"accept-language":"klingon"} 
import urllib, urllib2 
def get_response(self, url, params): 
    r""" 
    >>> from minimock import Mock 
    >>> urllib2.Request = Mock('urllib2.Request') 
    >>> urllib2.urlopen = Mock('urllib2.urlopen') 
    >>> get_response(None, 'http://google.com', {'foo':'bar'}) 
    Called urllib2.Request(
     'http://google.com', 
     headers={'accept-language': 'klingon'}) 
    Called urllib2.urlopen(None, 'foo=bar') 
    >>> 
    """ 
    encoded_params = urllib.urlencode(params) 
    request = urllib2.Request(BASE_URL, headers=HEADERS) 
    response = urllib2.urlopen(request, encoded_params) 
    return response 

Należy pamiętać, że urządzenie jest wbudowany w docstring dla funkcji badanego w formacie doctest.

5

Jest to dobra sprawa dla używając fałszywych przedmiotów:

# my_module 
get_url = urllib2.urlopen 

def get_response(self, url, params): 
    encoded_params = urllib.urlencode(params) 
    request = urllib2.Request(BASE_URL, headers=HEADERS) 
    response = get_url(request, encoded_params) 
    return response 

# test_my_module  
def fake_get_url(request, params): 
    assert request == "the url I expect" 
    assert params == ['the', 'params', 'i', 'expect'] 
    return SomeFakeResponse("OK") 

my_module.get_url = fake_get_url 
assert my_module.get_response("blah", "blah").content == "OK" 

To dopiero sketchiest szkic jak można zastąpić rzeczywistą funkcję urllib2.urlopen ze swoim fałszywym realizacji testować swój kod bez naprawdę uderzenie sieć.