servidor navegador instalar full desde descargar como acceder delphi unit-testing ftp delphi-2010

delphi - navegador - instalar filezilla



¿Cómo probar una clase que se conecta a un servidor FTP? (5)

Estoy desarrollando una actualización en vivo para mi aplicación. Hasta ahora, he creado casi todas las pruebas unitarias, pero no tengo idea de cómo probar una clase específica que se conecta a un servidor FTP y descarga nuevas versiones.

Para probar esta clase, ¿debo crear un servidor de prueba de FTP y usarlo en mis pruebas unitarias? Si es así, ¿cómo puedo asegurarme de que este servidor FTP siempre sea coherente con mis pruebas? ¿Debo crear manualmente todos los archivos que necesitaré antes de que comience la prueba o debería automatizar esto en mi clase de prueba (métodos de desmontaje y configuración)?

Esta pregunta también se aplica a las clases de pruebas unitarias que se conectan a cualquier tipo de servidor.

EDITAR

Ya me estoy burlando de mi clase de ftp, así que no siempre necesito conectarme al servidor ftp en otras pruebas.

Déjame ver si entendí bien lo que dijo Warren en su comentario:

Yo diría que una vez que hable con una aplicación separada sobre TCP / IP deberíamos llamar a eso "pruebas de integración". Uno ya no está probando una unidad o un método, sino un sistema.

Cuando una prueba unitaria necesita comunicarse con otra aplicación (que puede ser un servidor HTTP o un servidor FTP) ¿ya no es una prueba unitaria sino un servidor de integración? Si es así, ¿lo estoy haciendo mal al tratar de usar técnicas de pruebas unitarias para crear esta prueba? ¿Es correcto decir que no debería probar esta clase? Tiene sentido para mí porque parece ser mucho trabajo para una prueba unitaria.


Escriba un par de pruebas de integración enfocadas para el componente que sabe cómo comunicarse con un servidor FTP. Para esas pruebas, deberá iniciar un servidor FTP antes de cada prueba, colocar allí los archivos necesarios para la prueba y, después de la prueba, apagar el servidor.

Una vez hecho esto, en todas las demás pruebas no usará el componente que realmente se conecta a un servidor FTP, pero usará una versión falsa o falsa (que está respaldada por alguna estructura de datos en memoria en lugar de archivos reales y enchufes de red). De esta forma, puede escribir pruebas unitarias, que no necesitan un servidor FTP o una conexión de red, para todo lo demás, excepto el componente cliente FTP.

Además de esas pruebas, podría ser conveniente realizar también algunas pruebas de extremo a extremo que inicien todo el programa (a diferencia de las pruebas de integración centradas en componentes) y que conecten un servidor FTP real. Las pruebas de extremo a extremo no pueden cubrir todos los casos de esquina (a diferencia de las pruebas unitarias), pero pueden ayudar a resolver problemas de integración .


Se supone que las pruebas unitarias son rápidas, se alivian rápidamente. Todo lo que los frena lo desanima de querer ejecutarlos.

También se supone que son consistentes de una carrera a otra. Probar una transferencia de archivo real introduciría la posibilidad de fallas aleatorias en las pruebas de su unidad.

Si la clase que está probando no hace más que ajustar la API de la biblioteca ftp que está utilizando, entonces ha alcanzado uno de los límites de su aplicación, no necesita probarlo en una unidad . (Bueno, a veces lo haces. Se llama prueba exploratoria pero generalmente se descarta una vez que recibes tu respuesta)

Sin embargo, si hay alguna lógica en la clase, debe intentar probarla aisladamente de la API real. Para ello, crea un contenedor para la API ftp. Luego, en las pruebas de su unidad, crea un doble de prueba que puede reemplazar al envoltorio. Hay muchas variaciones que tienen diferentes nombres: stub, fake, mock object. En pocas palabras, quiere asegurarse de que las pruebas de su unidad estén aisladas de cualquier influencia externa. Una prueba unitaria con comportamiento esporádico es menos que inútil.

