Schrift
[thread]6809[/thread]

use Test::Simple;: wie teste ich richtig?!

Leser: 2


<< >> 6 Einträge, 1 Seite
Ronnie
 2005-03-22 14:18
#52859 #52859
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ich arbeite gerade an einer Datenbank basierten Webapplikation. Um überhaupt vorwärts zu kommen habe ich alles in sehr kleine Schritte zerlegt. Zuerst sind Zugriffsklassen für die Tabellen dran, dann soll die Validierung folgen, das Templating und zuletzt die eigentliche Applikation. Ich verwende POD um die einzelnen Module/Klassen zu dokumentieren und Test::Simple zum prüfen ob alles so läuft wie ich es mir vorstelle. Die Frage ist: Was sollte man alles prüfen, was kann man alles prüfen?! Wie geht ihr bei sowas vor?
Als Beispiel meine countries.t, die zum Modul DB::Countires gehört:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/bin/perl

use strict;
use warnings;

#use Data::Dumper;
use Test::Simple tests => 12;
use DB::Countries;

my $country = new DB::Countries;
my $to_insert = { country => 'Testunien',
country_code => 'TST' };

my $inserted = $country->insert($to_insert);

my $to_update = { country => 'Lummerland',
country_code => 'LUM',
ID_country => $inserted };

ok (defined $inserted,
'$inserted is defined');

ok ($inserted =~ m/^\d+$/,
'$inserted is a numerical id');

my $response = $country->get($inserted);

ok (defined $response,
'$response is defined');

ok (ref $response eq 'ARRAY',
'$response is a reference to an array');

ok ($response->[0]->{country} eq 'Testunien',
'$response->[0]->{country} has expected value: "Testunien"');

ok ($response->[0]->{country_code} eq 'TST',
'$response->[0]->{country_code} has expected value: "TST"');

ok ($country->update($to_update),
'$country->update($to_update) called and succeeded');

$response = $country->get($inserted);

ok (defined $response,
'$response is defined');

ok (ref $response eq 'ARRAY',
'$response is a reference to an array');

ok ($response->[0]->{country} eq 'Lummerland',
'$response->[0]->{country} has expected value: "Lummerland"');

ok ($response->[0]->{country_code} eq 'LUM',
'$response->[0]->{country_code} has expected value: "LUM"');

ok ($country->remove($inserted),
'$country->remove($inserted) called and succeeded');

exit;
sri
 2005-03-23 05:50
#52860 #52860
User since
2004-01-29
828 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hmm...sieht so aus als koenntest du Catalyst ganz gut gebrauchen. ;)
Sauberes und elegantes MVC mit integriertem test framework...

Bei interesse empfehle ich da Intro.
Strat
 2005-03-23 09:53
#52861 #52861
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
hilft dir vielleicht auch eins der folgenden module weiter:

Locale::Country
Geography::Countries
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
ptk
 2005-03-23 11:53
#52862 #52862
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=Ronnie,22.03.2005, 13:18]Die Frage ist: Was sollte man alles prüfen, was kann man alles prüfen?![/quote]
Wenn man es richtig machen will, dann sollte man durch Test-Skripte 100% Abdeckung (Coverage) erreichen. Um die Coverage seiner Test-Skripte zu errechnen, kann man Devel::Cover verwenden.
Quote
Wie geht ihr bei sowas vor?

Unterschiedlich. Wenn ich Zeit habe (was nie der Fall ist), dann versuche ich 100% abzudecken. Wenn ich keine Zeit habe, schreibe ich mindestens einen Basis-Test, der zusichert, dass alle Module und Skripte kompilieren, und Tests fuer Sachen, wo ich Bugs gefunden habe oder wo ich eine Aenderung mache und zusichern will, dass keine Regression entsteht.
kabel
 2005-03-23 12:02
#52863 #52863
User since
2003-08-04
704 Artikel
BenutzerIn
[default_avatar]
die codefragmente sind in der reihenfolge, ich hab nur einzelne statements rausgezogen um sie farbig markieren zu können.

Code: (dl )
1
2
3
4
5
6
7
#!/usr/bin/perl

use strict;
use warnings;

#use Data::Dumper;
use Test::Simple tests => 12;

use DB::Countries;

hierfür gibts require_ok/use_ok, dafür brauchts du allerdings Test::More. Test::More hat Test::Simple als API untermenge, du kannst also einfach Test::More anstelle Test::Simple importieren.
Code: (dl )
1
2
3
my $country = new DB::Countries;
my $to_insert = { country => 'Testunien',
country_code => 'TST' };

my $inserted = $country->insert($to_insert);
entweder du testest $inserted direkt hier oder der nachfolgende hash hat mind. 2 möglichkeiten für den wert hinter dem schlüssel ID_country. ist das wirklich was du willst?
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
my $to_update = { country       => 'Lummerland',
country_code => 'LUM',
ID_country => $inserted };

ok (defined $inserted,
'$inserted is defined');

ok ($inserted =~ m/^\d+$/,
'$inserted is a numerical id');

my $response = $country->get($inserted);

ok (defined $response,
'$response is defined');

ok (ref $response eq 'ARRAY',
'$response is a reference to an array');

dafür gibts isa_ok, oder du benutzt die kurzschlussemantik von &&. aber dafür ganze zwei zeilen?! ;)
ok ($response->[0]->{country} eq 'Testunien',
'$response->[0]->{country} has expected value: "Testunien"');
der code funktioniert nur unter der annahme, dass $response mind. 1 element enthält.
Code: (dl )
1
2
ok ($response->[0]->{country_code} eq 'TST',
'$response->[0]->{country_code} has expected value: "TST"');

ok ($country->update($to_update),
'$country->update($to_update) called and succeeded');

heisst das dass update eine exception schmeisst oder das update eine wert > 0 zurückliefert wenn die operation erfolgreich war?
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$response = $country->get($inserted);

ok (defined $response,
'$response is defined');

ok (ref $response eq 'ARRAY',
'$response is a reference to an array');

ok ($response->[0]->{country} eq 'Lummerland',
'$response->[0]->{country} has expected value: "Lummerland"');

ok ($response->[0]->{country_code} eq 'LUM',
'$response->[0]->{country_code} has expected value: "LUM"');

ok ($country->remove($inserted),
'$country->remove($inserted) called and succeeded');

exit;


schau dir den code mal genau an. du willst, dass $response eine bestimmte struktur hat, die du vorher angeben kannst.
dafür gibts is_deeply().

schau dir auch mal can_ok() an.

btw einer der fünf smileys ist echt. rate mal welcher.

hth
-- stefan
Dubu
 2005-03-23 12:36
#52864 #52864
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Ich habe ja nicht (mehr) viel mit Unittests etc. zu tun, aber was mich an den Testcases hier stoert, ist dass sie nur die "guten" Faelle abdecken. Bei den Tests, die ich kenne, war es immer wichtig, die pathologischen Faelle und die Grenzwerte zu testen. Was macht eine Routine, wenn man ihr falshce Daten uebergibt? Dort soll z.B. nur eine positive Zahl uebergeben werden - was passiert bei einer negativen, oder Null? Was passiert, wenn Pflichtfelder leer gelassen werden oder einer Routine zu wenig Felder uebergeben? Was ist mit sehr kurzen / sehr langen Eingaben? (Gut, letzteres ist unter Perl selten ein Problem, das ist eher fuer die C/C++ Tests ;)) Eine Applikation (oder auch eine Unit) sollte gerade bei flashcen Eingaben immer in einen definierten Zustand uebergehen.
<< >> 6 Einträge, 1 Seite



View all threads created 2005-03-22 14:18.