• Publicidad

Pruebas o Validaciones para un script en Perl

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Pruebas o Validaciones para un script en Perl

Notapor luicabcru » 2012-08-27 13:59 @624

Hola a todos.

Primero, me gustaría presentarme, ya que es mi primer mensaje en este foro, aunque no sea mi primera visita, ya que he leído en muchas ocasiones diferentes secciones y me han ayudado a resolver diversos problemas. Ahora escribo este mensaje por una duda, en principio teórica, pero que recibirá con mucho gusto ejemplos prácticos.

Mi duda es que no sé cómo plantear unas pruebas o validar un script escrito en Perl, ya sea mediante alguna plantilla o herramienta como Junit en Java. En programación, se habla de "Pruebas Unitarias", "Pruebas funcionales", "Testing automático" o "Validación de Regresiones" para llegar a un estado de fiabilidad en lugar de un estado de incertidumbre sobre lo programado.

¿Podrían ayudarme con este tema o aconsejarme algún método especialmente utilizado en Perl?

Toda información será bienvenida o cualquier tipo de respuesta que intente ayudarme.

Gracias de antemano, y saludos.
luicabcru
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-08-27 12:57 @581

Publicidad

Re: Pruebas o Validaciones para un script en Perl

Notapor explorer » 2012-08-27 14:43 @655

Bienvenido a los foros de Perl en Español, luicabcru.

Desde hace unos años, se demostró la indecibilidad de Perl, indicando que «Perl solo puede ser interpretado por perl».

Actualmente, la mejor forma de saber si un código contiene una sintaxis correcta de Perl, es ejecutar la fase de compilación del propio código:

perl -c código.pl

perl responderá con el mensaje de "syntax OK" en caso de la fase de compilación no haya fallado.

También está demostrado que, aun pasando esta prueba, se pueden crear programas Perl sintácticamente correctos y aun así, que falle su ejecución. O, naturalmente, que no se ejecute correctamente o que no se ejecute de acuerdo a lo que esperamos que haga.

En el mundo de Perl está muy arraigado todo lo que tiene que ver con el tema de las pruebas (test). Es algo casi de obligado cumplimiento.

Prácticamente, todas las distribuciones que hay en CPAN contiene un subdirectorio llamado t/ donde hay una serie de scripts que probarán si esa distribución funcionará o no en el sistema en que se está instalando. Casi todas ellas siguen el protocolo TAP (Test Anything Protocol) (ejemplo, planeta).

En la página de Wikipedia de TAP enlazada antes, tienes enlaces a los módulos Perl más famosos, como Test::More.

En CPAN hay ahora mismo 768 distribuciones que contienen la palabra "Test" en su nombre.

Con esto ya tienes algo por lo que empezar... :)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Pruebas o Validaciones para un script en Perl

Notapor luicabcru » 2012-08-28 04:33 @231

Gracias, explorer, por tu rápida respuesta y por ser tan claro y concreto en tu ayuda.

Voy a echar un vistazo a todo lo que me comentas y a ver si encuentro una buena solución que no se demore demasiado.

Concretando, se trata de un script en Perl que se conecta a un servidor de SGBD PostgreSQL, y en la web de CPAN he encontrado algunos módulos que parecen ser adecuados (Test-PostgreSQL, por ejemplo).

Gracias de nuevo y volveré con más noticias.

Saludos.
luicabcru
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-08-27 12:57 @581

Re: Pruebas o Validaciones para un script en Perl

Notapor luicabcru » 2012-08-29 06:39 @319

Buenas de nuevo,

quería comentar que he estado mirando la documentación de los módulos de Perl en CPAN:

Test::Simple http://search.cpan.org/~mschwern/Test-S ... /Simple.pm
Test::More http://search.cpan.org/~mschwern/Test-S ... st/More.pm

Y creo, si no he entendido mal, que ambos tienen mecanismos para probar el funcionamiento de cualquier función creada dentro del paquete que queremos comprobar.

