2009-10-05 12 views
12

Quali strutture e strumenti consiglieresti per il test unitario e gli oggetti mock in Perl?Quali sono i buoni framework per il test unitario e gli oggetti mock in Perl?

Possiedo un'applicazione Perl esistente, che esegue principalmente l'accesso al database, la lettura e la scrittura di file. L'applicazione è fondamentalmente un tipo di applicazione batch, legge molti file da file e database e scrive un sacco di nuovi file e alcune cose nel database.

L'applicazione al momento non ha alcun test unitario, ma mi piacerebbe che l'applicazione refactor avesse un buon test unitario.

Quali strutture e strumenti consiglieresti per il test unitario e gli oggetti di derisione? Ad esempio qualcosa di simile a Hamcrest e JMock di Java?

Inoltre, esistono ottimi framework di test basati su BDD (Behaviour Development) per Perl?

risposta

12

In termini di framework di test, mi piace utilizzare Test::Class, che consente di impostare le gerarchie di test dell'unità in modo simile a JUnit. La documentazione collegata offre una buona panoramica, anche se non si ha familiarità con le convenzioni di test Perl, consultare la documentazione per Test::Simple e TAP, che è il formato di output standard per i test Perl.

Per il mocking, c'è Test::Mock::Class, che è utile per impostare le classi di simulazione per le librerie al di fuori del controllo diretto, come i moduli CPAN su cui si basa l'applicazione.

C'è anche l'eccellente Test::MockDBI che fornisce servizi speciali per il controllo delle informazioni del database.

+0

Test :: Classe è uno strumento fantastico per i test basati oggetto; è leggero e funziona con Test :: Altro e tutti gli strumenti di test delle unità correlate Test :: Builder. –

6

Ultimamente, con MooseX::Declare, ho usato "oggetti reali" come oggetti mock.

Diciamo che avete un driver di database che fa un'interfaccia simile a questo:

role Database { 
    requires 'connect'; 
    requires 'query'; 
}; 

Poi si dispone di codice come questo che utilizza il database:

class FooPage { 
    has 'database' => (
     is  => 'ro', 
     does  => 'Database', 
     required => 1, 
    ); 

    method get_foo() { 
     $self->database->query({ foo => 42 }); 
    } 

    method render_page(Str $user) { 
     "Hello, $user. Here is a foo for you: ". $self->get_foo; 
    } 
}; 

ora si vuole verificare questa:

use Test::More tests => 2; 
use MooseX::Declare; 

my $fake_database = class with Database { 
    has 'data' => (is => 'ro', isa => 'HashRef'); 
    has 'connected' => (is => 'rw', isa => 'Bool'); 

    method connect() { $self->connected(1) } 
    method query(HashRef $query) { $self->data->{$query->{foo}} } 
}; 

my $test_database = $fake_database->name->new(
    data => { 
     42 => 'OH HAI', 
    }, 
}; 

my $foo_page = FooPage->new(database => $test_database); 
is $foo_page->get_foo, 'OH HAI', 'got correct foo'; 
is $foo_page->render_page('jrockway'), 
    'Hello, jrockway. Here is a foo for you: OH HAI', 
'got rendered page'; 

Nota come si ha sintassi concisa, ma tutta la potenza di un "reale" Classe Moose come oggetto fittizio. Conveniente e infinitamente flessibile.

(questi sono solo esempi ... potrebbe anche essere qualcosa di molto meglio.)

+0

Questo sembra dannatamente bello, ma se non stavo già usando Moose, probabilmente lo salterei. –

Problemi correlati