Tkinter und unittests?!?

Fragen zu Tkinter.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Gibt es eigentlich eine Möglichkeit Tkinter GUI Programm per unittests zu testen?

Klar, man sollte GUI und Programm trennen, dann kann man die von der GUI aufgerufenen Routinen Testen. Aber die GUI selber bleibt dann außen vor...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

jens hat geschrieben:Gibt es eigentlich eine Möglichkeit Tkinter GUI Programm per unittests zu testen?
An solchen Stellen wird es immer "schwierig". Streng genommen sind Oberflächentests keine Unittests mehr, da sie nicht isoliert ablaufen können, d.h. man hat halt immer eine Event-Loop des GUI-Frameworks laufen, die man schlecht mocken kann, oder einen Browser oder sonst etwas als Abhängigkeit zur Laufzeit. Zudem dauern sie (deswegen) auch relativ lange. Es mag aber weniger puristische Menschen geben, die das dennoch als Unittest ansehen würden, ich persönlich halte es da mit Roy Osheroves Definition, die eben mindestens durch die beiden genannten Punkte verletzt wird.

Ob es da für Tkinter etwas gibt, weiß ich nicht. Für andere Frameworks (Qt z.B.) gibt es Libs, die das ermöglichen, teilweise sogar vom Framework-Entwickler selber.

Alternativ gibt es ja auch universelle Tools, die eher für Integrationstests gedacht sind (was eben das Durchklicken durch eine GUI beinhaltet). Ranorex ist z.B. ein solches (wirklich tolles) Tool - allerdings kommerziell. Selenium wäre eine freie, wenn iirc auch auf Web-GUIs beschränkte, Alternative.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ja, ich schreibe immer pauschal unittests, obwohl ich oft Integrationstests meine ;)

Wie dem auch sei: Wie kann man eine GUI testen, ohne das halt manuell zu machen... Wäre die bessere Frage gewesen.

Also gibt es für Tkinter nix dazu?

EDIT: Viel zu dem Thema findet man nicht, aber das: http://stackoverflow.com/questions/4083 ... kinter-app

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Vielleicht sollte man in Richtung Fernsteuerung Lösungen suche?
Also wo es allgemein um das automatische steuern andere Programme über die GUI geht.

Gibt es da was in Python?

Edit: so was wie: http://www.getautoma.com/

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Man kann die GUI natürlich testen. Ich empfehle, die GUI so zu implementieren, dass sie keine Routinen der Geschäftslogik aufruft. Die GUI soll nur Messages mit und ohne Daten senden und empfangen. Wenn sich die Geschäftslogik als Empfänger registriert, dann empfängt die Geschäftslogik die Messages und die GUI ist mit der Geschäftslogik verbunden. Wenn man aber einen unittest mit dem Empfang der Messages verknüpft, kann man ohne weiteres die GUI testen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Egal wie man es nennt: Es gibt eine API zwischen GUI und eigentlichem Programm.

Diese API kann an natürlich in tests direkt ansprechen. Damit kann man aber nicht das richtige Zusammenspiel zwischen beidem Testen.


Es müßte für GUIs sowas wie Selenium geben, welches für Webseiten ist: http://www.seleniumhq.org/

EDIT: hab noch was gefunden:
https://pypi.python.org/pypi/autopy allerdings von 2011 und https://github.com/msanders/autopy/ letzter commit 2014.
Anscheinen kann man anscheinen die Maus nur nach Pixel-Koordinaten bewegen, siehe: http://www.autopy.org/documentation/api ... mouse.html
Wie soll man seine GUI Elemente genau treffen?!?

EDIT2: Ah, noch ein paar Links gibt es hier:
https://wiki.python.org/moin/PythonTest ... ting_Tools

Kann jemand was zu den Tools sagen?!?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

jens hat geschrieben:Egal wie man es nennt: Es gibt eine API zwischen GUI und eigentlichem Programm.

