Testen von SmartGWT Anwendungen mit Selenium und Robot Framework

2 Kommentare

Seit einigen Wochen verwenden wir SmartGWT in unserem GWT Projekt. SmartGWT bietet sehr umfangreiche und komfortable Benutzeroberflächen. Zur Freude aller Entwickler, beinhaltet der SmartGWT-Showcase sehr viele Code-Beispiele und unser Kunde war nach dem ersten Sprint Review Meeting ebenfalls sehr zufrieden mit der neuen Benutzeroberfläche.

ABER… Wie Ihr vielleicht wisst, ist Qualität für unsere Agile Software Factory sehr wichtig. Also starteten wir wie immer mit der Implementierung unserer Akzeptanztest auf Basis von Selenium und dem Robot Framework, wie wir es schon oft vorher getan haben. Leider war dies nicht so einfach wie gedacht und wir mussten zusätzlichen Aufwand investieren. In diesem Blog möchte ich einige Tipps und Trick bei der Verwendung von Selenium und dem Robot Framework in Verbindung mit SmartGWT veröffentlichen.

Als wir die ersten Testfälle mit der Selenium IDE aufzeichneten, bemerkten wir beim Abspielen schnell, dass dies leider nicht funktionierte. SmartGWT erzeugt hochkomplexe HTML-Strukturen und benötigt zusätzliche Browserevents, um korrekt arbeiten zu können. Das Lokalisieren der Benutzerkomponenten und die korrekten Events waren also das Hauptproblem.

SmartGWT unterstützt seit Version 2.2. Selenium. Dazu werden Benutzererweiterungen angeboten, die in die Selenium IDE und für automatisierte Tests in den Selenium Server eingebunden werden können.

Wer sich für Details interessiert, kann einen Blick in die selenium-api.js werfen. Dies ist die Original-Version und beinhaltet die Implementierung aller Selenium-Commands, wie z.B. doClick(). Diese Implementierung ist für SmartGWT leider nicht ausreichend. Die entsprechende Benutzerweiterung ist im SmartGWT 2.2 Download unter /selenium/user-extension.js zu finden. Dies erweitert die Original-Funktionalität und feuert z.B. einige zusätzliche Events (Mouse-Up, Mouse-Down).

Beispiel doClick:

this.browserbot.triggerMouseEvent(element, "mousedown", true, clientX, clientY);
this.browserbot.triggerMouseEvent(element, "mouseup", true, clientX, clientY);
this.browserbot.clickElement(element);

Die Benutzererweiterng führt zusätzlich einen weiteren Element-Lokator scLocator ein. Dieser Lokator kann wie die existierenden Selenium-Lokatoren (xpath, css, id) benutzt werden. Alle Sonderbehandlungen für SmartGWT-Komponenten werden nur bei Benutzung des scLocator angewendet. Ansonsten wird das Selenium-Standardverhalten genutzt. Oder, um genau zu sein, es SOLLTE das Standardverhalten genutzt werden. Dies ist in Version 2.2 leider nicht konsequent umgesetzt, so dass wir eine Version aus dem nightly build von SmartGWT 2.3 nutzen und einige Codezeilen angepasst haben.

Tipps und Tricks zum Testen

ID’s

Fügt einige sprechende ID’s in euren Code ein. Andernfalls nutzt ihr von SmartGWT generierte ID’s, die nach jedem neuen Build unterschiedlich sein können.

Beispiele:

Button searchPerson = new Button(MESSAGES.personBt());
searchPerson.setID("searchPerson");
ListGrid hitList = new ListGrid();
hitList.setID("hitList");

Nutzt Selenium IDE

Selenium IDE ist zum Erstellen von Testfällen sehr hilfriech. Nutzt die rechte Maustaste in eurer Anwendung und fügt einige Verify’s aus dem entsprechenden Kontextmenü hinzu. Ihr bekommt so einen Eindruck über die verwendeten Lokatoren. Falls ihr die user-extension-ide.js auch konfiguriert habt, wird die Selenium IDE auch einige der neuen scLocators vorschlagen. Bevor ihr jedoch die aufgezeichneten scLocators in euer endgültiges Test-Skript übernehmt, solltet ihr die Ausdrücke noch etwas kürzen, um saubere und wartungsfreundliche Skripts zu haben.

Beispiel: Dieser Ausdruck

scLocator=//DynamicForm[ID="doSearchForm"]/item[name=mainRegisterBox||title=Main%20Register||index=0||Class=ComboBoxItem]/element

kann zu diesem Ausdruck gekürzt werden.

scLocator=//DynamicForm[ID="doSearchForm"]/item[name=mainRegisterBox]/element

Robotframework

Falls ihr das Robot Framework nutzt, könnt Ihr leider nicht alle Keywords der SeleniumLibray nutzen. Keywords, die auf jeden Fall funktionieren sind „Call Selenium Api“, „Execute JavaScript“ und „Wait For Condition“.
Damit die Keywords der SeleniumLibray funktionieren, muss eine Location Strategy im robotframework hinzugefügt werden (siehe Kommentar 1 und 3).

Beispiele:

Call Selenium Api  click  scLocator=//Button[ID="searchPerson"]/
Call Selenium Api  verifyTable  scLocator=//ListGrid[ID="hitList"].0.0  05/20/2010

Nutzt JavaScript

Falls Tests oder Aktionen nicht einfach über die scLocators abzubilden sind, nutzt einfach JavaScript! Zur Erinnerung, euer Java Client Code wird in JavaScript übersetzt. Dies ist der Grund, warum ihr sehr viele Methoden der Objekte auch im Browser nutzen könnt.

Beispiele:

Execute JavaScript  window.hitList.selectRecord(2);
Execute JavaScript  window.hitList.deselectAllRecords();

Nutzt Firebug um Eure JavaScript-Ausdrücke zu testen

Firebug biete einige nützliche Funktionen um JavaScript Ausdrücke zu testen. Manchmal gibt es sogar Autovervollständigung für JavaScript. Dies ist besonders hilfreich, wenn man noch nicht alle Funktionen der zu testenden Komponente kennt.

Benutzt WaitFor statt Sleep

Als wir mit den Akzeptanz-Test für unsere GWT Anwendungen begonnen haben, waren unsere Testfälle voll mit „Sleep 2s“-Anweisungen. Da GWT mit Ajax Requests arbeitet, kann man nie genau wissen, wann die Antwort angekommen und sich die Oberfläche geändert hat. Es gibt keine neu geladene Seite, was das Kernkonzept von Seleniums xxxAndWait-Keywords ist. Die „Sleeps“ funktionieren, sind aber unzuverlässig und verlangsamen die Testläufe deutlich. Besser sind WaitFor-Keywords mit Timeouts.

Beispiele:

Wait For Condition  window.hitList.data.length == 5  2000
Wait For Condition  window.confirmBox.isVisible() == true  2000
Call Selenium Api  waitForElementPresent  scLocator=//ListGrid[ID="hitList"]/body/row[0]/col[0]  2000

Benutzt kein klassisches GWT gemixt mit SmartGWT

Dieser Tipp hat nichts mit dem Thema „Testen“ zu tun, ist aber dennoch wichtig. Benutzt keine klassischen GWT Komponenten in Verbindung mit SmartGWT Komponenten. Entscheidet euch für einen der beiden Ansätze. Die Komponenten harmonieren nicht gut zusammen und erschweren z.B. das Layout der Anwendung sehr. Wir haben den gemischten Ansatz getestet und sind nach kurzer Zeit komplett auf SmartGWT gewechselt.

Daniel Reuter

Daniel gehört seit April 2009 zum Team der codecentric. Seine Schwerpunkte liegen in der Entwicklung von Enterprise-Anwendungen im Versicherungsumfeld. Daniel ist Allroundcodehacker, Architekturgedankenpfleger, Sauberkeitsprogrammierenthusiast, Teamzusammenarbeitshelfer und Versicherungsfachdomänenfreund.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentare

  • Daniel Reuter

    Hi Andreas,

    thank you for this great tipp!

    I added the following line to the our suite-setup

    Add Location Strategy  scLocator  return Selenium.prototype.locateElementByScLocator(scLocator, inDocument, inWindow);

    And after that, you can perfectly use all Keywords from the Seleniumlibrary. For example:

    Click Button  scLocator=//Button[ID="searchPerson"]/  don't wait
  • Daniel Reuter

    Which SmartGWT-Version are you using? „AutoTest.getPageCoords“ is not included in SmartGWT 2.2. Nevertheless, if you want to use the better 2.4 user-extension.js together with the old SmartGWT 2.2, then you can use my temporary solution from here.

    But if you use SmartGWT 2.4, then the user-extension.js from the 2.4 Release should work!

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.