Sin embargo, mi script es sencillo y contiene una función que quiero comprobar que no recibe ningún parámetro, sino que su función es recoger la entrada al script pasadas como argumento en su ejecución, con la función "getopts" (del paquete Getopt::Std). A partir de las entradas recibidas debe configurar las variables globales para conectarse a una base de datos.

Con lo cual mi pregunta es: ¿es posible realizar con este par de módulos de Test pruebas pasándole diferentes entradas de forma que pueda ver cómo se comporta? Lo ideal sería poder consultar cómo quedan las variables globales tras la ejecución de la función, dependiendo de las entradas que recibe.

También he leído acerca del módulo:

Test::PostgreSQL http://search.cpan.org/~tjc/Test-Postgr ... tgreSQL.pm

Pero no comprendo muy bien su funcionamiento, al parecer simula una conexión a una BD, pero no sé cómo logra realizarla y qué puede probar.


EDIT: Indagando un poco en Google, un ejemplo claro para Java sería la típica clase main utilizada para crear una clase test "public static void main (String [] args)" donde ese array args son los argumentos de entrada al fichero.

Algo parecido es lo que intento conseguir en Perl.

Hasta ahora había utilizado la opción en Eclipse -> Run Configurations -> Arguments, donde se pueden indicar los argumentos de entradas para el script.

Por favor, si puede ayudarme le estará muy agradecido.

Gracias de antemano, saludos.
luicabcru
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-08-27 12:57 @581

Re: Pruebas o Validaciones para un script en Perl

Notapor explorer » 2012-08-29 11:20 @514

La idea de los Test es crear una batería de programas pequeños que validen que nuestra aplicación funciona, y que verifiquen que lo que hace, lo hace bien.

El cómo conseguirlo depende del programador. Los módulos lo único que hacen es hacer una serie de pruebas de las que conocen el resultado. Si el resultado es correcto, sacan un 'Ok' en pantalla. Si no, sacan el informe de errores. Al final, sacan el total de test que han pasado correctamente las pruebas.

Si quieres probar una función que no devuelve nada, deberás hacer una comprobación más tarde de que lo que ha hecho la función es correcto o no, y ese será el valor que entenderá el módulo de Test.

Ejemplo (extracto):

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Test::Simple tests => 23;       # cargamos el módulo e indicamos que vamos a realizar 23 test
  2.  
  3. ok(
  4.     funcion() && comprobacion(),    # llamamos a la función, y luego a la comprobación
  5.     "Prueba de funcion()",          # mensaje que sale en pantalla, al lado del resultado
  6. );
  7.  
  8. sub funcion {
  9.     system("perl programa.pl argumentos...");   # llamamos a nuestro programa
  10. }
  11.  
  12. sub comprobacion {
  13.     my $resultado = qx("perl comprobacion.pl argumentos...");  # ejecutamos la comprobación
  14.     if ($resultado =~ /Ok/) {                                  # si el resultado es correcto,
  15.         return 1;                                              # devolvemos valor verdadero
  16.     }
  17.     else {                                                     # sino,
  18.         return;                                                # falso.
  19.     }
  20. }
  21.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Ahí vemos que llamamos a tu programa y que luego ejecuta otro que debe comprobar si el primero lo ha hecho bien. Según lo que devuelva, ok() sacará en pantalla un mensaje de correcto o no.

Como ves, a cada acción que quieres comprobar, debes crear otro programa que compruebe el resultado.
O, si el programa devuelve una salida según una cierta entrada, puedes probarlo directamente, comprobando que siempre devuelve lo esperado para una entrada conocida.

Esto es lo que nosotros usamos como comprobación de instalación y funcionamiento de POD2::ES.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Test::More tests => 2;
  2.  
  3. BEGIN { use_ok('POD2::ES') };
  4.  
  5. my $pod2 = POD2::ES->new();
  6.  
  7. like($pod2->search_perlfunc_re(), qr/^Lista de funciones de Perl/, 'Texto cabecera de perlfunc');
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Esto se ejecuta en el momento de la instalación de POD2::ES.
Primero indicamos que vamos a realizar dos test.
El primero (use_ok()) está en el BEGIN{}, y comprueba que el módulo POD2::ES ha sido correctamente instalado.
El segundo (like()) comprueba que la llamada al método search_perlfunc_re() devuelve un texto coincidente con el patrón '^Lista de funciones de Perl'.

Si estas dos pruebas devuelven resultados correctos, entonces puedo decir que el módulo está instalado, y que funciona bien, con el Perl y en el sistema informático del usuario.

Este ejemplo se refiere al uso de un módulo externo, pero los módulos de Test se pueden aplicar a cualquier cosa, como por ejemplo, tu caso. Solo tienes que definir qué argumentos le das a tu programa y qué salidas (o cómo han de ser esas salidas) debe devolver. Los módulos de Test lo que hacen es ejecutar esa batería de comprobaciones y dar un resumen de los aciertos y fallos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Pruebas o Validaciones para un script en Perl

Notapor luicabcru » 2012-08-30 11:48 @533

Gracias, explorer, muchas gracias.

Me ha servido para realizar una lista de casos de prueba para evaluar el comportamiento de mi script según diferentes y posibles entradas.

Lo único que me queda una pequeña duda. Cuando la ejecución de mi script resulta exitosa la función ok() responde con un ok seguido de un mensaje de texto introducido como parámetro y en caso contrario con not ok:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
ok - "Prueba 1"
not ok - "Prueba 1"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Cuando mi script ejecuta exit 1; sale del programa de forma correcta y muestra ok, en cambio, si surge algún problema, como una conexión defectuosa a la base de datos con la función connect(), debido a que los parámetros de conexión a ésta introducidos no son correctos, el script sale con exit 0 y muestra not ok.

Mi duda es: si en programación, en general, y en este script de Perl en particular, tengo entendido que no siempre hay que utilizar exit 1, sólo cuando el script se complete totalmente de forma correcta; y que también es necesario programar con exit 0 aquellos casos en los que se produce un error (controlado por el programador mediante estructuras if(), por ejemplo), pero existe algún mensaje de error mostrado por STDERR y el script no se ha ejecutado completamente. ¿Estoy en lo cierto o me equivoco? Para ser rigurosos en esto de las pruebas.

En estos casos la diferencia sería de ok o not ok (1 ó 0) en la comprobación según unos parámetros correctos o incorrectos introducidos al script.

Corrígeme si me equivoco o si no se deben realizar de este modo dichas pruebas, por favor.

Gracias de nuevo, explorer. Un saludo.
luicabcru
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-08-27 12:57 @581

Re: Pruebas o Validaciones para un script en Perl

Notapor explorer » 2012-08-30 12:49 @576

luicabcru escribiste:Mi duda es: si en programación, en general, y en este script de Perl en particular, tengo entendido que no siempre hay que utilizar exit 1, sólo cuando el script se complete totalmente de forma correcta; y que también es necesario programar con exit 0 aquellos casos en los que se produce un error (controlado por el programador mediante estructuras if(), por ejemplo), pero existe algún mensaje de error mostrado por STDERR y el script no se ha ejecutado completamente. ¿Estoy en lo cierto o me equivoco? Para ser rigurosos en esto de las pruebas.
Todo tiene que ver con las convenciones heredadas de hace años, naturalmente, pero eso no impide que tu puedas crear una convención propia, dentro de un sistema informático en concreto. Cosa distinta es si tus programas pueden interaccionar con el resto del sistema (como cuando un administrador o un programador decide que puede usar tu programa dentro de un script. Entonces esperará que los valores de retorno sean conformes a como cualquier otro programa UNIX (0=>éxito, 1=>fallo)).

luicabcru escribiste:En estos casos la diferencia sería de ok o not ok (1 ó 0) en la comprobación según unos parámetros correctos o incorrectos introducidos al script.
La mayor parte de los usos del protocolo TAP es para comunicar el resultado de las baterías de pruebas al gestor de validaciones, para que decida si el número de pruebas pasadas es suficiente para que sea considerada buena la instalación o el funcionamiento de lo que se está probando (en la mayor parte de las ocasiones es necesario que se cumplan todas, pero en muchas instalaciones Perl -por ejemplo-, algunas pruebas pueden obviarse porque dependen de módulos externos opcionales).

