Hauptmenü

Unit Test?

Begonnen von herrmannj, 10 Mai 2020, 12:54:23

Vorheriges Thema - Nächstes Thema

RichardCZ

Was zum Erfolg führt, aber für meinen Geschmack ein wenig von hinten durch die Brust ins Auge (bzw FHEM Klärgrube-Freistil) ist:

t/FHEM/00_define_smoke.cfg

define AC1 ArduCounter /dev/tty0

dann in t/FHEM/00_define_smoke.t

fhem('define AC1 ArduCounter /dev/tty0');

dann kommt

2020.05.31 12:03:05 0: Server started with 3 defined entities (hobo.pl:99999/2020-04-11 perl:5.030001 os:linux user:root pid:842177)
2020.05.31 12:03:05 3: define AC1 ArduCounter /dev/tty0 : AC1 already defined, delete it first
$VAR1 = [
          '2020.05.31 12:03:05 3 : define AC1 ArduCounter /dev/tty0 : AC1 already defined, delete it first'
        ];


Naja ... das könnte ich testen. Aber kommt euch das nicht vor wie "die Stimme aus dem Grab über Bande gespielt"?


Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

justme1968

nein. das führt nicht zum erfolg. s.u.

wie immer ist etwas hintergrund wissen nötig:
es gibt mindestens drei varianten wie module ihren start organisieren:
- direkt im define wird alles abgearbeitet
  das ist die 'älteste' methode und funktioniert wenn das modul keine weiteren abhängigkeiten
  imhinblick auf andere device (iodev), gesetzte attribute hat

- im define wird ein internal timer gestartet und die initialisierung wird nach ablauf des timers gemacht

- das modul wertet $init_done und das globale INITIALIZED event aus
  - der benutzer legt zur laufzeit ein neues device von hand an -> $init_done ist gesetzt
    -> die initialisierung erfolgt sofort
  - das device wird beim fhem start aus dem gespeicherten zustand (define, attribute) angelegt
     -> $init_done ist noch nicht gesetzt -> es wird auf das INITIALIZED event gewartet
     -> der gespeicherte zustand ist komplett wieder hergestellt -> danach wird alles initialisiert

bei variante 1 kommt würden die log eintrage vor der 'Server started' zeile kommen. diese variante ist aber problematisch sobald es abhänigkeiten gibt.

variante 2 ist eigentlich nicht zu empfehlen weil niemand weiss ob der zeitraum reicht und ausserdem abhängigkeiten selbst dann nicht passen wenn das andere device die gleiche variante verwendet und die zeiten nicht passen

variante 3 ist die zu empfehlende wenn es abhängigkeiten gibt.

ArduCounter scheint variante 1 und 3 zu mischen. und es gibt Meldungen die vor der 'Server started...' zeile kommen und welche die danach kommen würden.


umgekehrt heisst das aber auch das man nicht einfach jedes modul auf die gleiche art testen kann da sich das start verhalten unterscheidet und man ausserdem eigentlich auch noch 'manuelles' define zur laufzeit und das define aus dem start vorgang abdecken muss da sich das verhalten auch hier unterscheiden kann. aber nur entweder oder. nicht in .cfg und in .t gleichzeitig. damit testet du nur ob das define kommando wie vorgesehen einen fehler liefert wenn du den gleichen namen mehrfach verwendest aber nichts auf device ebene.


es bedeutet ausserdem das man zumindest für variante 2 und 3 dafür sorgen muss das die fhem main loop zumindest ein klein wenig gelaufen ist. bevor man ins log schaut und den test beendet.





hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

RichardCZ

Danke für die Hinweise.

Dass man nicht jedes Modul über den gleichen Kamm scheren kann, habe ich vermutet und ist soweit ok - das Ziel ist das Ziel.
Ich habe kein Problem damit mal (mühsam) die (individuellen) Tests für die Module zu schreiben. Denn dann hat man wenigstens
einen Harnisch.

Aber je mehr ich probiere, desto bunter wird der Zoo. Dabei gehe ich stur nach commandref vor:

fhem('define ASC AutoShuttersControl');

Sieht wie Variante 3 aus,