Diese API kann an natürlich in tests direkt ansprechen. Damit kann man aber nicht das richtige Zusammenspiel zwischen beidem Testen.


Es müßte für GUIs sowas wie Selenium geben, welches für Webseiten ist: http://www.seleniumhq.org/
Du hattest doch geschrieben: Klar, man sollte GUI und Programm trennen, dann kann man die von der GUI aufgerufenen Routinen Testen. Aber die GUI selber bleibt dann außen vor...
Da hatte ich angenommen, Du wolltest nur die GUI testen. Wenn Du das Zusammenspiel testen willst, dann mußt Du eben den unittest erweitern zum Anwendungssimulator. So testet man auch bei großen Automobilfirmen etwa die HMI. Und der Anwendungssimulator hat dann auch eine GUI, bei der man Verschiedenes eingeben und auswählen kann.

Allerdings das echte Zusamenspiel kann man dann nur unter Realbedingungen testen, etwa beim Automobil durch Testfahrten. Protokolliert wird dann alles mittels Tracefiles. Darin kann man da nachsehen, wann und wo etwas nicht geklappt hatte und dann den Fehler suchen - war es die GUI (oder HMI) oder liegt ein Fehler der Anwendung (beim Auto eines Steuergerätes) vor.

Wenn die Geschäftslogik Traces in ein Logfile schreibt und die GUI ebenfalls, kann man darin deren Zusammenspiel sehen.
Zuletzt geändert von Alfons Mittelmeyer am Donnerstag 27. August 2015, 08:10, insgesamt 1-mal geändert.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Ich habe das vor ganz, ganz langer Zeit mal für ein Projekt gemacht, bei dem ich mitgearbeitet habe. Das war Java, und wir haben irgend etwas benutzt um die GUI ferngesteuert zu bedienen.

Wir sind damals zu dem Ergebnis gekommen, dass eine GUI nur so wirklich zu testen ist, nicht durch Tests am Code.

Ich kriege aber gerade nicht mehr zusammen, wie das Programm hieß, um das wir ein kleines Test-Framework gebastelt hatten.

Ich weiß noch, dass es am Anfang recht "simpel" war. So etwas wie "Programm öffnen, 4x Tab, Tippe "arfs", drücke Enter, erwarte Dialog mit dem Dialog mit "Falsche Eingabe" ".
Dann stießen wir auf das Problem, dass wir nur schwer auf eine geänderte GUI reagieren konnten und machten die Elemente über Tastenkombinationen zugänglich (also statt 4xTab so etwas wie "Alt+S").

Teilweise mussten wir auch Dinge manuell beim Tester erfragen. Zum Beispiel wenn sich ein Teil der GUI deaktivierte, konnten wir das damals nur über eine Rückfrage beim Menschen vor der Tastatur heraus finden.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Also nicht Tests am Code machen und ob die GUI geändert wurde, ist egal, wenn mit Messages kommuniziert wird. Die GUI selber allerdings, nämlich ob da Einträge richtig dargestellt werden, muss man manuell, also durch den Augenschein testen. Es gibt auch Bildschirmgrabber, die das Erscheinungsbid vergleichen, aber wenn sich da die GUI ändert, muß man solche automatisierten Tests immer wieder nachziehen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich hatte Ranorex ja schon genannt - eben kommerziell und afaik nur für Windows und einige Mobile Plattformen (iOS / Android?). Selbst wenn man es nicht nutzen kann - ansehen sollte man sich die Demos / Videos mal. Damit bekommt man einen guten Eindruck, was das Tool so kann.

Letztlich könnte man sich auch selber so etwas basteln... je nach Grad der Flexibilität bezüglich GUI-Frameworks, muss man sich direkt in den Kommunikationsprozess von Windowmanager und Programm einklinken oder in die Event-Loop des GUI-Frameworks. Für Qt gibt es für letzteres iirc Ansätze! Ersteres ist letztlich der Ranorex-Ansatz.

Trivial erscheint mir keins von beiden ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten