2009-12-31 14 views
14

Estoy escribiendo un módulo de Python que finaliza una cierta API de servicio web. Es todo REST, por lo que es relativamente fácil de implementar.Usando SimpleHTTPServer para pruebas de unidades

Sin embargo, encontré un problema cuando se trata de pruebas unitarias: como no ejecuto los servicios para los que hice este módulo, no quiero martillarlos, pero al mismo tiempo, necesito recuperarlos. datos para ejecutar mis pruebas. Miré SimpleHTTPServer, que estaría bien.

Resolví parte del problema que tenía, pero ahora, como parece que no puedo terminar el hilo, tengo problemas con la "dirección que ya está en uso" cuando ejecuto la aplicación de prueba más de una vez.

He aquí algunos ejemplos de código

PORT = 8001 

handler = SimpleHTTPServer.SimpleHTTPRequestHandler 

httpd = SocketServer.TCPServer(("", PORT), handler) 

httpd_thread = threading.Thread(target=httpd.serve_forever) 
httpd_thread.setDaemon(True) 
httpd_thread.start() 

api_data = urllib.urlopen("http://localhost:8001/post/index.json") 
print "Data start:" 
print json.load(api_data) 

Donde "index.json" es un archivo JSON maqueta que hice que sustituye a la cosa real. ¿Cómo puedo limpiar las cosas elegantemente después de que el programa termina?

+0

SimpleHTTPServer debería ser realmente la forma más fácil. ¿Qué tipo de problemas tienes? – balpha

+0

Reescribí las cosas, espero que esté más claro ahora. – Einar

Respuesta

11

Trate de usar un subclass of TCPServer with allow_reuse_address set True:

class TestServer(SocketServer.TCPServer): 
    allow_reuse_address = True 

... 
httpd = TestServer(("", PORT), handler) 
+0

¡genial! Sencillo y simple – Claudiu

+0

Esto no funcionó para mí, pero pude resolverlo configurando el SocketServer en un método setUpClass en lugar del método setUp. El error de dirección en uso parece ocurrir la segunda vez que se llama al método setUp (que ocurre cuando se ejecuta la segunda prueba). – mlissner

4

Usamos un servidor construido en wsgiref. http://docs.python.org/library/wsgiref.html

Es muy fácil agregar funciones a este servidor ya que agregamos pruebas unitarias.

Iniciamos el servidor con subprocess. http://docs.python.org/library/subprocess.html?highlight=subprocess#module-subprocess

No usamos hilos para este tipo de prueba. ¿Por qué? (1) Nuestro servidor de pruebas unitarias es bastante complejo y nos gustaría mantenerlo completamente aislado de las aplicaciones de los clientes. (2) Nuestras aplicaciones de cliente serán procesos separados en hardware separado, necesitamos estar seguros de que tenemos expectativas de rendimiento realistas para esa configuración. (3) Es más simple. (4) Es portátil en todas las plataformas. (5) Es trivial pasar de una prueba de unidad independiente a una prueba de integración con un servidor de producción similar que ya se está ejecutando.

En realidad, tenemos una pequeña aplicación WSGI que hace que el servidor se cierre de forma razonablemente controlada para que los registros se cierren correctamente.

+0

De hecho, parece que un subproceso puede ser una buena alternativa. Investigaremos más. – Einar

4

hilo viejo, pero las respuestas aquí no me ayuda, estoy usando HTTPServer, y el cierre después de cada prueba unitaria (por defecto HTTPServer tiene allow_reuse_address = 1 juego) Sin embargo, aún tengo el problema de la dirección que ya está en uso después de cerrar la llamada. Lo arreglé usando:

from BaseHTTPServer import HTTPServer 

class MyHTTPServer(HTTPServer): 
    def shutdown(self): 
     self.socket.close() 
     HTTPServer.shutdown(self) 

¿No estoy seguro de por qué esto no ocurre de manera predeterminada? ¿Puede ser que esto no sea óptimo?

Cuestiones relacionadas