Python Unittest Howto

Me gustaría saber cómo puedo probar el siguiente módulo.

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 

Los proponentes de pruebas unitarias le dirán que las pruebas unitarias deben ser autocontenidas, es decir, no deben acceder a la red o al sistema de archivos (especialmente no en modo de escritura). Las pruebas de redes y sistemas de archivos están más allá del scope de las pruebas unitarias (aunque podría someterlas a pruebas de integración).

Hablando generalmente, para tal caso, extraería los códigos urllib y de escritura de archivos para funciones separadas (que no serían probadas por una unidad), e inyectaría funciones simuladas durante las pruebas unitarias.

Es decir (ligeramente abreviado para una mejor lectura):

 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 

Y, en el archivo de prueba:

 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... 

Y luego apoyo la sugerencia de Daniel, deberías leer más material en profundidad sobre las pruebas de unidad.

Pregunta vaga. Si solo está buscando una cartilla para la prueba de unidad en general con una inclinación de Python, le recomiendo “Dive Into Python” de Mark Pilgrim, que tiene un capítulo sobre la prueba de unidad con Python . De lo contrario, necesita aclarar qué problemas específicos está teniendo para probar ese código.

Para burlarse de urllopen puede obtener algunos ejemplos que luego puede usar en sus pruebas de unidad. Aquí hay un ejemplo para comenzar:

 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