La prueba del mecanismo de transferencia de archivos real debe hacerse en las pruebas de integración, que generalmente se ejecutan con menos frecuencia porque es más lento. Incluso en las pruebas de integración, querrá intentar controlar el entorno de prueba tanto como sea posible. (es decir, prueba con un servidor ftp en una red local que está configurada para imitar el servidor de producción).

Y recuerda, nunca podrás ver todo por adelantado. Los errores se pasarán sin importar cuán buenas sean las pruebas. Solo asegúrese de que cuando lo haga agregue otra prueba para atraparlos la próxima vez.

Recomendaría comprar o consultar una copia de XUnit Test Patterns por Gerard Meszaros. Es un tesoro de información útil sobre qué / cuándo / cómo probar la unidad.


Solo tome prestada la demostración del servidor FTP o HTTP que viene con el conjunto de componentes de socket que prefiera (Indy, ICS o lo que sea). Servidor de prueba instantánea

Lo pondría en una carpeta de herramientas para ir con mis pruebas unitarias. Podría escribir algún código que compruebe si TestFtpServer.exe ya está activo, y si no lo está, ejecutarlo.

Lo mantendría fuera del espacio de memoria de proceso de mi aplicación de prueba, por lo tanto, el proceso por separado.

Tenga en cuenta que para cuando llegue a las operaciones del servidor FTP, las pruebas unitarias realmente deberían llamarse "pruebas de integración".

No crearía manualmente archivos de mi prueba de unidad. Esperaría que mi código salga del control de versiones y compile, como está, desde un archivo por lotes, que ejecuta mi programa de prueba, que conoce una subcarpeta llamada Herramientas que contiene EXEs y tal vez una carpeta llamada ServerData y LocalData que podría usarse para mantener los datos que se inician en el servidor y que se transfieren a la aplicación de prueba de mi unidad local. Tal vez puedas hackear tu servidor de demostración para que finalice una sesión en parte (cuando quieras probar fallas) pero todavía no creo que vayas a obtener una buena cobertura.

Nota: Si está haciendo actualizaciones automáticas, creo que ninguna cantidad de pruebas unitarias lo reducirá. Debes lidiar con muchos problemas potenciales relacionados con Internet. ¿Qué sucede cuando tu nombre de host no se resuelve? ¿Qué sucede cuando una descarga se interrumpe y falla? La actualización automática no es una gran combinación con las capacidades de las pruebas unitarias.


Si está utilizando el componente TIdFTP Indy 10, puede utilizar la clase TIdIOHandlerStream de Indy para falsificar una conexión FTP sin hacer realmente una conexión física a un servidor FTP real.

Cree un objeto TStream , como TMemoryStream o TStringStream , que contenga las respuestas FTP que espera que TIdFTP reciba para todos los comandos que envía (use un analizador de paquetes para capturarlos de antemano para darle una idea de lo que necesita incluir), y coloque una copia de su archivo de actualización en la carpeta local donde normalmente se descargaría. Cree un objeto TIdIOHandlerStream y asigne TStream como TStream , luego asigne ese IOHandler a la propiedad TIdFTP.IOHandler antes de llamar a Connect() .

Por ejemplo:

ResponseData := TStringStream.Create( ''220 Welcome'' + EOL + ... + // login responses here, etc... ''150 Opening BINARY mode data connection for filename.ext'' + EOL + ''226 Transfer finished'' + EOL + ''221 Goodbye'' + EOL); IO := TIdIOHandlerStream.Create(FTP, ResponseData); // TIdIOHandlerStream takes ownership of ResponseData by default FTP.IOHandler := IO; FTP.Passive := False; // Passive=True does not work under this setup FTP.Connect; try FTP.Get(''filename.ext'', ''c:/path/filename.ext''); // copy your test update file to ''c:/path/filename.ext''... finally FTP.Disconnect; end;


En las pruebas, el objetivo siempre es primero responder a la pregunta: qué se prueba, es decir, el alcance de la prueba.

Entonces, si está probando la implementación de un servidor FTP, deberá crear un cliente FTP.

Si está probando un cliente FTP, tendrá que crear un servidor FTP.

Por lo tanto, tendrá que reducir la extensión de la prueba hasta llegar a un nivel unitario.

Puede ser, por ejemplo, para su propósito:

  • Obtener una lista de los archivos actuales instalados para la aplicación;
  • Obtener una lista de los archivos disponibles de forma remota;
  • Obteniendo una actualización de archivos;
  • Comprobando que un archivo es correcto (¿suma de comprobación?);
  • y así...

Cada artículo probado es para tener algunos simulacros y trozos. Vea este artículo sobre la diferencia entre los dos. En resumen (AFAIK), un stub es solo un objeto de emulación, que siempre funciona. Y un simulacro (que debe ser único en cada prueba) es el elemento que puede cambiar el resultado de la prueba (pase o no).

Para el propósito exacto de una conexión FTP, puede, por ejemplo (al probar el lado del cliente) tener algunos resguardos que devuelven una lista de archivos, y una simulación que probará varios posibles problemas del servidor FTP (tiempo de espera, conexión perdida, error contenido). Entonces su lado del cliente deberá reaccionar como se esperaba. Su simulación puede ser una verdadera instancia de servidor FTP, pero que se comportará como se espera para desencadenar todos los errores potenciales. Por lo general, cada error generará una excepción, que las unidades de prueba deben rastrear, para aprobar / reprobar cada prueba.

Esto es un poco difícil de escribir un buen código de prueba. Un enfoque basado en pruebas consume un poco de tiempo al principio, pero siempre es mejor a largo plazo. Un buen libro es aquí obligatorio, o al menos algunos artículos de referencia (como Martin Fowler''s como se relacionó anteriormente). En Delphi, el uso de interfaces y principios SÓLIDOS puede ayudarlo a escribir dicho código, y crear stubs / mocks para escribir sus pruebas.

Según mi experiencia, cada programador puede perderse algunas veces al escribir pruebas ... la buena escritura de prueba puede consumir más tiempo que la escritura de características, en algunas circunstancias ... ¡está advertido! Cada prueba se verá como una característica, y su costo se evaluará: ¿vale la pena? ¿No hay otra prueba más adecuada aquí? ¿Mi prueba está desacoplada de la función que está probando? ¿No está ya probado? ¿Estoy probando mi código o una función de tercera parte / biblioteca?

Fuera del tema, pero mis dos centavos: HTTP / 1.1 puede ser un mejor candidato hoy en día que FTP, incluso para la actualización de archivos. Puede reanudar una conexión HTTP, cargar contenido HTTP en fragmentos en paralelo, y este protocolo es más amigable para proxy que FTP. Y es mucho más fácil alojar contenido HTTP que FTP (algunos servidores FTP también tienen problemas de seguridad conocidos). La mayoría de las actualizaciones de software se realizan a través de HTTP / 1.1 en estos días, no de FTP (por ejemplo, productos de Microsoft o la mayoría de los repositorios de Linux).

EDITAR:

Puede argumentar que está realizando pruebas de integración cuando usa un protocolo remoto. Podría tener sentido, pero en mi humilde opinión esto no es lo mismo.

A mi entender, las pruebas de integración tienen lugar cuando dejas que todos tus componentes trabajen juntos como con la aplicación real, luego verificas que están funcionando como se esperaba. Mi propuesta sobre las pruebas FTP es que se está burlando de un servidor FTP para probar de forma explícita todos los posibles problemas (tiempo de espera, conexión o error de transmisión ...). Esto es algo más que las pruebas de integración: la cobertura del código es mucho más grande. Y solo está probando una parte del código, no toda la integración del código. Esto no se debe a que esté utilizando alguna conexión remota que esté realizando pruebas de integración: esto todavía es una prueba unitaria.

Y, por supuesto, las pruebas de integración y sistema se realizarán después de las pruebas unitarias. Pero las pruebas unitarias de cliente FTP pueden simular un servidor FTP, ejecutarlo localmente, pero probar todos los problemas potenciales que puedan ocurrir en la gran red mundial real.