2010-10-28 19 views
15

Estoy escribiendo un cliente + servidor de Python que usa gevent.socket para la comunicación. ¿Hay alguna forma de probar el funcionamiento del código a nivel de socket (por ejemplo, verificar que las conexiones SSL con un certificado inválido serán rechazadas)? ¿O es más simple simplemente spawn un servidor real?Python: unidad de prueba basada en el código del socket?

Editar: No creo que la burla "ingenua" sea suficiente para probar los componentes SSL debido a las complejas interacciones involucradas. ¿Estoy equivocado en eso? ¿O hay una forma mejor de probar cosas con SSL?

Respuesta

15

Puede iniciar fácilmente un servidor y luego acceder a él en un caso de prueba. El gevent own test suite hace exactamente eso para probar gevent built-in servers.

Por ejemplo:

class SimpleServer(gevent.server.StreamServer): 

    def handle(self, socket, address): 
     socket.sendall('hello and goodbye!') 

class Test(unittest.TestCase):  

    def test(self): 
     server = SimpleServer(('127.0.0.1', 0)) 
     server.start() 
     client = gevent.socket.create_connection(('127.0.0.1', server.server_port)) 
     response = client.makefile().read() 
     assert response == 'hello and goodbye!' 
     server.stop() 

Usando 0 para el valor del puerto significa que el servidor utilizará cualquier puerto disponible. Después de iniciar el servidor, el valor real elegido por bind está disponible como atributo .

StreamServer soporta SSL también, pasar keyfile y certfile argumentos al constructor y se envuelva cada toma de corriente con SSLObject antes de pasarlo a su controlador.

Si no utiliza StreamServer y su servidor se basa en Greenlet entonces de hecho spawning es lo que debe hacer. No se olvide de kill al final del caso de prueba.

Iniciar un servidor y generar un greenlet son operaciones rápidas en gevent, mucho más rápido que crear un nuevo hilo o proceso y puede crear fácilmente un nuevo servidor para cada caso de prueba. Solo no olvide limpiar tan pronto como ya no necesite el servidor.

Creo que no hay necesidad de burlarse de ninguna de las API de gevent, es mucho más fácil simplemente usarlo ya que los servidores y clientes pueden vivir felizmente dentro del mismo proceso.

+0

Si tiene varias pruebas que crean un SimpleServer (tenga en cuenta que el número de puerto es el mismo) y ejecuta estas pruebas en paralelo, obtendrá bloqueos o fallas de prueba. – Sardathrion

+1

El número de puerto en mi ejemplo es cero, lo que significa que bind() encontrará un puerto libre y lo usará. –

+0

¿Cómo reacciona esto si no se genera en un punto verde separado? ¿Están 'connect' y' read' el bloqueo implícito? Sin embargo, gran ejemplo sobre la simplicidad y el poder de coroutines verdes :) – schlamar

7

Hay otra forma (IMO mejor): debe burlarse de la biblioteca que está utilizando. Un ejemplo de asistente de burla para python es mox.

No necesita un conjunto de servidores con un certificado válido, otro con un certificado no válido, sin soporte de SSL, ninguno que responda a ningún paquete, etc. Puede simular su comportamiento con un " dummy "socket del cliente. La forma en que funciona con Mox es que primero "enseñas" lo que debería esperar y cómo debería reaccionar, y luego ejecutas tu código real mientras cambias el gevent.socket real por el que se burló. Requiere algo de práctica dominarlo, pero vale la pena.

+0

No creo que sea tan simple ... Por diseño, SSL no se puede reproducir ... Así que no estoy seguro de cómo iba a burlarme de un apretón de manos SSL. –

+0

No he dicho que puedas burlarte de tu biblioteca con mox, solo dije que deberías burlarte de alguna manera. En casos como ese, a veces escribo a mano una clase ficticia que es difícil o imposible de simular con mox. ¿Quizás deberías simplemente burlarte de gevent.ssl ​​con mox? ¿Qué estás haciendo exactamente? ¿Estás implementando el protocolo de enlace SSL? Si no, deberías poder burlarte fácilmente. –

+0

Necesito dejar que 'gevent.ssl' ejecute un apretón de manos en las pruebas para poder verificar que plantea los errores que espero (y acepta las conexiones que creo que debería aceptar). Tienes razón en que, una vez que se establece la conexión, puedo burlarme de las interacciones ... Pero eso no cubre lo que quiero. –

6

El burlarse y el troceo son geniales, pero a veces es necesario llevarlo al siguiente nivel de integración. Dado que generar un servidor, incluso uno falso, puede llevar algo de tiempo, considere un conjunto de pruebas separado (llámelos pruebas de integración) que podrían estar en orden.

"Pruébelo como si fuera a usarlo" es mi guía, y si se burla y resiste tanto que su prueba se vuelve trivial no es tan útil (aunque casi cualquier prueba es mejor que ninguna). Si le preocupa manejar certificados SSL incorrectos, tome todos los medios malos y escriba un accesorio de prueba al que pueda alimentarlos. Si eso significa generar un servidor, que así sea. Tal vez si eso te molesta lo suficiente, te llevará a una refactorización que lo hará comprobable de otra manera.

Cuestiones relacionadas