2010-04-16 7 views
3

Je voudrais savoir comment je pourrais tester le module suivant.python unittest howto

def download_distribution(url, tempdir): 
    """ Method which downloads the distribution from PyPI """ 
    print "Attempting to download from %s" % (url,) 

    try: 
     url_handler = urllib2.urlopen(url) 
     distribution_contents = url_handler.read() 
     url_handler.close() 

     filename = get_file_name(url) 

     file_handler = open(os.path.join(tempdir, filename), "w") 
     file_handler.write(distribution_contents) 
     file_handler.close() 
     return True 

    except ValueError, IOError: 
     return False 

Répondre

5

Les initiateurs de tests unitaires vous diront que les tests unitaires doivent être autonomes, c'est-à-dire qu'ils ne doivent pas accéder au réseau ou au système de fichiers (en particulier en mode écriture). Les tests de réseau et de système de fichiers dépassent la portée des tests unitaires (bien que vous puissiez les soumettre à des tests d'intégration). En règle générale, dans un tel cas, j'extrais les codes urllib et d'écriture de fichiers pour séparer les fonctions (qui ne seraient pas testées unitairement), et j'injecte les fonctions fictives lors des tests unitaires.

I.e. (Légèrement abrégée pour une meilleure lecture):

def get_web_content(url): 
    # Extracted code 
    url_handler = urllib2.urlopen(url) 
    content = url_handler.read() 
    url_handler.close() 
    return content 

def write_to_file(content, filename, tmpdir): 
    # Extracted code 
    file_handler = open(os.path.join(tempdir, filename), "w") 
    file_handler.write(content) 
    file_handler.close() 

def download_distribution(url, tempdir): 
    # Original code, after extractions 
    distribution_contents = get_web_content(url) 
    filename = get_file_name(url) 
    write_to_file(distribution_contents, filename, tmpdir) 
    return True 

Et, sur le fichier de test:

import module_I_want_to_test 

def mock_web_content(url): 
    return """Some fake content, useful for testing""" 
def mock_write_to_file(content, filename, tmpdir): 
    # In this case, do nothing, as we don't do filesystem meddling while unit testing 
    pass 

module_I_want_to_test.get_web_content = mock_web_content 
module_I_want_to_test.write_to_file = mock_write_to_file 

class SomeTests(unittest.Testcase): 
    # And so on... 

Et puis je deuxième suggestion de Daniel, vous devriez lire une matière plus approfondie sur les tests unitaires.

5

Question vague. Si vous recherchez simplement un primer pour les tests unitaires en général avec une inclinaison Python, je recommande le "Dive Into Python" de Mark Pilgrim qui a a chapter on unit testing with Python. Sinon, vous devez clarifier les problèmes spécifiques que vous rencontrez en testant ce code.

0

Pour simuler urllopen vous pouvez pré-extraire quelques exemples que vous pouvez ensuite utiliser dans vos tests unitaires. Voici un exemple pour commencer:

def urlopen(url): 
    urlclean = url[:url.find('?')] # ignore GET parameters 
    files = { 
     'http://example.com/foo.xml': 'foo.xml', 
     'http://example.com/bar.xml': 'bar.xml', 
    } 
    return file(files[urlclean]) 
yourmodule.urllib.urlopen = urlopen