2020.05.31 12:33:14 0: Server started with 2 defined entities (hobo.pl:99999/2020-04-11 perl:5.030001 os:linux user:root pid:843417)
2020.05.31 12:33:14 3: ASC: unknown attribute icon. Type 'attr ASC ?' for a detailed list.
2020.05.31 12:33:14 3: ASC: unknown attribute devStateIcon. Type 'attr ASC ?' for a detailed list.
2020.05.31 12:33:14 3: AutoShuttersControl (ASC) - defined
$VAR1 = [
          '2020.05.31 12:33:14 3 : ASC: unknown attribute icon. Type \'attr ASC ?\' for a detailed list.',
          '2020.05.31 12:33:14 3 : ASC: unknown attribute devStateIcon. Type \'attr ASC ?\' for a detailed list.',
          '2020.05.31 12:33:14 3 : AutoShuttersControl (ASC) - defined'
        ];


Es kommt zum "richtigen" Zeitpunkt, wenngleich ich jetzt nicht erwartet hätte so viele Fehler um die Ohren gewatscht zu bekommen.

Ok, ich stocher' mal rum bei den einzelnen Modulen um einGefühl dafür zu bekommen welches wie startet.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

justme1968

die fehler kommt weil ASC vermutlich nicht vorsieht ohne fhemweb zu laufen. dort kommen die attribute icon und devStateIcon her.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Variante 2 mit InternalTimer(1, sub{}, 0) ist die einfachere Variante der global:INITIALIZED Event-Auswertung, weil die eingetragenen Timer-Routinen erst nach Einlesen aller Config-Files abgearbeitet werden. Ich ziehe diese Methode global:INITIALIZED inzwischen vor. Beides dient dazu, dass die Initialisierung mit Kenntnis aller Attribute und Readings erfolgt.

Zu den Tests:
- define legt ein Geraet an. Wann es vollstaendig initialisiert/"betriebsbereit" ist, kann der Autor mit den genannten Methoden entscheiden.
- autocreate erzeugt bei den voreingestellten verbose 3 eine Ausgabe, und define ArduCounter nicht. Warum wird das als Fehler gewertet?
- wenn ich pruefen will, ob ein Modul keine Syntaxfehler hat, dann wuerde ich nach dem define testen, ob das Geraet angelegt ist.
- icon und devStateIcon sind nur fuer FHEMWEB relevant, deswegen muss vorher eine FHEMWEB Instanz definiert sein, was wiederum per userattr diese Attribute aktiviert.

P.S. Kommentare ala Klaergrube nerven mich, und fuehren mittelfristig dazu, dass ich meine Hilfe nicht anbiete.

RichardCZ

#50
https://gl.petatech.eu/root/HomeBot/-/jobs/168 (s.u. nun 8 Funktionstests)

https://gl.petatech.eu/root/HomeBot/-/commit/1cefbb3a753d56d65ef2801a06918bb7f852774b#43b584c479f6e29dee48f9676c72edae39725b16

a.k.a. "Schwalbe - noch kein Sommer", aber trotzdem nett - finde ich.

übrigens: einer von denen braucht Date::Time - hat der Test ergeben.


PS: Mich nervt auch so manches. z.B wenn  neuer Code 2020 a.D. so aussieht wie
"das war schon 2005 nicht so toll". Da frage ich mich dann auch ob es die vergebliche
Liebesmüh' wert ist.

And that's why we can't have nice things.

Sehr schade eigentlich.




Modifikationen an FhemTestUtils:

sub FhemTestUtils_gotLog {
    my $arg   = shift;
    my $reset = shift // 0;

    my $back = grep m{$arg}, @logs;

    @logs = () if ($reset);

    return $back;
}


2. Parameter macht einen Log Reset. Default: kein Reset.

Da FhemTestUtils_gotLog einen Wahrheitswert zurückliefert, kann man im Testfile auch ok(...) statt is(..., 1) verwenden.


ElsnerWS verhält sich sehr fragil beim Define:

