Python3 unittest: Wie Observer-Pattern Events testen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
buhtz
Beiträge: 1099
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Python3 unittest: Wie Observer-Pattern Events testen

Beitrag von buhtz » 20.05.2020 12:28:02

Ich lerne gerade spielersich den Umgang mit unittest bzw. überhaupt testgetriebener Entwicklung.

Einige meiner Objekte kommunizieren per Observer-Pattern - also über Events. Bisher konnte ich online keinen Betrag dazu finden, wie man Events (nicht GUI!) am pythonischten testen kann. Natürlich hab ich einige Ideen, aber bei Python gibts ja immer gerne eine viel einfachere pythonische Lösung, die mir nie eingefallen wäre.

Um das Subjekt (also z.B. eine datenhalte Objektinstanz) zu testen, also ob es den Event auch auslöst, würde ich mir einen Hilfs-Observer basteln und darin einfach die Änderung einer Variable prüfen.
Pseudocode:

Code: Alles auswählen

class HilfsObserver:
  def __init__(self):
     self.notified = False

  def notify(self):
     self.notified = True
     
  # ...
 
class TestSubjekt(unittest.TestCase):
   def test_notify(self):
     ho = HilfsObserver()
     subj = FooBarSubjekt()

     self.assertFalse(ho.notified)
     subj.do_something()
     self.assertTrue(ho.notified)
     
     # ...
Geht es auch eleganter?
Zuletzt geändert von buhtz am 22.05.2020 21:56:35, insgesamt 1-mal geändert.
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

reox
Beiträge: 2459
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Python3 unittest: Wie Observer-Pattern Events testen

Beitrag von reox » 21.05.2020 12:06:00

Ich versteh nicht ganz wie ho in diesem Fall überhaupt irgendwas von subj empfangen kann - oder hast du da noch irgendwo magische inspection sachen am laufen die automatisch solche objekte bei der erzeugung eintragen?
Ich vermute mal dein code sollte eigentlich eher so aussehen:

Code: Alles auswählen

class HilfsObserver:
  def __init__(self):
     self.notified = False

  def notify(self):
     self.notified = True
 
class TestSubjekt(unittest.TestCase):
   def test_notify(self):
     ho = HilfsObserver()
     subj = FooBarSubjekt()
     subj.register(ho)

     self.assertFalse(ho.notified)
     subj.do_something()
     self.assertTrue(ho.notified)
Jedenfalls hätte ich das jetzt auch so gemacht.
Weiß ja nicht was du sonst noch so testen willst, aber wenn du zB Timings herausfinden willst oder so, also dass ein Objekt innerhalb einer gewissen Zeit informiert wird, könntest du das vllt per decorator einbauen, dass in subj beim aufruf von do_something der aktuelle timestamp gespeichert wird und in notify von HilfsObserver dann ebenfalls. So kannst du nachher die Stempel vergleichen.
Oder um dir noch einen anderen Pythonischen Weg zu zeigen: Gerne "monkey-patched" man ja auch mal methoden um gewisse Dinge zu testen.
Also um zB nur herauszufinden ob FooBarSubjekt jemals seine eigene notify methode aufruft, kann man die ja auch überschreiben.
Evt schau dir auch mal an wie man asyncio sachen testen kann, vielleicht kannst dir da noch Ideen holen.

buhtz
Beiträge: 1099
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: Python3 unittest: Wie Observer-Pattern Events testen

Beitrag von buhtz » 22.05.2020 22:02:37

reox hat geschrieben: ↑ zum Beitrag ↑
21.05.2020 12:06:00
Ich versteh nicht ganz wie ho in diesem Fall überhaupt irgendwas von subj empfangen kann
Nur Pseudocode.
reox hat geschrieben: ↑ zum Beitrag ↑
21.05.2020 12:06:00
Jedenfalls hätte ich das jetzt auch so gemacht.
Na, prima! :THX:
reox hat geschrieben: ↑ zum Beitrag ↑
21.05.2020 12:06:00
Evt schau dir auch mal an wie man asyncio sachen testen kann, vielleicht kannst dir da noch Ideen holen.
Auweia, ich hatte es befürchtet, dass das auch geht. :D
Ich nutze asynico (plus Multi-Threading & -Processing) "ziemlich intensiv" (ok es läuft nur auf einem PC nicht auf einem Cluster :mrgreen: ) und hatte mich schon gefragt, wie man sowas wohl in unittests backen könnte. Wenn es geht, muss ich es machen.

Hast du da nette Ressourcen, wo ich mich einlesen kann?
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

reox
Beiträge: 2459
Registriert: 06.06.2006 22:09:47
Lizenz eigener Beiträge: MIT Lizenz

Re: Python3 unittest: Wie Observer-Pattern Events testen

Beitrag von reox » 23.05.2020 12:36:20

Ich hab asyncio noch nie wirklich gebraucht. Das erste was ich gefunden hätte wäre https://medium.com/ideas-at-igenius/tes ... f3628f82bc
und es gibt wohl auch hilfsmodule: https://pypi.org/project/pytest-asyncio/

Antworten