next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: El Módulo test_harness y Sup: Pruebas en la Construcción Ant: El fichero META.yml Err: Si hallas una errata ...


Las Pruebas

Ahora estudiemos el programa de prueba. Está en el directorio t.
$ pwd
/home/lhp/Lperl/src/threads/knapsack/Algorithm-Knap01DP/t
$ ls -l
-rw-r--r--  1 lhp lhp 1693 2005-05-17 19:57 01MartelloAndTothBook.t
-rw-r--r--  1 lhp lhp  134 2005-05-16 18:37 knap21.dat
-rw-r--r--  1 lhp lhp  125 2005-05-16 18:37 knap22.dat
-rw-r--r--  1 lhp lhp  123 2005-05-16 18:37 knap23.dat
-rw-r--r--  1 lhp lhp  158 2005-05-16 18:37 knap25.dat
Además del programa 01MartelloAndTothBook.t tenemos cuatro ficheros con cuatro diferentes problemas de la mochila. Los números corresponden a las páginas del clásico libro de Martello y Toth [13] en el que aparece el correspondiente problema.
$ cat -n 01MartelloAndTothBook.t
 1	# Before `make install' is performed this script should be runnable with
 2	# `make test'. After `make install' it should work as `perl Algorithm-Knap01DP.t'
 3	
 4	#########################
 5	use strict;
 6	use Test::More  tests => 11;
 7	
 8	BEGIN { use_ok('Algorithm::Knap01DP', qw/Knap01DP ReadKnap/); }

Realizaremos 11 pruebas de las que la primera es comprobar que el módulo se carga correctamente (línea 8).

 
10  ### main
11  my @inputfiles = qw/knap21.dat  knap22.dat  knap23.dat  knap25.dat/;
12  my @sol = (280, 107, 150, 900);
13  my $knap21 = ['102', [ '2', '20', '20', '30', '40', '30', '60', '10' ],
14                    [ '15', '100', '90', '60', '40', '15', '10', '1' ]];
15  my $knap22 = ['50',  [ '31', '10', '20', '19', '4', '3', '6' ],
16                    [ '70', '20', '39', '37', '7', '5', '10' ]];
17  my $knap23 = ['190', [ '56', '59', '80', '64', '75', '17' ],
18                    [ '50', '50', '64', '46', '50', '5' ]];
19  my $knap25 = ['104', [ '25', '35', '45', '5', '25', '3', '2', '2' ],
20                    [ '350', '400', '450', '20', '70', '8', '5', '5' ]];
21
22  my $knapsackproblem = [$knap21, $knap22, $knap23, $knap25];
La variable @inputfiles contiene los nombres de los ficheros de prueba. La variable @sol las soluciones óptimas a esos problemas. Las variables $knap21 ...$knap25 contienen estructuras de datos que definen los problemas: capacidad de la mochila, vector de pesos y vector de beneficios. Cuando la función ReadKnap lee un fichero de datos devuelve una estructura como esta:
~/Lperl/src/threads/knapsack/Algorithm-Knap01DP/t$ perl \
   -I/home/lhp//Lperl/src/threads/knapsack/Algorithm-Knap01DP/lib \
   -d 01MartelloAndTothBook.t
Loading DB routines from perl5db.pl version 1.25
1..11
ok 1 - use Algorithm::Knap01DP qw/Knap01DP ReadKnap/;;
main::(01MartelloAndTothBook.t:11):
11:     my @inputfiles = qw/knap21.dat  knap22.dat  knap23.dat  knap25.dat/;
  DB<1> b 31 # ponemos un break después de la llamada a ReadKnap
  DB<2> c # y ejecutamos hasta allí
main::(01MartelloAndTothBook.t:31):
31:       is_deeply($knapsackproblem->[$i], [$M, $w, $p], "ReadKnap $file");
  DB<2> x [$M, $w, $p] # Veamos que nos devuelve ReadKnap:
0  ARRAY(0x8555ad0)
   0  102
   1  ARRAY(0x845e034)
      0  2
      1  20
      2  20
      3  30
      4  40
      5  30
      6  60
      7  10
   2  ARRAY(0x845e04c)
      0  15
      1  100
      2  90
      3  60
      4  40
      5  15
      6  10
      7  1
De hecho, es usando el depurador, cortando y pegando que hemos construido las líneas 13-20 definiendo las estructuras de datos $knapXX. A continuación leeemos cada fichero y comprobamos que ambas ReadKnap y Knap01DP dan los resultados esperados. La función is_deeply nos dice si dos estructuras de datos son equivalentes. Véase perldoc Test::More para mas información sobre el módulo Test::More y las funciones is_deeply e is.
24  my $i = 0;
25  my ($M, $w, $p);
26  my @f;
27
28  # Now 2*@inputfiles = 8 tests
29  for my $file (@inputfiles) {
30    ($M, $w, $p) = ReadKnap((-e "t/$file")?"t/$file":$file);
31    is_deeply($knapsackproblem->[$i], [$M, $w, $p], "ReadKnap $file");
32    my $N = @$w;
33    @f = Knap01DP($M, $w, $p);
34    is($sol[$i++], $f[$N-1][$M], "Knap01DP $file");
35  }
A continuación realizamos una prueba para comprobar el funcionamiento cuando se le pasan a Knap01DP vectores de pesos y beneficios de distinto tamaño. Recordemos que en la rutina Knap01DP habíamos escrito el siguiente código:
22    croak "Profits and Weights don't have the same size" 
                                    unless scalar(@w) == scalar(@p)
por tanto, pasarle a la rutina vectores de distinto tamaño hace que el programa muera. Es por esto que protegeremos la ejecución dentro de un eval:
37  # test to check when weights and profits do not have the same size
38  $M = 100; @$w = 1..5; @$p = 1..10;
39  eval { Knap01DP($M, $w, $p) };
40  like $@, qr/Profits and Weights don't have the same size/;
Observe las salidas y los comentarios en inglés. Si tu intención es hacer público el módulo en CPAN es recomendable que las salidas, los nombres de variables y los comentarios estén en ese idioma.

Vamos a hacer una prueba mas. Supongamos que tengo la intención de añadir una función GenKnap que genere aleatoriamente un problema de la mochila. Como no esta hecho, lo declaramos como una prueba a hacer (TODO). Es decir, se trata de un test que fallará, pero que se espera que deje de hacerlo en el futuro.

42  TODO: { # I plan to provide a function to find the vector solution ...
43    local $TODO = "Return vector solution";
44    can_ok('Algorithm::Knap01DP', 'GenKnap');
45  }
Primero una ejecución a mano:
~/Lperl/src/threads/knapsack/Algorithm-Knap01DP/t$ perl \
-I/home/lhp//Lperl/src/threads/knapsack/Algorithm-Knap01DP/lib 01MartelloAndTothBook.t
1..11
ok 1 - use Algorithm::Knap01DP qw/Knap01DP ReadKnap/;;
ok 2 - ReadKnap knap21.dat
ok 3 - Knap01DP knap21.dat
ok 4 - ReadKnap knap22.dat
ok 5 - Knap01DP knap22.dat
ok 6 - ReadKnap knap23.dat
ok 7 - Knap01DP knap23.dat
ok 8 - ReadKnap knap25.dat
ok 9 - Knap01DP knap25.dat
ok 10
not ok 11 - Algorithm::Knap01DP->can('GenKnap') # TODO Randomly generated problem
#     Failed (TODO) test (01MartelloAndTothBook.t at line 45)
#     Algorithm::Knap01DP->can('GenKnap') failed
Obsérvese que: Sigue una ejecución con make test (un directorio por encima):
~/Lperl/src/threads/knapsack/Algorithm-Knap01DP$ make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" \
                                "-e" "test_harness(0, 'blib/lib', 'blib/arch')" \
                                t/*.t
t/01MartelloAndTothBook....ok
All tests successful.
Files=1, Tests=11,  0 wallclock secs ( 0.09 cusr +  0.00 csys =  0.09 CPU)
Observa como ahora se informa que todas las pruebas fueron correctamente. Se ha ocultado que hay una prueba TODO y su fallo no se considera significativo para la posible instalación del módulo. De este modo el directorio de pruebas puede ser utilizado como lista recordatorio de objetivos y requerimientos a realizar.


next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: El Módulo test_harness y Sup: Pruebas en la Construcción Ant: El fichero META.yml Err: Si hallas una errata ...
Casiano Rodríguez León
2006-02-21