2020.05.31 16:00:16 1: PERL WARNING: Use of uninitialized value $d in hash element at hobo.pl line 3221.
2020.05.31 16:00:16 1: PERL WARNING: Use of uninitialized value $autocreateName in hash element at ./FHEM/00_ElsnerWS.pm line 121.
2020.05.31 16:00:16 2: ElsnerWS define FileLog_EWS FileLog ./log/EWS-%Y-%m.log EWS
2020.05.31 16:00:16 1: PERL WARNING: Use of uninitialized value $autocreateName in hash element at ./FHEM/00_ElsnerWS.pm line 144.
2020.05.31 16:00:16 2: ElsnerWS define SVG_EWS SVG FileLog_EWS:ElsnerWS:CURRENT
2020.05.31 16:00:16 1: PERL WARNING: Use of uninitialized value $FW_gplotdir in concatenation (.) or string at ./FHEM/98_SVG.pm line 141.
2020.05.31 16:00:16 1: PERL WARNING: Use of uninitialized value $FW_gplotdir in concatenation (.) or string at ./FHEM/98_SVG.pm line 144.
2020.05.31 16:00:16 2: ElsnerWS ERROR: set SVG_EWS copyGplotFile: Can't open /ElsnerWS.gplot: No such file or directory
2020.05.31 16:00:16 1: define EWS ElsnerWS comtype=rs485 devicename=/dev/tty0: Can't open /ElsnerWS.gplot: No such file or directory
2020.05.31 16:00:16 3: define EWS ElsnerWS comtype=rs485 devicename=/dev/tty0 : Can't open /ElsnerWS.gplot: No such file or directory


Ich gehe natürlich davon aus, dass das im Lokalkolorit ja überhaupt kein Problem darstellt, aber unter normalen Umständen ("da draussen") stört sowas.




Reiche Ernte:

FBAHAHTTP macht überhaupt keinen Mucks im Log beim define. Nichtmal wenn ich ihm die lokale Fritzbox anbiete und auch nicht nach X Sekunden.

define FHZ FHZ /dev/tty0

kämpft ein wenig

2020.05.31 16:19:32 3: FHZ opening FHZ device /dev/tty0
2020.05.31 16:19:32 3: FHZ opened FHZ device /dev/tty0
2020.05.31 16:19:33 1: Trying again get FHZ init2 (2 out of 3)
2020.05.31 16:19:34 1: Trying again get FHZ init2 (3 out of 3)
2020.05.31 16:19:37 1: Trying again get FHZ serial (2 out of 3)
2020.05.31 16:19:38 1: Trying again get FHZ serial (3 out of 3)


Dann faltet sich alles fatal:

Can't use an undefined value as an ARRAY reference at hobo.pl line 1558.
Compilation failed in require at hobo.pl line 4651.
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 29 just after 5.


Gut, das passiert mir zwar in HoBo, aber ich würde wetten das passiert in FHEM auch. In DoSet:

$arg = join(" ", @args) if (!@{$hash->{CHANGED}});

Ich gehe davon aus $hash->{CHANGED} ist in dem Fall (noch) keine Arrayref.
Ha! Was ein wenig defensives Programmieren doch ausmachen kann:

        $hash->{CHANGED} //= [];
        $arg = join(" ", @args) if (!@{$hash->{CHANGED}});


=> Und der Test läuft durch.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

rudolfkoenig

ZitatModifikationen an FhemTestUtils:
Man verliert dadurch die Moeglichkeit eine Liste (z.Bsp den kompletten Log) zurueckzuliefern.

ZitatFBAHAHTTP macht überhaupt keinen Mucks im Log beim define.
Bei mir steht "MISSING: attr fbaha fritzbox-user" im Log und im STATE.

ZitatDann faltet sich alles fatal:
Bei mir faltet sich nix, muss an hobo.pl liegen.

RichardCZ

Na gut, dann eben List-Kontext.

https://gl.petatech.eu/root/HomeBot/-/commit/47d6819b8451a7fa1e6ceaf1fb8ea73dd054e43f

Du hast Recht, fhem.pl faltet sich nicht, werde ich Ursachenforschung bei HoBo betreiben.
Allerdings macht auch bei mir fhem.pl keinen Mucks bei FBAHAHTTP. Musst ein noch magischeres fhem.pl haben als auf SVN verfügbar.

perl fhem.pl -t t/FHEM/00_smoke_define.t