Test::Harness, por ejemplo, es un completo entorno de trabajo de gestión de baterías de pruebas.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Pruebas o Validaciones para un script en Perl

Notapor luicabcru » 2012-09-01 13:43 @613

Hola, explorer, gracias de nuevo por tu ayuda.

Según lo que me has explicado, entonces no logro comprender, porque tras la ejecución de esta línea:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Test::Simple tests => 1;
  2. ok(system("perl script.pl argumentos"),"Prueba 1\n");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si estoy programando un script cuya salida es exit; y con lo cual su respuesta es un 0, que en UNIX significa correcto o éxito, en este caso la función ok() devuelve 'not ok' porque espera recibir un 1 o true. Lo cual me resulta contradictorio ¿o no es una buena forma para comprobar este script?

Yo esperaba recibir aquí un 'ok' y para cuando se produjese un error en el script controlado por el programador y saliese del programa con exit 1; entonces recibiera un mensaje de 'not ok' por parte de la función ok().

Si este no es el procedimiento correcto, ¿podrías indicarme qué debo cambiar?

Gracias y un saludo.
luicabcru
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-08-27 12:57 @581

Re: Pruebas o Validaciones para un script en Perl

Notapor explorer » 2012-09-01 14:52 @661

Es fácil de entender: en UNIX los programas devuelven un código numérico para informar del resultado de la ejecución de esos programas. Pero no tienen un significado de verdadero o falso. Son solo códigos numéricos.

Otra cosa es el sentido de verdadero y falso que hay dentro de los programas, escritos con sus propios lenguajes informáticos. Y cada uno tiene un sentido de lo que es falso y de lo que es verdadero. En el caso de Perl, es fácil saberlo (en la página Perl de Wikipedia y en la sección Verdad y Falsedad de perlsyn lo tienes muy bien explicado).

Entonces... cuando un programa devuelve un '0' al sistema operativo, está indicando que no hubo errores (por ser una convención numérica). El programa que lo recibe, debe probar la condición "el programa no devolvió un informe de errores" según sus propios términos de verdad y falsedad.

Si cogemos ese '0' de forma directa, entonces nos lo trata como un valor de falsedad. Estamos cometiendo el error de confundir un código numérico con una condición de verdadero/falso.

Hay que transformar el código que nos devuelve el programa a un valor de verdadero/falso conforme a nuestro lenguaje:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $resultado = system("perl script.pl argumentos");
  2. ok($resultado == 0, 'Prueba 1');
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El operador de comparación numérica está mirando por si el $resultado de la ejecución es un '0'. Si lo es, la condición es verdadera, por lo que entonces podemos decir que el programa ha devuelto un informe de no errores (y ok() recibe un valor verdadero).

Pero... hay otro problema... Tal como está puesto, te funcionará bien en la mayor parte de los casos, pero si el programa script.pl es terminado mediante el envío de una señal, comenzarán los problemas.

system() de Perl no funciona igual que en otros lenguajes (ver perldoc -f system). En resumen: lo que devuelve system() es un valor entero de dos bytes. El byte alto es el resultado del programa que ha devuelto con el exit. Y el byte bajo almacena la señal que provocó el cierre abrupto del programa y si hubo o no volcado del núcleo.

Como seguramente este byte bajo no te interesa para nada, lo que debes hacer es quedarte solo con el byte alto. Eso se hace muy fácil:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $resultado = system("perl script.pl argumentos") >> 8;  # desplazamos 8 pos. hacia la derecha
  2. ok($resultado == 0, 'Prueba 1');
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
o también así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. system("perl script.pl argumentos");
  2. ok($? >> 8  ==  0, 'Prueba 1');
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
(la variable especial $? funciona igual que en Bash. Ver perldoc perlvar).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Intermedio

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados