Thread Tests schreiben (14 answers)
Opened by pktm at 2009-08-27 20:02

sid burn
 2009-08-28 13:05
#125056 #125056
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
2009-08-27T18:02:49 pktm
Hallo!
Welche Test-Module sind empfehlenswert?

Ich finde Test::Most sehr gut, das ist sozusagen ein ersatz für Test::More und beinhaltet auch gleich weitere Module.

* Test::More
* Test::Exception
* Test::Differences
* Test::Deep
* Test::Warn

Das sind auch so ganz gute Module die man öfters mal benötigt. Ebenfalls interessant ist auch: Test::Class

Habe ich persönlich aber bisher noch nicht genutzt.

Quote
Wie aber schreibt man Tests?

Hast du deine Module als gültiges CPAN Distribution erstellt? Wenn nicht dann schau dir mal Module::Starter an. Hiermit erstellst du eine Distribution. Deine Module kommen dann in das "lib" verzeichnis. Tests legst du unter das "t/" verzeichnis ab.

Ein Beispiel:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sidburn@sid:~/perl$ module-starter --distro=Point --module=Point --mb --author="David Raab" --email="perl@david-raab.de" --license=mit 
Created starter directories and files
sidburn@sid:~/perl$ cd Point/
sidburn@sid:~/perl/Point$ find
.
./Makefile.PL
./Changes
./t
./t/00.load.t
./t/pod.t
./t/pod-coverage.t
./t/perlcritic.t
./lib
./lib/Point.pm
./MANIFEST
./Build.PL
./README
./ignore.txt


"lib/Point.pm" wird abgeändert.
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
package Point;
use MooseX::Declare;
our $VERSION = '0.001000';
    $VERSION = eval $VERSION;

class Point {
    has 'x' => ( is => 'ro', isa => 'Int', required => 1 );
    has 'y' => ( is => 'ro', isa => 'Int', required => 1 );
}

1;


Und nun Tests dazu:
t/01-point.t anlegen mit folgenden inhalt:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Test::Most qw(defer_plan die);
BEGIN { use_ok('Point') }

my $point;
lives_ok {
    $point = Point->new( x => 100, y => 200 );
} 'check Point creation';

cmp_ok( $point->x, '==', 100, 'x is 100' );
cmp_ok( $point->y, '==', 200, 'y is 200' );

dies_ok { Point->new() }      'die because x, y forgotten';
dies_ok { Point->new(x=>10) } 'die because y forgotten';
dies_ok { Point->new(y=>10) } 'die because x forgotten';

all_done();


Um nun eine einzelne Testdatei auszuführen kannst du folgendes machen:
Code: (dl )
prove -l -v t/01.point.t

Wenn du das ausführst solltest du auch soetwas sehen:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sidburn@sid:~/perl/Point$ prove -l -v t/01-point.t 
t/01-point.t ..
ok 1 - use Point;
ok 2 - check Point creation
ok 3 - x is 100
ok 4 - y is 200
ok 5 - die because x, y forgotten
ok 6 - die because y forgotten
ok 7 - die because x forgotten
1..7
ok
All tests successful.
Files=1, Tests=7, 1 wallclock secs ( 0.02 usr 0.00 sys + 0.82 cusr 0.04 csys = 0.88 CPU)
Result: PASS


Wir haben also sieben Tests für unser Modul geschrieben und sie sind erfolgreich durchgelaufen.

Ansonsten wenn du alle Tests ausführen möchtest die unter t/ liegen dann empfiehlt sich du nutzt das Build System (In diesem Fall nutze ich Module::Build).

Daher du musst einmalig "perl Build.PL" aufrufen.

Und danach kannst du mit einem aufruf von "./Build test" alle tests ausführen lassen. Wenn du das Beispiel so verfolgst dann sollte auch der perlcritic test fehlschlagen (der default angelegt wird) der unseren Sourecode auf Best Practices überprüft. Bei "Point" wird es anmeckern das kein "use strict" oder "use warnings" geladen wurde. Das ist bei Moose (hier MooseX::Declare) aber egal, da es sowieso implizit geladen wird. PerlCritic würde ich sowieso so anpassen das es ein Author tests ist, sprich nicht per Default ausgeführt wird.

Ansonsten habe ich nur die Bereiche zum Testen erklärt, für eine komplette Distribution gehört mehr dazu, z.B. solltest du in Build.PL eintragen welche Module du nutzt. Ansonsten gibt dir Module::Build auch mehr funktionalitäten. Auf ein Buildsystem solltest du aber generell schon aufsetzen.
Last edited: 2009-08-28 14:21:03 +0200 (CEST)
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de

View full thread Tests schreiben