Código Fácil De Testear

Post on 05-Dec-2014

5.575 views 2 download

description

Charla dada durante la conferencia deSymfony en Castellón, España.http://www.desymfony.com

Transcript of Código Fácil De Testear

Saturday, June 16, 12

Saturday, June 16, 12

Acerca de

• Programador en Liip AG | Zürich

• Blog: http://videlalvaro.github.com/

• Twitter: @old_sound

Saturday, June 16, 12

Hecho en Uruguay

Saturday, June 16, 12

Acerca de

Co Autor de

ConillMQ en acció

http://bit.ly/rabbitmq

Saturday, June 16, 12

Acerca de

Co Autor de

RabbitMQ in Action

http://bit.ly/rabbitmq

Saturday, June 16, 12

No Soy

Saturday, June 16, 12

No Soy

• Gurú del testeo de aplicaciones

Saturday, June 16, 12

No Soy

• Guru del testeo de aplicaciones

• Abogado del TDD

Saturday, June 16, 12

Unit Testing

The goal of unit testing is to isolate each part of the program and show

that the individual parts are correct.

http://en.wikipedia.org/wiki/Unit_testing

Saturday, June 16, 12

Unit Tests

http://es.wikipedia.org/wiki/Prueba_unitaria

Por definición, sólo prueban las unidades por sí solas. Por lo tanto, no descubrirán

errores de integración, problemas de rendimiento y otros problemas que afectan a

todo el sistema en su conjunto.

Saturday, June 16, 12

Dogma vs.

Realidad

Saturday, June 16, 12

Trade Offs

Saturday, June 16, 12

¿Qué testear?

Saturday, June 16, 12

¿Cuánto testear?

Saturday, June 16, 12

http://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565

"I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given

level of confidence" – Kent Beck

Saturday, June 16, 12

El Secreto del TDD

Saturday, June 16, 12

El Secreto del TDD

Saturday, June 16, 12

El Secreto del TDD

Saturday, June 16, 12

Algunos Libros de Kent Beck

Saturday, June 16, 12

Para escribir buenos Tests primero hay que

saber programar

Saturday, June 16, 12

Saturday, June 16, 12

Los Programadores somos como los

usuarios de los que tanto nos quejamos

Saturday, June 16, 12

El diseño se madura y macera con el tiempo

Saturday, June 16, 12

TIPS

Saturday, June 16, 12

Separar el código puro del impuro o stateful

Saturday, June 16, 12

Funciones Puras

Saturday, June 16, 12

Funciones Puras

• Devuelven datos en bases a los parámetros que aceptan

Saturday, June 16, 12

Funciones Puras

• Devuelven datos en bases a los parámetros que aceptan

• No modifican estado externo

Saturday, June 16, 12

Funciones Puras

• Devuelven datos en bases a los parámetros que aceptan

• No modifican estado externo

• No producen efectos secundarios

Saturday, June 16, 12

http://dl.dropbox.com/u/7810909/docs/what-does-fp-mean/what-does-fp-mean/chunk-html/ar01s05.html

if($player->getScore() > 0) { $player->setSwizzle(7);} else { $player->setSwizzle( $player->getSwizzle() + 1 );}

¿Qué tiene de malo este código?

Saturday, June 16, 12

http://dl.dropbox.com/u/7810909/docs/what-does-fp-mean/what-does-fp-mean/chunk-html/ar01s05.html

$newScore = $player->getScore() > 0 ? 7 : $player->getSwizzle() + 1;

$player->setSwizzle($newScore);

Version que no mezcla modificaciones de estado

Saturday, June 16, 12

El cálculo del Score se puede extraer a una

función

Saturday, June 16, 12

El cálculo del Score se puede testear

Saturday, June 16, 12

Primero Escribir Código Puro

Saturday, June 16, 12

Agregar paso a paso el codigo

impuro necesario

Saturday, June 16, 12

Código Fácil de Componer

Saturday, June 16, 12

http://en.wikipedia.org/wiki/Function_(mathematics)

Function Composition

Saturday, June 16, 12

http://en.wikipedia.org/wiki/Function_(mathematics)

Function Composition

Saturday, June 16, 12

Esto suena familiar

Saturday, June 16, 12

“Many UNIX programs do quite trivial tasks in

isolation, but, combined with other programs,

become general and useful tools.”

http://math.albany.edu/math/pers/hammond/unixphil.html

Saturday, June 16, 12

http://www.commandlinefu.com/commands/view/1767/number-of-open-connections-per-ip.

netstat -ntu | awk '{print $5}' | \cut -d: -f1 | sort | uniq -c | sort -n

Number of open connections per IP

Saturday, June 16, 12

¿Por qué no programar código de esa forma?

Saturday, June 16, 12

Esto suena familiar

Saturday, June 16, 12

¡Bienvenido a la Programación

Funcional!

Saturday, June 16, 12

“Writing unit tests is reinventing functional

programming in non-functional

languages”http://noss.github.com/2009/02/25/writing-unit-tests-is-reinventing-functional-programming-in-non-functional-languages.html

Saturday, June 16, 12

¿Qué nos enseña la programación

funcional?

Saturday, June 16, 12

Uso Correcto de Types

Saturday, June 16, 12

¿Qué significa ‘null’?

Saturday, June 16, 12

¿Qué significa ‘false|true’?

Saturday, June 16, 12

Código semánticamente

correcto

Saturday, June 16, 12

Vamos a hacer la comida

Saturday, June 16, 12

Vamos a cocinar la comida

Saturday, June 16, 12

Funciones que cumplen sólo una función

Saturday, June 16, 12

Separación radical de código

puro del impuro

Saturday, June 16, 12

Veamos un Ejemplo

http://pastie.org/4097327

Saturday, June 16, 12

Testeando AMQP

https://github.com/videlalvaro/php-amqplib/

Saturday, June 16, 12

public  function  queue_declare($queue="",  $passive=false,  $durable=false,        $exclusive=false,  $auto_delete=true,  $nowait=false,    $arguments=NULL,  $ticket=NULL)

{    if($arguments  ==  NULL)        $arguments  =  array();

     $args  =  new  AMQPWriter();      if($ticket  !=  NULL)          $args-­‐>write_short($ticket);      else          $args-­‐>write_short($this-­‐>default_ticket);      $args-­‐>write_shortstr($queue);      $args-­‐>write_bit($passive);      $args-­‐>write_bit($durable);      $args-­‐>write_bit($exclusive);      $args-­‐>write_bit($auto_delete);      $args-­‐>write_bit($nowait);      $args-­‐>write_table($arguments);      $this-­‐>send_method_frame(array(50,  10),  $args);

     if(!$nowait)          return  $this-­‐>wait(array("50,11"));        //  Channel.queue_declare_ok}

Testeando queue_declare

Saturday, June 16, 12

Testeando queue_declareclass  AMQPChannel  extends  AbstractChannel{    public  function  __construct($connection,  $channel_id=null,  $auto_decode=true)    {        $this-­‐>frameBuilder  =  new  FrameBuilder();

       if  ($channel_id  ==  null)  {            $channel_id  =  $connection-­‐>get_free_channel_id();        }

       parent::__construct($connection,  $channel_id);

       if  ($this-­‐>debug)  {            MiscHelper::debug_msg("using  channel_id:  "  .  $channel_id);        }

       $this-­‐>default_ticket  =  0;        $this-­‐>is_open  =  false;        $this-­‐>active  =  true;  //  Flow  control        $this-­‐>alerts  =  array();        $this-­‐>callbacks  =  array();        $this-­‐>auto_decode  =  $auto_decode;

       $this-­‐>x_open();    }    /*  ...  más  métodos  y  propiedades  omitidos  */}

Saturday, June 16, 12

Testeando queue_declare

public  function  queueDeclare($queue,  $passive,  $durable,  $exclusive,  $auto_delete,  $nowait,  $arguments,  $ticket)

{    $args  =  new  AMQPWriter();    $args-­‐>write_short($ticket)              -­‐>write_shortstr($queue)              -­‐>write_bit($passive)              -­‐>write_bit($durable)              -­‐>write_bit($exclusive)              -­‐>write_bit($auto_delete)              -­‐>write_bit($nowait)              -­‐>write_table($arguments);    return  $args;}

Saturday, June 16, 12

Testeando queue_declare

public  function  queue_declare($queue="",  $passive=false,  $durable=false,                                                                  $exclusive=false,  $auto_delete=true,  $nowait=false,                                                              $arguments=NULL,  $ticket=NULL){    $arguments  =  $this-­‐>getArguments($arguments);    $ticket  =  $this-­‐>getTicket($ticket);

   $args  =  $this-­‐>frameBuilder-­‐>queueDeclare(                                              $queue,  $passive,  $durable,  $exclusive,

 $auto_delete,  $nowait,  $arguments,  $ticket);        $this-­‐>send_method_frame(array(50,  10),  $args);

   if  (!$nowait)  {        return  $this-­‐>wait(array("50,11"));        //  Channel.queue_declare_ok                                                              }}

Saturday, June 16, 12

Testeando queue_declare

public  function  testQueueDeclare(){    $expected  =  "\x00\x00\x03foo\x00\x00\x00\x00\x00";    $args  =  $this-­‐>frameBuilder                              -­‐>queueDeclare(

     'foo',  false,  false,  false,  false,  false,  array(),  0);

   $this-­‐>assertEquals($expected,  $args-­‐>getvalue());}

Saturday, June 16, 12

¿Cómo aplico esto al mundo real?

Saturday, June 16, 12

¿Cómo aplico esto al mundo real?

• Ver la charla de Ricard “Servicios en Symfony2”

Saturday, June 16, 12

¿Cómo aplico esto al mundo real?

• Ver la charla de Ricard “Servicios en Symfony2”

• Muchos servicios especializados y desacoplados

Saturday, June 16, 12

¿Cómo aplico esto al mundo real?

• Ver la charla de Ricard “Servicios en Symfony2”

• Muchos servicios especializados y desacoplados

• Clases que cumplen sólo una función

Saturday, June 16, 12

http://www.linfo.org/q_programming.html

“Inside every well-written large

program is a well-written small program”

Saturday, June 16, 12

¿Preguntas?

Saturday, June 16, 12

¡Gracias!Álvaro Videla

http://twitter.com/old_sound

http://github.com/videlalvaro

http://www.slideshare.net/old_sound

Saturday, June 16, 12