2010-05-14 13 views
10

Ich beginne mit Test::More, habe schon ein paar .t Testskripte. Jetzt möchte ich eine Funktion definieren, die nur für die Tests, aber für verschiedene .t-Dateien verwendet wird. Wo ist der beste Platz für eine solche Funktion? Definieren Sie ein weiteres .t ohne irgendwelche Tests und require es wo benötigt? (Als Randbemerkung verwende ich die Modulstruktur, die von Module::Starter erstellt wurde)Wo sollte ich allgemeine Dienstprogrammfunktionen für Perl.t-Tests setzen?

Antwort

9

ein Modul schreiben als RJH unter Beweis gestellt hat.

use lib 't/lib'; 
use Test::YourThing; 

Oder man kann es gerade setzen in t/Test/YourThing.pm, nennen es package t::Test::YourThing und laden Sie es als: Legen Sie es in t/lib/Test/YourThing.pm, dann kann es als geladen werden:

use t::Test::YourThing; 

Der Kopf aufweist, ist nicht die use lib Linie in jeder Testdatei zu schreiben, und sie als lokaler Testmodul eindeutig zu identifizieren. Die untere Seite ist überfüllt t /, es wird nicht funktionieren, wenn "." ist nicht in @INC (zum Beispiel, wenn Sie Ihre Tests im Taint-Modus ausführen, aber es kann mit use lib "." umgehen) und wenn Sie beschließen, die .pm-Datei aus Ihrem Projekt zu verschieben, müssen Sie alle Verwendungen neu schreiben. Deine Entscheidung.

+0

Okay für den Moment werde ich mit diesem sogar gehen Wenn ich mir Test: Builder in einem Moment ansehen werde. – zedoo

11

Der beste Ansatz besteht darin, Ihre Testfunktionen wie alle anderen Funktionen in ein Modul zu integrieren. Sie können dann Test::Builder verwenden, damit sich Ihre Testdiagnose-/Fehlermeldungen so verhalten, als ob der Fehler von der .t-Datei und nicht von Ihrem Modul stammte.

Hier ist ein einfaches Beispiel.

package Test::YourModule; 

use Test::Builder; 
use Sub::Exporter -setup => { exports => ['exitcode_ok'] }; # or 'use Exporter' etc. 

my $Test = Test::Builder->new; 

# Runs the command and makes sure its exit code is $expected_code. Contrived! 
sub exitcode_ok { 
    my ($command, $expected_code, $name) = @_; 

    system($command); 
    my $exit = $? >> 8; 
    my $message = $!; 

    my $ok = $Test->is_num($exit, $expected_code, $name); 
    if (!$ok) { 
     $Test->diag("$command exited incorrectly with the error '$message'"); 
    } 

    return $ok; 
} 

In Ihrem Skript:

use Test::More plan => 1; 
use Test::YourModule qw(exitcode_ok); 
exitcode_ok('date', 0, 'date exits without errors'); 
+1

Ich stimme all dem zu, aber ich würde im Allgemeinen testspezifische Funktionalität in ein Modul im Verzeichnis t/einfügen, so dass es nicht mit der tatsächlichen Anwendung verwechselt werden kann - z. in MyApp/t/Common.pm mit dem Paketnamen MyApp :: t :: Common. – Ether

+4

Ich würde Test :: Builder :: Modul empfehlen, da es sich darum kümmert, einen intelligenten Import() für Sie zu schreiben, einen, der einen Testplan verarbeiten kann. Dadurch kann Ihr Modul von Test :: More alleine bestehen. – Schwern

+1

Dies ist ein wenig schwerwiegend, wenn der gemeinsame Code, den Sie teilen möchten, nichts testet. Dienstprogrammfunktionen und verschiedene andere Dinge, die kein TAP ausgeben, profitieren nicht von einem Test :: Builder-Wrapper. –

Verwandte Themen