Autor Thema: Automatisches Testen  (Gelesen 801 mal)

Offline Sidey

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2093
Automatisches Testen
« am: 19 September 2018, 19:36:51 »
Hallo,

Ich überlege schon seit längerem, ob man seine Module automatisiert testen könnte.

Damit habe ich auch schon mal ein wenig getestet.

Zwei Versuche hatte ich bislang unternommen
- FHEM mit einer Config starten, welche einen Testfall abdeckt und dann wird es tricky: Befehle an das eigene Modul kann man mittels Telnet einfach auslosen. Danach müsste man das Logfile Parsen. Z.B. auf Fehler, einen Stacktrace . Ob der FHEM Prozess abgeschmiert ist, bekommt man auch recht einfach mit.
Hat man ein Modul, welches Daten von einem Physischen Geräte verarbeitet, muss man dieses simulieren, was möglich aber auch aufwändig ist.

- Das Modul selbst könnte man aber auch starten und die FHEM Umgebung simulieren.
Diese Variante würde mir viel besser gefallen, da einzelne Funktionen des Moduls getestet werden könnten.
Bislang habe ich es aber nicht geschafft so ein FHEM Modul ohne FHEM zum Laufen zu bekommen :(

Vielleicht hat ja schon einmal jemand selbiges versucht oder Interesse an so einem Projekt.

Grüße Sidey

Gesendet von meinem XT1650 mit Tapatalk

Signalduino, HMLan, Raspberry Pi, Mysensors, ArduinoSensor

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 19351
Antw:Automatisches Testen
« Antwort #1 am: 20 September 2018, 07:49:59 »
Ich wuerde FHEM mit einer test-fhem.cfg starten, was nach der Definition der benoetigten Instanzen die Test-Befehle direkt enthaelt. Ich wuerde da neben trigger/set/get auch die Modulfunktionen mit {} direkt aufrufen.

Das Ergebnis zu analysieren duerfte komplizierter sein, und je nach Aufgabe unterschiedlich:
- notify/watchdog
- perl-Code, was Rueckgabewert oder gesetzte Attribute/Readings prueft
- Log3 umdefinieren, und nach dem Befehl pruefen, ob bestimmte Log-Ausgaben erfolgt sind.

Das alles ist nur eine Ideensammlung, ohne konkrete Erfahrung damit gemacht zu haben.

Offline Sidey

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2093
Antw:Automatisches Testen
« Antwort #2 am: 20 September 2018, 09:08:17 »
Hallo Rudi,

Danke für deine Antwort.

Vermutlich ist es das beste, den Test aus einer laufenden FHEM Instanz zu entwickeln.

Nach meinem Post habe ich auch tatsächlich was von markusfeist gefunden.
Vom Prinzip hat er auf einem Travis-CI Server FHEM installiert und es mit einer minimal Konfiguration gestartet.
Weniger ist hier besser denke ich :)

Da sein Modul einen TCP Server bereitstellt hat er dann Daten an den Socket geschickt.
Hier muss halt jeder selbst schauen, wie er Daten am besten in das System bringt :)

Bis hier eigentlich noch einfach.
Über die Telnet Schnittstelle von FHEM sendet dann Befehle ab und wertet die Rückgabe aus. Solange alles passt, wird der Test als erfolgreich gesehen.

Das Vorgehen trifft nicht gänzlich den Begriff unittest, da FHEM durchaus mit getestet wird, allerdings könnte man ja wie Du auch schreibst, die Perl Funktionen einzeln aufrufen und den Rückgabewert verifizieren.

Spannend wird es dann an den Stellen, an denen z.B. Dispatch oder ReadingUpdate aus dem eigenen Modul aufgerufen werden.
Möchte man hier nur wissen, ob der richtige Parameter übergeben wurde, so müsste man diese Funktionen mocken.

Mit dem Überschreiben von Funktionen habe ich mich aber noch nicht beschäftigt.
Wäre eine Idee.



Hier der Link zum Ansatz von Markus:

https://github.com/markusfeist/FhemMobileAlerts/tree/master/test

Grüße Sidey