...
2020.05.31 19:28:35 3: Opening FB1 device 127.0.0.1:2002
2020.05.31 19:28:35 1: FB1: Can't connect to 127.0.0.1:2002: Connection refused
2020.05.31 19:28:35 3: FHZ opening FHZ device /dev/tty0
2020.05.31 19:28:35 3: FHZ opened FHZ device /dev/tty0
2020.05.31 19:28:36 1: Trying again get FHZ init2 (2 out of 3)
2020.05.31 19:28:37 1: Trying again get FHZ init2 (3 out of 3)
2020.05.31 19:28:40 1: Trying again get FHZ serial (2 out of 3)
2020.05.31 19:28:41 1: Trying again get FHZ serial (3 out of 3)
2020.05.31 19:28:43 3: WEB: port 8084 opened
...

Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

RichardCZ

https://gl.petatech.eu/root/HomeBot/-/jobs/173

es geht langsam voran. Den Bug in HoBo mit FHZ define habe ich behoben - da war ich etwas übereifrig beim Optimieren.

Bisheriges Ergebnis der Tests:

ElsnerWS - kotzt viel zu viele Warnings, aber bleibt am Leben
FBAHAHTTP - bleibt still
LIRC - couldn't connect to Lirc::Client=HASH(0x5557efa5f558)->dev: No such file or directory at ./FHEM/00_LIRC.pm line 44

Die anderen - siehe https://gl.petatech.eu/root/HomeBot/-/blob/master/t/FHEM/00_smoke_define.t - sind ok.




@Rudolf

Ich würde vorschlagen/bitten, dass Deine Tests unabhängig voneinander laufen können, sonst kann man sie nicht parallelisieren.

prove --exec 'perl hobo.pl -t' -r t/FHEM/
t/FHEM/00_MQTT2_SERVER/00_parseMsg.t .... ok   
t/FHEM/00_MQTT2_SERVER/01_autocreate.t .. ok   
t/FHEM/00_smoke_define.t ................ ok   
t/FHEM/fhem.pl/00_parseParams.t ......... ok   
All tests successful.
Files=4, Tests=20, 19 wallclock secs ( 0.03 usr  0.00 sys +  0.70 cusr  0.09 csys =  0.82 CPU)
Result: PASS


tut, aber

# prove --exec 'perl hobo.pl -t' -r -j 2 t/FHEM/
t/FHEM/00_MQTT2_SERVER/01_autocreate.t .. Dubious, test returned 1 (wstat 256, 0x100)
No subtests run
t/FHEM/00_MQTT2_SERVER/00_parseMsg.t .... ok                           
t/FHEM/fhem.pl/00_parseParams.t ......... ok                           
t/FHEM/00_smoke_define.t ................ ok   

Test Summary Report
-------------------
t/FHEM/00_MQTT2_SERVER/01_autocreate.t (Wstat: 256 Tests: 0 Failed: 0)
  Non-zero exit status: 1
  Parse errors: No plan found in TAP output
Files=4, Tests=18, 18 wallclock secs ( 0.02 usr  0.01 sys +  0.68 cusr  0.05 csys =  0.76 CPU)
Result: FAIL


tut nicht. Wenn ich wirklich mal 500 Module testen will bei jedem commit, sollten da etliche test-Threads parallel laufen.
Schon jetzt dauern die paar define smoketests 20 Sekunden - die meiste Zeit wartet man auf timeouts.

Falls Du also in einer .t-Datei den mosquitto startest, den laufenden mosquitto aber in der anderen test-Datei brauchst, dann besser diese beiden .t Files zusammenzufassen.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

rudolfkoenig

ZitatFBAHAHTTP - bleibt still
Bitte mein Kommentar von frueher beachten.

ZitatIch würde vorschlagen/bitten, dass Deine Tests unabhängig voneinander laufen können, sonst kann man sie nicht parallelisieren.
Bei z.Zt. genau 1 Beitrag (00_parseParams.t) sehe ich die Notwendigkeit nicht als dringend.
Ich habe trotzdem in FHEM/00_MQTT2_SERVER/fhem.cfg den Port auf 1884 verlegt, damit laeuft der Test bei mir auch mit prove -j 2 durch.

RichardCZ

Zitat von: rudolfkoenig am 02 Juni 2020, 12:04:40
Bitte mein Kommentar von frueher beachten.

Woraufhin ich antwortete

ZitatAllerdings macht auch bei mir fhem.pl keinen Mucks bei FBAHAHTTP. Musst ein noch magischeres fhem.pl haben als auf SVN verfügbar.

Ebenso machen Neuron, MAXLAN und MYSENSORS keinen Mucks

OWX_ASYNC meint unbedingt nochmal den Log3 Prototypen erwähnen zu müssen.

2020.06.02 12:29:28 1: PERL WARNING: Prototype mismatch: sub main::Log3: none vs ($$$) at ./FHEM/00_OWX_ASYNC.pm line 94


Er ist zwar schon in fhem.pl (im gleichen Namespace also) definiert, aber warum nicht...
Hier wirst Du natürlich sagen "Ich habe das Problem in FHEM nicht". Ja klar  :)
Aber ich erinnere an Deine Einlassung hinsichtlich Aversion gegenüber Code-Dupes.

Zitat
Bei z.Zt. genau 1 Beitrag (00_parseParams.t) sehe ich die Notwendigkeit nicht als dringend.
Ich habe trotzdem in FHEM/00_MQTT2_SERVER/fhem.cfg den Port auf 1884 verlegt, damit laeuft der Test bei mir auch mit prove -j 2 durch.

Danke.  Feel free die Smoketests von HoBo zu verwenden. Dann kannst Du schon von 2 Beiträgen sprechen.

Mittlerweile sind die smoketests auch schön data-driven.  8)

Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

rudolfkoenig

ZitatAllerdings macht auch bei mir fhem.pl keinen Mucks bei FBAHAHTTP. Musst ein noch magischeres fhem.pl haben als auf SVN verfügbar.
Bei mir macht "define FBAHAHTTP" auch kein Mucks, und das ist auch ok so.
Wenn ich pruefen will, ob das FBAHAHTTP Modul kein Sytaxfehler hat, dann wuerde ich nach dem define pruefen, ob das Geraet angelegt ist.

00_OWX_ASYNC.pm muss von seinem Maintainer angepasst werden (oder auch nicht).

RichardCZ

Zitat von: rudolfkoenig am 02 Juni 2020, 12:52:11
Bei mir macht "define FBAHAHTTP" auch kein Mucks, und das ist auch ok so.
Wenn ich pruefen will, ob das FBAHAHTTP Modul kein Sytaxfehler hat, dann wuerde ich nach dem define pruefen, ob das Geraet angelegt ist.

Ok, kannst Du ein Beispiel machen? Ich mache dann gerne die 00_smoke_exist.t Fleißarbeit.

Das sich abzeichnende Problem wird wohl sein, dass man einigen Modulen ein Device wird vorgaukeln müssen. Dieses Mocking wird schweißtreibend, deswegen schiebe ich es noch vor mir her.
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.

rudolfkoenig

ZitatOk, kannst Du ein Beispiel machen?
Fuer Folgendes muessen die define Argumente korrekt sein, und je nach Modul auch das Geraet erreichbar, Passwort/etc gesetzt sein:
is(defined($defs{<NAME>}), 1, "instance defined");

Die Instanz kann entweder in fhem.cfg definiert werden oder in der Testdatei mit fhem('define <NAME> ModulName Parameter')


Pruefen ob ein Modul geladen werden konnte (nur Syntax-Check):
is(CommandReload(undef, "98_dummy.pm"), undef, "dummy loaded");

ZitatDas sich abzeichnende Problem wird wohl sein, dass man einigen Modulen ein Device wird vorgaukeln müssen.
Etliche Module unterstuetzten ein test/debug Modus ohne Hardware, z.Bsp. CUL mit "define CUL CUL none 1234".
Aehnlich ist es bei FHZ, ZWDongle, ZWCUL, FBAHA*, KM271, etc.

RichardCZ

Ok, wühle ich mich mal durch. Danke.

Anderweitiges Durchwühlen brachte:

2020.06.02 19:37:13 0: Bareword "NULL" not allowed while "strict subs" in use at ./FHEM/00_SIGNALduino.pm line 4982.


->

            my $osv2byte = "";
            $osv2byte = NULL;
            $osv2byte = substr( $bitData, $idx, 16 );


Zeile 5049 ähnlich

            my $osv3nibble = "";
            $osv3nibble = NULL;
            $osv3nibble = substr( $bitData, $idx, 4 );


Das kann doch noch nie funktioniert haben - oder?
Witty House Infrastructure Processor (WHIP) is a modern and
comprehensive full-stack smart home framework for the 21st century.