Java GUI Plugins: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
(26 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 5: Zeile 5:
Um das Verständnis zum theoretischen Teil noch zu festigen, wird im Anschluss ein Praxisnahes Beispiel Schritt für Schritt durchgearbeitet und beschrieben, bei dem Sie aktiv mitarbeiten können. Die dazu benötigten Testsuiten und Anwendungen laden Sie sich bitte über die in den Abschnitten zu Verfügung gestellten Links herunter.
Um das Verständnis zum theoretischen Teil noch zu festigen, wird im Anschluss ein Praxisnahes Beispiel Schritt für Schritt durchgearbeitet und beschrieben, bei dem Sie aktiv mitarbeiten können. Die dazu benötigten Testsuiten und Anwendungen laden Sie sich bitte über die in den Abschnitten zu Verfügung gestellten Links herunter.


== Unterstützte Java-Technologien ==
== Java Swing ==
expecco unterstützt die Automatisierung von Java-Anwendungen, die mit Java Swing, Java SWT oder JavaFX implementiert sind. Ebenso weden Anwendungen unterstützt, die mehrere dieser Technologien vereinen, z.B. eine Swing-Anwendung mit eingebettetem JavaFX-Inhalt.

=== Java Swing ===


Diese Erweiterung für expecco ermöglicht die Benutzeroberflächen Testautomatisierung für Java Anwendungen deren Benutzeroberflächen mit Swing erstellt wurden. Die Baustein-Bibliothek beinhaltet Blöcke zur Steuerung und Überprüfung von Swing Benutzeroberflächen. Zudem integriert sich diese Erweiterung in die expecco GUI Test Extension. Diese dient der Unterstützung bei der Entwicklung von Testsequenzen.
Diese Erweiterung für expecco ermöglicht die Benutzeroberflächen Testautomatisierung für Java Anwendungen deren Benutzeroberflächen mit Swing erstellt wurden. Die Baustein-Bibliothek beinhaltet Blöcke zur Steuerung und Überprüfung von Swing Benutzeroberflächen. Zudem integriert sich diese Erweiterung in die expecco GUI Test Extension. Diese dient der Unterstützung bei der Entwicklung von Testsequenzen.


=== Hauptmerkmale ===
==== Hauptmerkmale ====


* Automatisierte Bedienung und Überprüfung von Swing Benutzeroberflächen
* Automatisierte Bedienung und Überprüfung von Swing Benutzeroberflächen
Zeile 20: Zeile 23:
* Block-Bibliothek mit Aktionen und Überprüfungen für Swing Komponenten
* Block-Bibliothek mit Aktionen und Überprüfungen für Swing Komponenten


=== Funktionsweise ===
=== Java SWT ===

=== JavaFX ===
Ab Java 11 ist JavaFX nicht mehr im JDK enthalten. Daher müssen Sie zusätzlich ein JavaFX SDK installieren, z.B. von [https://openjfx.io/ OpenJFX]. Kopieren Sie dann die jar-Dateien aus dem lib-Verzeichnis des JavaFX JDKs nach <code>packages\exept\expecco\plugin\javafx\lib</code> im expecco-Installationsverzeichnis.

== Funktionsweise ==


Das Interface baut eine Verbindung zur Java VM auf, und stellt Funktionen zum Lesen von Widget-Attributen, Aufnehmen von Benutzereingaben sowie zum Fernsteuern der Anwendung zur Verfügung. Außerdem werden in einer Bibliothek zusätzliche Bausteine zur Automatisierung von Tests bereitgestellt.
Das Interface baut eine Verbindung zur Java VM auf, und stellt Funktionen zum Lesen von Widget-Attributen, Aufnehmen von Benutzereingaben sowie zum Fernsteuern der Anwendung zur Verfügung. Außerdem werden in einer Bibliothek zusätzliche Bausteine zur Automatisierung von Tests bereitgestellt.
Zeile 26: Zeile 34:
für expecco und der Applikationssteuerung (Agent). Zur Steuerung der Swing Anwendung wird ein so genannter Agent in die Java Virtual Machine der laufenden Java Anwendung geladen. Um den Agenten zu laden wird ein Java Development Kit 1.8 (JDK) oder höher benötigt. Die zu Testende Anwendung kann jedoch in einer normalen Java Runtime Edition 1.8 (JRE) ausgeführt werden.
für expecco und der Applikationssteuerung (Agent). Zur Steuerung der Swing Anwendung wird ein so genannter Agent in die Java Virtual Machine der laufenden Java Anwendung geladen. Um den Agenten zu laden wird ein Java Development Kit 1.8 (JDK) oder höher benötigt. Die zu Testende Anwendung kann jedoch in einer normalen Java Runtime Edition 1.8 (JRE) ausgeführt werden.


=== Anforderungen ===
== Anforderungen ==


Auf dem Rechner auf dem die zu testende Anwendung laufen soll (lokal oder entfernt):
Auf dem Rechner auf dem die zu testende Anwendung laufen soll (lokal oder entfernt):
Zeile 40: Zeile 48:
<br>
<br>


===Zugriffsberechtigungen===


Um eine Verbindung auf dem Zielsystem garantieren zu können, müssen beim Start der zu testenden Anwendung (sowie des Java Agenten) zusätzliche Parameter mitgegeben werden.<br>
=====Java Optionen=====

Um eine Verbindung auf dem Zielsystem garantieren zu können, müssen beim Start der zu testenden Anwendung sowie des Java Agenten zwei zusätzliche Parameter mitgegeben werden.<br>
Dabei ergeben sich zwei Möglichkeiten dies zu tun
Dabei ergeben sich zwei Möglichkeiten dies zu tun


* Setzen einer Umgebungsvariable die automatisch beim Start jeder Java Anwendung geladen wird<br>
* Setzen einer Umgebungsvariablen die automatisch beim Start jeder Java Anwendung geladen wird<br>
* Manuelle Übergabe der Parameter bei jedem Start einer Java Anwendung
* Manuelle Übergabe der Parameter bei jedem Start einer Java Anwendung
* (Alternativ kann man Zugriffsrechte in den module-info.java Dateien direkt verändern, dies ist jedoch alles andere als praktikabel)


'''Bis Java 11''' sollte es ausreichen, folgende Parameter zu setzen:<br>
Die Parameter lauten wie folgt:<br>
<code>-Djdk.attach.allowAttachSelf=true</code> <br>
<code>-Djdk.attach.allowAttachSelf=true</code> <br>
<code>--illegal-access=permit</code> <br>
<code>--illegal-access=permit</code> <br>


Das Setzen der Umgebungsvariable funktioniert folgendermaßen<br>
Das Setzen einer Umgebungsvariable funktioniert folgendermaßen (''Am Beispiel JDK_JAVA_OPTIONS welche bei jedem JVM Start geladen wird'')<br>
''für Windows Systeme''<br>
'''für Windows Systeme'''<br>
* <code>setx JDK_JAVA_OPTIONS "-Djdk.attach.allowAttachSelf=true; --illegal-access=permit"</code>
* <code>setx JDK_JAVA_OPTIONS "-Djdk.attach.allowAttachSelf=true; --illegal-access=permit"</code>
* oder über das GUI (Windowstaste + Pause).<br>
* oder über das GUI (Windowstaste + Pause).<br>
[[Datei:Windows Setenvironment.png|border|600px|]]
[[Datei:Windows Setenvironment.png|border|600px|]]
<br><br>
<br><br>
'''für Unix Systeme'''<br>


''für Unix Systeme''<br>
* Bash: <code>export _JAVA_OPTIONS='-Djdk.attach.allowAttachSelf=true; --illegal-access=permit'</code>
* Bash: <code>export _JAVA_OPTIONS='-Djdk.attach.allowAttachSelf=true; --illegal-access=permit'</code>
* C Shell: <code>setenv _JAVA_OPTIONS '-Djdk.attach.allowAttachSelf=true; --illegal-access=permit'</code>
* C Shell: <code>setenv _JAVA_OPTIONS '-Djdk.attach.allowAttachSelf=true; --illegal-access=permit'</code>
<br>

'''Ab Java 11''' erfolgt für die Kapselung von Modulen eine striktere Trennung:<br>
<code>--illegal-access=permit</code> wird dabei nicht mehr funktionieren, falls die Zielapplikation eine festgelegte Modulkapselung besitzt ([https://stackoverflow.com/questions/46741907/what-is-an-automatic-module Details]).<br>
In diesem Fall müssen beim Programmstart zusätzliche Parameter angegeben werden, welche Expecco einen Zugriff auf die innewohnenden Ressourcen gewähren.<br>
Je nach verwendeter Technologie können die benötigten Parameter variieren, weshalb Sie diese selbstständig herausfinden müssen.
<br><code>jdeps list-deps JARNAME.jar</code> Jdeps ist dafür ein frei verfügbares (teil der jdk) sehr nützliches Werkzeug.<br>
Eine kurze Übersicht der Kommandos findet man [https://doc.expecco.de/w2.x/images/0/03/Java_module_cheat_sheet.pdf hier] [https://zeroturnaround.com/rebellabs ©]
<hr>
'''Beispiel JavaFX''':<br>
Die Umgebungsvariable <code>PATH_TO_FX</code> die auf das JavaFX Verzeichnis zeigt muss gesetzt sein (Funktionsweise s.o.)<br>
Die folgenden Parameter müssen beim Start der Java Anwendung vorhanden sein

<div class="toccolours mw-collapsible mw-collapsed">
ParameterListe (ausklappbar)
<div class="mw-collapsible-content">
*<code>--module-path "%PATH_TO_FX%" </code>

* <code>--add-modules=javafx.controls </code>
* <code>--add-modules=javafx.swing </code>
* <code>--add-modules=javafx.web </code>

* <code>--add-opens javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.stage=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.scene=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.scene.layout=ALL-UNNAMED </code>

* <code>--add-opens javafx.controls/javafx.scene.control=ALL-UNNAMED </code>
* <code>--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED </code>
* <code>--add-opens javafx.controls/javafx.scene.chart=ALL-UNNAMED </code>
* <code>--add-exports javafx.controls/com.sun.javafx.charts=ALL-UNNAMED </code>
* <code>--add-opens javafx.controls/com.sun.javafx.charts=ALL-UNNAMED </code>
* <code>--add-exports javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED </code>
* <code>--add-opens javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED </code>

* <code>--add-opens javafx.graphics/javafx.scene.image=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.scene.shape=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.application=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.geometry=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.scene.robot=ALL-UNNAMED </code>
* <code>--add-exports javafx.graphics/com.sun.glass.ui=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/com.sun.glass.ui.win=ALL-UNNAMED </code>
* <code>--add-opens javafx.graphics/javafx.scene.input=ALL-UNNAMED </code>

* <code>--add-opens javafx.base/javafx.event=ALL-UNNAMED </code>
* <code>--add-exports javafx.base/com.sun.javafx.runtime=ALL-UNNAMED </code>
* <code>--add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED </code>

* <code>--add-exports javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED </code>
* <code>--add-exports javafx.graphics/com.sun.javafx.util=ALL-UNNAMED </code>
* <code>--add-exports javafx.graphics/com.sun.javafx.scene.input=ALL-UNNAMED </code>

* <code>--add-exports javafx.web/com.sun.webkit.dom=ALL-UNNAMED</code>
</div>
</div>

Sollten Sie dennoch einen <code>java.lang.IllegalAccessError</code> erhalten, müssen Sie diese Parameter in folgender Weise erweitern:
* Fehlertext der Art <code>module <module> does not "opens <package>" to unnamed module</code>
: <code>--add-opens <module>/<package>=ALL-UNNAMED </code>
: ''Beispiel:'' <code>module java.base does not "opens java.lang" to unnamed module</code> ''lösen Sie mit'' <code>--add-opens java.base/java.lang=ALL-UNNAMED</code>
* Fehlertext der Art <code>cannot access class <package>.<class name> (in module <module>) because module <module> does not export <package> to unnamed module</code>
: <code>--add-exports <module>/<package>=ALL-UNNAMED </code>
: ''Beispiel:'' <code>cannot access class com.sun.javafx.scene.input.ExtendedInputMethodRequests (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.input to unnamed module</code> ''lösen Sie mit'' <code>--add-exports javafx.graphics/com.sun.javafx.scene.input=ALL-UNNAMED</code>


=== Konfiguration ===
== Konfiguration ==
==== Installation auf dem expecco Rechner ====
=== Installation auf dem expecco Rechner ===


Die Java Swing Erweiterung wird automatisch durch ein Installationsprogramm in expecco Installiert.<br>
Die Java Swing Erweiterung wird automatisch durch ein Installationsprogramm in expecco Installiert.<br>
Zeile 75: Zeile 147:
[[Datei:JDKPfadEinstellungen.png|border|600px|]]
[[Datei:JDKPfadEinstellungen.png|border|600px|]]


==== Installation auf dem Testanwendungsrechner ====
=== Installation auf dem Testanwendungsrechner ===


Es muss das javaBin Verzeichnis des Expecco Bridge Frameworks auf den Testrechner kopiert werden. Dieses befindet sich im expecco Installationsverzeichnis unter:
Es muss das javaBin Verzeichnis des Expecco Bridge Frameworks auf den Testrechner kopiert werden. Dieses befindet sich im expecco Installationsverzeichnis unter:
Zeile 81: Zeile 153:
<nowiki>...\exept\bridgeFramework\javaBridge\javaBin</nowiki>
<nowiki>...\exept\bridgeFramework\javaBridge\javaBin</nowiki>


=== expecco GUI Browser ===
== expecco GUI Browser ==


Der expecco GUI-Browser ist ein zusätzliches 'Werkzeug', welches die Möglichkeit bietet, laufende Anwendungen zu analysieren und Testsequenzen zu entwickeln. Anschließend kann man die Informationen, wie beispielsweise Namen und Eigenschaften einzelner Elemente dazu verwenden, um mit der Funktionsbibliothek Aktionen auszuführen bzw. mit einzelnen Elementen zu interagieren.
Der expecco GUI-Browser ist ein zusätzliches 'Werkzeug', welches die Möglichkeit bietet, laufende Anwendungen zu analysieren und Testsequenzen zu entwickeln. Anschließend kann man die Informationen, wie beispielsweise Namen und Eigenschaften einzelner Elemente dazu verwenden, um mit der Funktionsbibliothek Aktionen auszuführen bzw. mit einzelnen Elementen zu interagieren.


==== Verbindungsaufbau ====
=== Verbindungsaufbau ===


Im Folgenden eine kurze Bilderstrecke, die Ihnen beim Einrichten einer Verbindung als '''Leitfaden''' dienen kann<br>
Im Folgenden eine kurze Bilderstrecke, die Ihnen beim Einrichten einer Verbindung als '''Leitfaden''' dienen kann<br>
Zeile 108: Zeile 180:
Wenn eine Verbindung erfolgreich aufgebaut wurde, wird sie automatisch in die Expecco Konfigurationsliste eingetragen.<br>
Wenn eine Verbindung erfolgreich aufgebaut wurde, wird sie automatisch in die Expecco Konfigurationsliste eingetragen.<br>
Dort kann auch der GUI Aufbau der Anwendung als hierarchischer Baum eingesehen werden. <br>
Dort kann auch der GUI Aufbau der Anwendung als hierarchischer Baum eingesehen werden. <br>
Informationen zum weiteren Vorgehen können Sie hier finden [[Expecco_GUI_Tests_Extension_Reference]] <br>
Informationen zum weiteren Vorgehen können Sie hier finden: [[Expecco_GUI_Tests_Extension_Reference| GUI Test Referenz]] <br>
<hr width="50%"><br>
<hr width="50%"><br>
[[Datei:JavaSwing Connection Reconnect.png|border|600px|]]
[[Datei:JavaSwing Connection Reconnect.png|border|600px|]]
<br><br>
<br><br>
Wenn Sie zu einer zuvor verbundenen Anwendung erneut eine Verbindung aufstellen möchten, können Sie dies durch Rechtsklick auf den Eintrag.<br>
Wenn Sie zu einer zuvor verbundenen Anwendung erneut eine Verbindung aufstellen möchten, können Sie dies im Dialogfenster nach durch Rechtsklick auf den Eintrag.<br>
Falls Sie die Anwendung (oder im Fall entferntes System auch den Agenten) zwischenzeitlich neu gestartet haben, müssen Sie die Verbindung eventuell neu aufbauen.<br>
Falls Sie die Anwendung (oder im Fall entferntes System auch den Agenten) zwischenzeitlich neu gestartet haben, müssen Sie die Verbindung eventuell neu aufbauen.<br>
<br>
<hr width="50%"><br>


==== Verbindung zu Entfernten Systemen ====
=== Verbindung zu Entfernten Systemen ===
[[Datei:JavaSwing Connection RemoteSetup.png|border|600px|]]
[[Datei:JavaSwing Connection RemoteSetup.png|border|600px|]]
<br><br>
<br><br>
Zeile 128: Zeile 200:
* <code>-port >PortNummer</code> gibt dem Agenten einen spezifischen Port an, auf dem auf Verbindungen von Expecco gewartet werden soll.<br> Standardport ist 56784.
* <code>-port >PortNummer</code> gibt dem Agenten einen spezifischen Port an, auf dem auf Verbindungen von Expecco gewartet werden soll.<br> Standardport ist 56784.


==== Fehlerbehandlung ====
=== Warnhinweise ===
[[Datei:JavaSwing Connection Warnings.png|border|600px|]]
[[Datei:JavaSwing Connection Warnings.png|border|600px|]]
<br><br>
<br><br>
Zeile 137: Zeile 209:
::{|
::{|
|JAVA VERSION MISMATCH
|JAVA VERSION MISMATCH
|Wie im Bild zu sehen, kann es zu Java Versionskonflikten zwischen dem Agenten und der Anwendung kommen.<br> In diesem Fall ist es am einfachsten die Expecco Einstellungen für Java Bridge anzupassen.
|Wie im Bild zu sehen, kann es zu Java Versionskonflikten zwischen dem Agenten und der Anwendung kommen.<br> In diesem Fall ist es am einfachsten die Expecco Einstellungen für Java Bridge anzupassen.<br> Eine Remote Verbindung müsste das Programm stattdessen manuell mit der gewollten Java Version starten.<br> Der Java Agent, wenn über das <code>startAgentLoader</code> skript aufgerufen, wählt die Version Anhand von <code>JAVA_HOME</code> auf dem remote System
|-
|-
|32 BIT - 64 BIT KONFLIKT
|32 BIT - 64 BIT KONFLIKT
|32 und 64 Bit Versionen von Java sind nicht miteinander Kompatibel. <br>Sowohl der Agent als auch die Anwendung müssen mit der selben "Bit Version" von Java gestartet werden.
|32 und 64 Bit Versionen von Java sind nicht miteinander Kompatibel. <br>Sowohl der Agent als auch die Anwendung müssen mit der selben "Bit Version" von Java gestartet werden.<br>
|-
|-
|UNABLE TO DETERMINE VERSION
|UNABLE TO DETERMINE VERSION
|Der Agent kann nicht feststellen, welche Java Version die Anwendung nutzt. <br>Eine Verbindung ist eventuell möglich, es kann aber potentiell ein Versionskonflikt auftreten.
|Der Agent kann nicht feststellen, welche Java Version die Anwendung nutzt. <br>Eine Verbindung ist eventuell möglich, es kann aber potentiell ein Versionskonflikt auftreten.
|-
|CONNECTION REFUSED
|In seltenen Fällen, kann die Socket-Verbindung zu einer Anwendung oder dem Agent durch eine vorherige Verbindung blockiert werden. <br>Ein Neustart der Anwendung und des Agenten (im Fall remote) sollte helfen. <br>Sollte das Problem bestehen bleiben, prüfen Sie bitte auch ihre Firewall Einstellungen, die eine Verbindung verhindern können.
|}
|}
:
:


== Technologieübergreifende Verbindungen ==
=== JavaSwingLibrary ===
Falls eine Anwendung mehrere Java-Technologien verwendet, müssen Sie nur eine Verbindung aufbauen und dann die Bausteine aus der Library entsprechend der Technologie des anzusprechenden Elements verwenden.
=== Example ===

=== FAQ ===
=== Eingebettetes JavaFX in Java Swing ===
Ist JavaFX in eine Swing-Anwendung eingebettet, enthält diese ein Element JFXPanel. Im GUI-Browser werden die JavaFX-Elemente unterhalb von diesem Panel angezeigt. Damit die FX-Bausteine diese eingebetteten FX-Elemente finden, muss zu Beginn der Baustein ''Set FX Context To Panel'' aus der Swing-Library mit dem Pfad zum JFXPanel ausgeführt werden.

=== WebView in JavaFX ===
Ist ein WebView in JavaFX eingebunden, so werden dessen Elemente im GUI-Browser unterhalb des WebView-Elements angezeigt. Für diese Elemente gibt es eigene Bausteine in der JavaFX-Library, die im Ordner ''Embedded WebView'' zusammengefasst sind. Damit die Elemente im Test gefunden werden können, muss zuvor der Baustein ''Set WebView Context'' auf das Element WebView ausgeführt werden.

=== Eingebettetes Java Swing in JavaFX ===
Ist Java Swing in eine JavaFX-Anwendung eingebettet, enthält diese ein Element SwingNode. Im GUI-Browser wird dessen Inhalt bisher noch parallel zum FX-Inhalt angezeigt. Die Bausteine der Swing-Library können direkt mit diesen Elementen verwendet werden.

== JavaSwingLibrary ==

== Example ==

== FAQ ==
*'''Der Baum im GUI-Browsers zeigt nicht alle Elemente meiner Applikation'''
*'''Der Baum im GUI-Browsers zeigt nicht alle Elemente meiner Applikation'''
:Eine Applikation besteht aus vielen verschiedenen Elementen. Manche davon sind nicht interaktiv, das heißt sie sind für den Anwender nicht direkt sichtbar und dienen lediglich der Formatierung, wie beispielsweise Panels. Das Vorhandensein solcher Elemente führt dazu, dass der Baum sehr groß und tief werden kann. Da diese Elemente in der Regel für die Automatisierung uninteressant sind, werden sie in expecco standardmäßig ausgeblendet.
:Eine Applikation besteht aus vielen verschiedenen Elementen. Manche davon sind nicht interaktiv, das heißt sie sind für den Anwender nicht direkt sichtbar und dienen lediglich der Formatierung, wie beispielsweise Panels. Das Vorhandensein solcher Elemente führt dazu, dass der Baum sehr groß und tief werden kann. Da diese Elemente in der Regel für die Automatisierung uninteressant sind, werden sie in expecco standardmäßig ausgeblendet.
Zeile 171: Zeile 254:
:Durch das Ausführen des Bausteins ändert sich das Verhalten für die aktuelle Verbindung. Es bezieht sich sowohl darauf, was im Baum angezeigt wird, als auch, wie mit den Pfaden an den Bausteinen umgegangen wird.
:Durch das Ausführen des Bausteins ändert sich das Verhalten für die aktuelle Verbindung. Es bezieht sich sowohl darauf, was im Baum angezeigt wird, als auch, wie mit den Pfaden an den Bausteinen umgegangen wird.


*'''Ich kann mich nicht verbinden aber alle Einstellungen stimmen'''
== Java SWT ==
:Auch wenn dies generell nicht passieren sollte, hier ein paar Aspekte, die Einfluss auf die Verbindung nehmen können.
== JavaFX ==
::{|
|FIREWALL
|Die Firewall kann das kommunizieren des Java Agenten mit der Anwendung stören. <br>Entweder man richtet eine Ausnahmeregel für den Agenten ein oder aber man deaktiviert die Firewall für die Dauer des Tests.
|-
|SOCKET BELEGT
|Es kann vorkommen, besonders beim Debuggen, dass eine vorherige Instanz eines Java Agenten nicht korrekt geschlossen wurde. Das kann dazu führen, dass dieser den Socket belegt und andere Verbindungen abweist.<br>Über <code>Extrax => Fehleranalyse => Alle BridgeVerbindung schließen / Alle Socketverbindungen schließen</code> werden vorherige Instanzen entfernt. <br>Bitte beachten, dass damit auch alle anderen bestehenden (lokalen) Expecco Verbindungen geschlossen werden. Im Fall Remote sollte ein Neustart des Agenten und evtl. auch der Anwendung Abhilfe schaffen.
|}

Version vom 21. Dezember 2018, 16:28 Uhr

AllJavaInterfaces.png

expecco unterstützt unterschiedliche UI-Frameworks. Hierzu zählen unter anderem auch JavaFX, Java Swing und Java SWT. Die folgenden Abschnitte sollen einen Überblick in die von expecco unterstützten Java UI-Frameworks geben, um Ihnen einen schnellen und einfachen Einstieg zu ermöglichen. In diesem Zusammenhang wird Ihnen bei dieser Einführung von den Hauptmerkmalen der einzelnen Frameworks über die Funktionsweise, die Konfigurationen und den Anforderungen bis hin zu der Verwendung einzelner Funktionsbausteine aus den jeweiligen 'Funktionsbibliotheken' näher erläutert. Um das Verständnis zum theoretischen Teil noch zu festigen, wird im Anschluss ein Praxisnahes Beispiel Schritt für Schritt durchgearbeitet und beschrieben, bei dem Sie aktiv mitarbeiten können. Die dazu benötigten Testsuiten und Anwendungen laden Sie sich bitte über die in den Abschnitten zu Verfügung gestellten Links herunter.

Unterstützte Java-Technologien[Bearbeiten]

expecco unterstützt die Automatisierung von Java-Anwendungen, die mit Java Swing, Java SWT oder JavaFX implementiert sind. Ebenso weden Anwendungen unterstützt, die mehrere dieser Technologien vereinen, z.B. eine Swing-Anwendung mit eingebettetem JavaFX-Inhalt.

Java Swing[Bearbeiten]

Diese Erweiterung für expecco ermöglicht die Benutzeroberflächen Testautomatisierung für Java Anwendungen deren Benutzeroberflächen mit Swing erstellt wurden. Die Baustein-Bibliothek beinhaltet Blöcke zur Steuerung und Überprüfung von Swing Benutzeroberflächen. Zudem integriert sich diese Erweiterung in die expecco GUI Test Extension. Diese dient der Unterstützung bei der Entwicklung von Testsequenzen.

Hauptmerkmale[Bearbeiten]

  • Automatisierte Bedienung und Überprüfung von Swing Benutzeroberflächen
  • Gleichzeitige Bedienung mehrerer Anwendungen
  • Steuerung von Swing Benutzeroberflächen auf entfernten Zielsystemen
  • Steuerung von bereits eigenständig Laufenden Java Anwendungen (keine Änderung am Quell-Code notwendig, Keine Rekompilierung der Anwendung nötig)
  • Adressierung der Bedienelemente durch Pfade ähnliche dem XPath
  • Zugriff auf Objektebene durch Java Bridge Interface Library möglich
  • Integration in die expecco GUI Tests Extension
  • Block-Bibliothek mit Aktionen und Überprüfungen für Swing Komponenten

Java SWT[Bearbeiten]

JavaFX[Bearbeiten]

Ab Java 11 ist JavaFX nicht mehr im JDK enthalten. Daher müssen Sie zusätzlich ein JavaFX SDK installieren, z.B. von OpenJFX. Kopieren Sie dann die jar-Dateien aus dem lib-Verzeichnis des JavaFX JDKs nach packages\exept\expecco\plugin\javafx\lib im expecco-Installationsverzeichnis.

Funktionsweise[Bearbeiten]

Das Interface baut eine Verbindung zur Java VM auf, und stellt Funktionen zum Lesen von Widget-Attributen, Aufnehmen von Benutzereingaben sowie zum Fernsteuern der Anwendung zur Verfügung. Außerdem werden in einer Bibliothek zusätzliche Bausteine zur Automatisierung von Tests bereitgestellt. Im wesentlichen besteht das Java Swing plugin aus zwei Teilen, der Erweiterung für expecco und der Applikationssteuerung (Agent). Zur Steuerung der Swing Anwendung wird ein so genannter Agent in die Java Virtual Machine der laufenden Java Anwendung geladen. Um den Agenten zu laden wird ein Java Development Kit 1.8 (JDK) oder höher benötigt. Die zu Testende Anwendung kann jedoch in einer normalen Java Runtime Edition 1.8 (JRE) ausgeführt werden.

Anforderungen[Bearbeiten]

Auf dem Rechner auf dem die zu testende Anwendung laufen soll (lokal oder entfernt):

Auf dem expecco Rechner gelten die expecco Anforderungen.

Bitte nehmen Sie zur Kenntnis, dass sowohl der Agent als auch die zu testende Anwendung, jeweils beide entweder mit 32 oder 64 Bit Java gestartet werden müssen, da ansonsten keine Verbindung möglich ist.
Aufgrund von JDK Änderungen zwischen den Java Versionen, können potentiell Versionskonflikte auftreten.

Die Kompatibilität der Versionen ist wie folgt. Weitere Informationen dazu.
JavaSwing Bridge Compatibility.png

Zugriffsberechtigungen[Bearbeiten]

Um eine Verbindung auf dem Zielsystem garantieren zu können, müssen beim Start der zu testenden Anwendung (sowie des Java Agenten) zusätzliche Parameter mitgegeben werden.
Dabei ergeben sich zwei Möglichkeiten dies zu tun

  • Setzen einer Umgebungsvariablen die automatisch beim Start jeder Java Anwendung geladen wird
  • Manuelle Übergabe der Parameter bei jedem Start einer Java Anwendung
  • (Alternativ kann man Zugriffsrechte in den module-info.java Dateien direkt verändern, dies ist jedoch alles andere als praktikabel)

Bis Java 11 sollte es ausreichen, folgende Parameter zu setzen:
-Djdk.attach.allowAttachSelf=true
--illegal-access=permit

Das Setzen einer Umgebungsvariable funktioniert folgendermaßen (Am Beispiel JDK_JAVA_OPTIONS welche bei jedem JVM Start geladen wird)
für Windows Systeme

  • setx JDK_JAVA_OPTIONS "-Djdk.attach.allowAttachSelf=true; --illegal-access=permit"
  • oder über das GUI (Windowstaste + Pause).

Windows Setenvironment.png

für Unix Systeme

  • Bash: export _JAVA_OPTIONS='-Djdk.attach.allowAttachSelf=true; --illegal-access=permit'
  • C Shell: setenv _JAVA_OPTIONS '-Djdk.attach.allowAttachSelf=true; --illegal-access=permit'


Ab Java 11 erfolgt für die Kapselung von Modulen eine striktere Trennung:
--illegal-access=permit wird dabei nicht mehr funktionieren, falls die Zielapplikation eine festgelegte Modulkapselung besitzt (Details).
In diesem Fall müssen beim Programmstart zusätzliche Parameter angegeben werden, welche Expecco einen Zugriff auf die innewohnenden Ressourcen gewähren.
Je nach verwendeter Technologie können die benötigten Parameter variieren, weshalb Sie diese selbstständig herausfinden müssen.
jdeps list-deps JARNAME.jar Jdeps ist dafür ein frei verfügbares (teil der jdk) sehr nützliches Werkzeug.
Eine kurze Übersicht der Kommandos findet man hier ©


Beispiel JavaFX:
Die Umgebungsvariable PATH_TO_FX die auf das JavaFX Verzeichnis zeigt muss gesetzt sein (Funktionsweise s.o.)
Die folgenden Parameter müssen beim Start der Java Anwendung vorhanden sein

ParameterListe (ausklappbar)

  • --module-path "%PATH_TO_FX%"
  • --add-modules=javafx.controls
  • --add-modules=javafx.swing
  • --add-modules=javafx.web
  • --add-opens javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.stage=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.scene=ALL-UNNAMED
  • --add-opens javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.scene.layout=ALL-UNNAMED
  • --add-opens javafx.controls/javafx.scene.control=ALL-UNNAMED
  • --add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED
  • --add-opens javafx.controls/javafx.scene.chart=ALL-UNNAMED
  • --add-exports javafx.controls/com.sun.javafx.charts=ALL-UNNAMED
  • --add-opens javafx.controls/com.sun.javafx.charts=ALL-UNNAMED
  • --add-exports javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED
  • --add-opens javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.scene.image=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.scene.shape=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.scene.text=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.application=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.geometry=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.scene.robot=ALL-UNNAMED
  • --add-exports javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
  • --add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
  • --add-opens javafx.graphics/com.sun.glass.ui.win=ALL-UNNAMED
  • --add-opens javafx.graphics/javafx.scene.input=ALL-UNNAMED
  • --add-opens javafx.base/javafx.event=ALL-UNNAMED
  • --add-exports javafx.base/com.sun.javafx.runtime=ALL-UNNAMED
  • --add-opens javafx.base/com.sun.javafx.runtime=ALL-UNNAMED
  • --add-exports javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED
  • --add-exports javafx.graphics/com.sun.javafx.util=ALL-UNNAMED
  • --add-exports javafx.graphics/com.sun.javafx.scene.input=ALL-UNNAMED
  • --add-exports javafx.web/com.sun.webkit.dom=ALL-UNNAMED

Sollten Sie dennoch einen java.lang.IllegalAccessError erhalten, müssen Sie diese Parameter in folgender Weise erweitern:

  • Fehlertext der Art module <module> does not "opens <package>" to unnamed module
--add-opens <module>/<package>=ALL-UNNAMED
Beispiel: module java.base does not "opens java.lang" to unnamed module lösen Sie mit --add-opens java.base/java.lang=ALL-UNNAMED
  • Fehlertext der Art cannot access class <package>.<class name> (in module <module>) because module <module> does not export <package> to unnamed module
--add-exports <module>/<package>=ALL-UNNAMED
Beispiel: cannot access class com.sun.javafx.scene.input.ExtendedInputMethodRequests (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.input to unnamed module lösen Sie mit --add-exports javafx.graphics/com.sun.javafx.scene.input=ALL-UNNAMED

Konfiguration[Bearbeiten]

Installation auf dem expecco Rechner[Bearbeiten]

Die Java Swing Erweiterung wird automatisch durch ein Installationsprogramm in expecco Installiert.
Wird die zu Testende Anwendung zur Entwicklung von Testsequenzen auf dem gleichen Rechner ausgeführt sollte nach dem Start von expecco unter
Extras => Einstellungen => Erweiterungen => Java Bridge der Lokale Pfad zu einem Java Development Kit 1.8 oder höher angegeben werden.
Die unbedingt erforderliche Einstellung hier ist Pfad zur JDK Installation welcher für die Hauptverbindung genutzt wird.
Pfad zur Java Installation ist eine alternative Einstellung für Groovy, welches nur ein JRE benötigt.
Der Java Agent wird in lokalen Verbindungen automatisch mit diesen Einstellungen gestartet.

JDKPfadEinstellungen.png

Installation auf dem Testanwendungsrechner[Bearbeiten]

Es muss das javaBin Verzeichnis des Expecco Bridge Frameworks auf den Testrechner kopiert werden. Dieses befindet sich im expecco Installationsverzeichnis unter:

         ...\exept\bridgeFramework\javaBridge\javaBin

expecco GUI Browser[Bearbeiten]

Der expecco GUI-Browser ist ein zusätzliches 'Werkzeug', welches die Möglichkeit bietet, laufende Anwendungen zu analysieren und Testsequenzen zu entwickeln. Anschließend kann man die Informationen, wie beispielsweise Namen und Eigenschaften einzelner Elemente dazu verwenden, um mit der Funktionsbibliothek Aktionen auszuführen bzw. mit einzelnen Elementen zu interagieren.

Verbindungsaufbau[Bearbeiten]

Im Folgenden eine kurze Bilderstrecke, die Ihnen beim Einrichten einer Verbindung als Leitfaden dienen kann

JavaSwing GUI Browser.png

Zunächst wählt man über den GUI Browser (schwarzer Kreis) im Reiter Verbinden die Option Java (roter Kreis) aus. Im sich öffnenden Dialog kann man nun zwischen 3 Optionen wählen.

  • Anwendung auf der lokalen Maschine starten
    liefert eine bequeme Möglichkeit eine lokale Java Anwendung per Kommandozeilenbefehl zu starten
  • Zu einer laufenden Anwendung auf der lokalen Maschine verbinden
    Ermöglicht die Verbindung zu lokal laufenden Java Anwendungen
    Der Java Agent wird automatisch mit der Java Version, die Sie in den Expecco Einstellungen festgelegt haben, gestartet.
  • Zu einer laufenden Anwendung auf einer anderen Maschine verbinden
    Ermöglicht die Verbindung zu einem bereits gestarteten Java Agenten auf einer anderen Maschine
    Dieser stellt dann die Verbindung zur dort laufenden Java Anwendung her.


JavaSwing Connection Window.png

Eine Suche nach Java Anwendungen listet uns alle laufenden Java Virtuellen Maschinen auf, die sich auf dem Zielsystem befinden
(im Beispiel: localhost). Eine Auswahl der einzelnen Einträge listet weitere Informationen über die betreffende Anwendung auf.



JavaSwing Connection Connected.png

Wenn eine Verbindung erfolgreich aufgebaut wurde, wird sie automatisch in die Expecco Konfigurationsliste eingetragen.
Dort kann auch der GUI Aufbau der Anwendung als hierarchischer Baum eingesehen werden.
Informationen zum weiteren Vorgehen können Sie hier finden: GUI Test Referenz



JavaSwing Connection Reconnect.png

Wenn Sie zu einer zuvor verbundenen Anwendung erneut eine Verbindung aufstellen möchten, können Sie dies im Dialogfenster nach durch Rechtsklick auf den Eintrag.
Falls Sie die Anwendung (oder im Fall entferntes System auch den Agenten) zwischenzeitlich neu gestartet haben, müssen Sie die Verbindung eventuell neu aufbauen.

Verbindung zu Entfernten Systemen[Bearbeiten]

JavaSwing Connection RemoteSetup.png

Um eine Verbindung remote zu erstellen, muss zunächst auf dem Zielrechner der Java Agent gestartet werden.
Dazu navigieren Sie auf dem Rechner zum zuvor kopierten Verzeichnis ...\exept\bridgeFramework\javaBridge\javaBin
Dort liegt ein Skript, welches automatisch die Java Version in JAVA_HOME erkennt und den korrekten Agenten startet.

  • Windows Nutzer starten startAgentLoader.bar
  • UNIX Nutzer starten startAgentLoader.sh

Diese Skripte können über die Kommandozeile wie im Bild gezeigt mit Parametern versehen werden.

  • -ip <HostnameOderIP> gibt dem Agenten eine spezielle IP an, auf der auf eine Verbindung gewartet werden soll. Nützlich für spezifische Netzwerkmasken.
    StandardHost ist 0.0.0.0.
  • -port >PortNummer gibt dem Agenten einen spezifischen Port an, auf dem auf Verbindungen von Expecco gewartet werden soll.
    Standardport ist 56784.

Warnhinweise[Bearbeiten]

JavaSwing Connection Warnings.png

Sollten bei den Anwendungen in dieser Liste Probleme auftreten wie im oben stehenden Bild zu sehen ist, liefert der Verbindungsdialog automatisch einen Lösungsvorschlag.
Wenn der auftretende Fehler eine Verbindung unmöglich machen würde, wird der Entsprechende Eintrag automatisch als ungültig markiert.
Folgende Fehlermeldungen könnten eventuell auftreten und sind einfach behebbar:

JAVA VERSION MISMATCH Wie im Bild zu sehen, kann es zu Java Versionskonflikten zwischen dem Agenten und der Anwendung kommen.
In diesem Fall ist es am einfachsten die Expecco Einstellungen für Java Bridge anzupassen.
Eine Remote Verbindung müsste das Programm stattdessen manuell mit der gewollten Java Version starten.
Der Java Agent, wenn über das startAgentLoader skript aufgerufen, wählt die Version Anhand von JAVA_HOME auf dem remote System
32 BIT - 64 BIT KONFLIKT 32 und 64 Bit Versionen von Java sind nicht miteinander Kompatibel.
Sowohl der Agent als auch die Anwendung müssen mit der selben "Bit Version" von Java gestartet werden.
UNABLE TO DETERMINE VERSION Der Agent kann nicht feststellen, welche Java Version die Anwendung nutzt.
Eine Verbindung ist eventuell möglich, es kann aber potentiell ein Versionskonflikt auftreten.

Technologieübergreifende Verbindungen[Bearbeiten]

Falls eine Anwendung mehrere Java-Technologien verwendet, müssen Sie nur eine Verbindung aufbauen und dann die Bausteine aus der Library entsprechend der Technologie des anzusprechenden Elements verwenden.

Eingebettetes JavaFX in Java Swing[Bearbeiten]

Ist JavaFX in eine Swing-Anwendung eingebettet, enthält diese ein Element JFXPanel. Im GUI-Browser werden die JavaFX-Elemente unterhalb von diesem Panel angezeigt. Damit die FX-Bausteine diese eingebetteten FX-Elemente finden, muss zu Beginn der Baustein Set FX Context To Panel aus der Swing-Library mit dem Pfad zum JFXPanel ausgeführt werden.

WebView in JavaFX[Bearbeiten]

Ist ein WebView in JavaFX eingebunden, so werden dessen Elemente im GUI-Browser unterhalb des WebView-Elements angezeigt. Für diese Elemente gibt es eigene Bausteine in der JavaFX-Library, die im Ordner Embedded WebView zusammengefasst sind. Damit die Elemente im Test gefunden werden können, muss zuvor der Baustein Set WebView Context auf das Element WebView ausgeführt werden.

Eingebettetes Java Swing in JavaFX[Bearbeiten]

Ist Java Swing in eine JavaFX-Anwendung eingebettet, enthält diese ein Element SwingNode. Im GUI-Browser wird dessen Inhalt bisher noch parallel zum FX-Inhalt angezeigt. Die Bausteine der Swing-Library können direkt mit diesen Elementen verwendet werden.

JavaSwingLibrary[Bearbeiten]

Example[Bearbeiten]

FAQ[Bearbeiten]

  • Der Baum im GUI-Browsers zeigt nicht alle Elemente meiner Applikation
Eine Applikation besteht aus vielen verschiedenen Elementen. Manche davon sind nicht interaktiv, das heißt sie sind für den Anwender nicht direkt sichtbar und dienen lediglich der Formatierung, wie beispielsweise Panels. Das Vorhandensein solcher Elemente führt dazu, dass der Baum sehr groß und tief werden kann. Da diese Elemente in der Regel für die Automatisierung uninteressant sind, werden sie in expecco standardmäßig ausgeblendet.
Wenn Sie in Ihrem Fall auf eines dieser Elemente zugreifen wollen oder es für das Erstellen eines eindeutigen Pfades brauchen, können Sie dieses Verhalten ändern. In der JavaSwingLibrary gibt es dafür den Baustein Set Skip Mode. Dabei sind vier Modi auswählbar:
INTERACTIVE nur interaktive Elemente einsammeln
ALL alle Elemente einsammeln
INTERACTIVE_HYBRID wie INTERACTIVE, aber mit dem Fallback zu ALL wenn ein Pfad nicht aufgelöst werden kann
ALL_HYBRID wie ALL, aber mit dem Fallback auf INTERACTIVE wenn ein Pfad nicht aufgelöst werden kann
Durch das Ausführen des Bausteins ändert sich das Verhalten für die aktuelle Verbindung. Es bezieht sich sowohl darauf, was im Baum angezeigt wird, als auch, wie mit den Pfaden an den Bausteinen umgegangen wird.
  • Ich kann mich nicht verbinden aber alle Einstellungen stimmen
Auch wenn dies generell nicht passieren sollte, hier ein paar Aspekte, die Einfluss auf die Verbindung nehmen können.
FIREWALL Die Firewall kann das kommunizieren des Java Agenten mit der Anwendung stören.
Entweder man richtet eine Ausnahmeregel für den Agenten ein oder aber man deaktiviert die Firewall für die Dauer des Tests.
SOCKET BELEGT Es kann vorkommen, besonders beim Debuggen, dass eine vorherige Instanz eines Java Agenten nicht korrekt geschlossen wurde. Das kann dazu führen, dass dieser den Socket belegt und andere Verbindungen abweist.
Über Extrax => Fehleranalyse => Alle BridgeVerbindung schließen / Alle Socketverbindungen schließen werden vorherige Instanzen entfernt.
Bitte beachten, dass damit auch alle anderen bestehenden (lokalen) Expecco Verbindungen geschlossen werden. Im Fall Remote sollte ein Neustart des Agenten und evtl. auch der Anwendung Abhilfe schaffen.



Copyright © 2014-2024 eXept Software AG