Gesendet von meinem XT1650 mit Tapatalk

Signalduino, HMLan, Raspberry Pi, Mysensors, ArduinoSensor

Offline Sidey

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2093
Antw:Automatisches Testen
« Antwort #3 am: 20 September 2018, 14:10:37 »
Hallöchen,

Ich hab mir Mock::SUB angesehen.
Damit ist es möglich Funktionen in einem Perl Modul zu überschreiben.

Also habe ich mir eine fbem.pm (symlink) erstellt und das Modul via use in ein kleines Hilfsprogramme gepackt.

Soweit so gut dachte ich, aber FHEM ist ein Script und kein Modul.
Durch den use Befehl wird FHEM dann ausgeführt ohne, dass man nun die Funktionen noch mocken könnte.

Da gäbe es nun zwei Optionen:

1) in FHEM.pm erkennen ob es als Script oder mit use aufgerufen wurde und anschließend zurück an das Hauptprogramm übergeben.
Wenn ich das grob überblicke, muss nur das eigentlich Hauptprogramm in eine SUB z.b. run gepackt werden.
Wird FHEM direkt aufgerufen dann wird die Funktionen run aufgerufen.
Läuft FHEM als Modul, muss die run sub durch das hilfsscript immer wieder  aufgerufen werden.
Dazwischen kann man FHEM Funktionen überschreiben (mocken) usw.

2) Ein eigenes Modul schreiben, welches dazu dient FHEM Funktionen zu überschreiben. Eventuell können da auch die Testfälle mit eingebaut werden.
Das Modul könnte man über eine geeignete Definition die FHEM.cfg ja einfach laden und über Telnet Befehle steuern, sofern nötig.
Vermutlich kann man es auch in die 99_myutils schreiben.

Beides hat vor und Nachteile, Meinungen erwünscht. :)


Grüße Sidey


Gesendet von meinem XT1650 mit Tapatalk

Signalduino, HMLan, Raspberry Pi, Mysensors, ArduinoSensor

Offline betateilchen

  • Developer
  • Hero Member
  • ****
  • Beiträge: 15207
  • s/fhem\.cfg/configDB/g
Antw:Automatisches Testen
« Antwort #4 am: 20 September 2018, 15:54:16 »
Ich überlege schon seit längerem, ob man seine Module automatisiert testen könnte.

Was sind denn das für neue Sitten? Module vor der Veröffentlichung testen???
Ist es nicht ein eisernes Grundprinzip von FHEM, die QS für neue Module durch die Anwender im Einsatz machen zu lassen?

So war es zumindest bisher üblich, vor allem bei vielen Modulen, die in den letzten 2-3 Jahren veröffentlich wurden. Ob ich das gut finde oder nicht, steht auf einem anderen Blatt.

Im Ernst:

Deinen Ansatz finde ich grundsätzlich gut. Aber um eine sinnvolle Test-Infrastruktur für FHEM aufbauen zu können, müsste man große Teile von FHEM komplett umstricken und weiter kapseln. Verwendung von Namespaces wäre da schon ein erster Schritt.

Für die Umsetzung Deiner Idee wünsche ich Dir viel Erfolg - aber verrenne Dich nicht allzu sehr in die Thematik :)
-----------------------
Unaufgeforderte Anfragen per email werden von mir nicht beantwortet. Dafür ist das Forum da.
-----------------------
Nächster Hamburg-Stammtisch: 14.12.2018 - 18:30 Uhr

Online CoolTux

  • Developer
  • Hero Member
  • ****
  • Beiträge: 16746
Antw:Automatisches Testen
« Antwort #5 am: 20 September 2018, 16:26:32 »
Deinen Ansatz finde ich grundsätzlich gut. Aber um eine sinnvolle Test-Infrastruktur für FHEM aufbauen zu können, müsste man große Teile von FHEM komplett umstricken und weiter kapseln. Verwendung von Namespaces wäre da schon ein erster Schritt.

Wie gut das ich aktuell anfange mit Namespaces zu arbeiten. Und auch einige meiner älteren Module werde ich entsprechend umbauen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.me/MOldenburg
Mein GitHub: https://github.com/LeonGaultier
kein Support für cfg Editierer

Offline Sidey

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2093
Antw:Automatisches Testen
« Antwort #6 am: 20 September 2018, 16:53:12 »

Danke für die Anmerkungen.


FHEM komplett durchtesten war und ist nicht mein Anspruch :)

Und das Testen bei den Anwendern hat meistens doch auch ganz gut funktioniert. 

Es ist halt so, dass die Module, an denen ich entwickele auch andere Personen mit entwickeln.
Die Komplexität der Abläufe trägt auch noch das ein oder andere dazu bei.
Ich würde mich halt wohler fühlen, wenn ich einfach, z.B. mit unit Tests, verifizieren könnte, ob sich ein Verhalten ändert.

Was letztendlich der richtige Code ist, muss man ja eh selbst herausfinden.

Ich denke ich schau mir die Variante mit dem eigenen Modul an. Das scheint mir zunächst wenig invasiv zu sein. Baut halt aber darauf auf, dass FHEM nicht durch fehlerhaften code Abschmiert.
Wenn dass passiert, hilft aber meistens ohnehin nur der Blick in das Logfile.


In so ein Thema kann man sich schnell verrennen. Ich glaube ich denke schon mindestens 1 Jahr darüber nach, was ich hier machen könnte.


Grüße Sidey

Gesendet von meinem XT1650 mit Tapatalk

Signalduino, HMLan, Raspberry Pi, Mysensors, ArduinoSensor

Offline Sidey

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2093
Antw:Automatisches Testen
« Antwort #7 am: 21 September 2018, 00:00:15 »
Wenn es jemanden Interessiert...

Ich habe die Variante mit dem Modul (ich habe es 98_unittest) genannt ausprobiert:

https://github.com/RFD-FHEM/RFFHEM/blob/dev-r33-travis-update/test/98_unittest.pm

Das sind bislang wirklich nur Basis tests, aber das sieht bis hier ganz gut aus.

Ich lasse den Test einfach nach dem Event INITIALIZED loslaufen und prüfe den Inhalt vom Hash eines anderes Gerätes. (Ich habe mich auf den Type und den Inhalt des readings state beschränkt.)

Das mocken der Funktion Log3 habe ich auch probierte auch. Ob es eine gute Idee ist, die Log Funktion zu kapern weiss ich noch nicht.
Ich muss jetzt erst mal eine Strategie überlegen, wie ich mal einen kleinen sinnvollen Test erstelle :)

Grüße Sidey
Signalduino, HMLan, Raspberry Pi, Mysensors, ArduinoSensor
Zustimmung Zustimmung x 1 Liste anzeigen

Offline Sidey

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2093
Antw:Automatisches Testen
« Antwort #8 am: 24 September 2018, 16:45:45 »
Ich fasse mal zusammen was ich in den letzten Tagen so geschafft habe.

Vielleicht ist es ja auch für den ein oder anderen Entwickler interessant. :)

1. Ich habe ein Repository auf github, welches ich mit Travis CI und Coveralls verknüpft habe.

2. Bei jedem Push oder Pull-Request wird ein Build Job auf Travis CI gestartet.

3. Travis CI clont das git, installiert FHEM via deb Paket und pimpt das installiere FHEM dann via Kopieren von Dateien mit den Modulen aus dem git Repo.

4. Für das Testen habe ich ein kleines Hilfs Modul geschrieben:
https://github.com/RFD-FHEM/RFFHEM/blob/dev-r33-travis-update/test/98_unittest.pm
Das Modul hat im wesentlichen nur die Aufgabe eine Umgebung für den Test zur Verfügung zu stellen.
SUB UnitTest_Test_generic
Das Hilfsmodul führt Perlcode mittels Eval aus der im DEF Teil angegeben wurde.

Die Defininition übergebe ich mittels eines Shell Scriptes in eine laufende FHEM Instanz via Telnet, da es damit einfacher ist, das Ergebnis auszuwerten.
https://github.com/RFD-FHEM/RFFHEM/blob/dev-r33-travis-update/test/test-runner.sh

Das Shellscript wertet auch das Ergebnis vom Test aus und schreibt ihn nach STDOUT von der Shell. Dadurch kann ich die Ausgabe im Travis Build Log sehen.

So sieht eine Test Definition z.B. aus:
https://github.com/RFD-FHEM/RFFHEM/blob/dev-r33-travis-update/test/test1-definition.txt

Alternativ kann man es auch in die FHEM.cfg schreiben.

Damit FHEM auf dem Travis Server mit den richtigen Perl Einstellungen läuft muss es unter dem User Travis und nicht FHEM laufen.
Ich starte FHEM daher ohne init scripte, da ich auch noch einen Report möchte, welche Teile von meinem Code mit dem Test abgedeckt werden.
Ich lasse den Test übrigens aktuell mit drei verschiedenen Perl Versionen laufen. Und bekomme für jede Version ein eigenes Ergebnis.

perl -MDevel::Cover fhem.pl fhem.cfg
Der Report wird geschrieben, nachdem der Perl Prozess ein SIGTERM erhält. Ich habe mich für folgende Variante zum Beenden von Perl entschieden, da ich mit dem Upload des Reports warten muss, bis dieser fertig erstellt wurde:
sudo timeout 30 killall -vw perl || sudo killall -vws9 perl
Damit der Report auf Coveralls geladen werden kann kopiere ich ihn wieder ins GIT und lasse ihn auf coveralls bereitstellen:
 - cp -R /opt/fhem/cover_db ./

 - cover -select FHEM/00_SIGNALduino.pm -report coveralls

Ich weiss nicht ob der Report öffentlichen zugänglich ist, aber es sieht dann so aus:

https://coveralls.io/builds/19147953/source?filename=FHEM/00_SIGNALduino.pm#L1538

Code Zeilen die durch einen Test abgedeckt werden, sind grün hinterlegt.
Rot hinterlegte Zeilen sind nicht abgedeckt. Das funktioniert auch schon ganz gut und so sehe ich gleich, dass ich ein paar Bedingungen nicht verifiziere.



Wenn ich nun einen weiteren Test erzeugen möchte, erstelle ich eine neue TestDefiniton uns lasse diese laufen.

In folgendem Test habe noch die FHEM Funktion Diapatch überschrieben, da ich nur wissen möchte, ob die erwarteten Daten an diese Funktion übergeben wurden:
https://github.com/RFD-FHEM/RFFHEM/blob/dev-r33-travis-update/test/test3-definition.txt

Ganz ideal ist es nicht, dass ich FHEM komplett laufen lassen muss, da Devel:: Cover komplett FHEM analysiert.

Das war es erstmal mit meinem Bericht.

Gesendet von meinem XT1650 mit Tapatalk

Signalduino, HMLan, Raspberry Pi, Mysensors, ArduinoSensor

Offline Loredo

  • Developer
  • Hero Member
  • ****
  • Beiträge: 2915
  • ~ Challenging Innovation ~
Antw:Automatisches Testen
« Antwort #9 am: 28 September 2018, 21:07:13 »
Vielleicht hilft es auch, wenn du als Basis das FHEM Docker Image verwendest.
Das FHEM Image dafür gibt es schon und es wird ebenfalls auf Travis gebaut:
https://github.com/docker-home-automation-stack/fhem-docker


Es wäre wohl ein leichtes dieses als Basis zu nehmen und quasi nur das test-integration.sh Script so zu erweitern, dass neben dem generellen hochfahren des Containers und eines erfolgreichen Health Check zusätzlich noch Module geladen und auf Funktion geprüft werden.
FHEM-Module: ENIGMA2, GEOFANCY, ONKYO_AVR, PHTV, RESIDENTS, ROOMMATE, GUEST, HP1000, Pushover, THINKINGCLEANER, Wunderground | FHEM-Befehl: msg

Docker-FHEM 5.10dev auf Intel NUC mit Proxmox VE
Homematic via HMCCU, Hue Color Bulbs, LG OLED 65C8, Sonos Playbar+2xOne+Sub, 2x Sonos One, 1x Sonos Play:1

 

decade-submarginal