Selenium und ExtJs

2009 5 June

Da es mich sehr viel Zeit gekostet hat die ExtJs Web Desktop Anwendung mit Selenium zu testen will ich euch kurz hier meine Lösung dafür vorstellen

Der wichtigste Punkt ist, dass verschiedene Stellen, wie der START Button unten links, auf einen mouseDown Event hört und nicht auf click Event, wie man zunächst meinen würde. Sobald ich das herausgefunden hatte kam ich eigentlich ganz gut zurecht. Ein sehr hilfreicher Selenium Command ist waitForElementPresent, den man relativ häufig einsetzten muss da das Element nicht sofort da ist und ansonsten nicht gefunden wird.
Was man auf jeden Fall anpassen muss sind die dynamischen ids, der Selenium IDE hat in der Regel ganz brauchbare Vorschläge für CSS Selectoren oder XPATH, die in den meisten Fällen ausreichen ansonsten muss man sich das selber schreiben.

Hier ein Bespiel

RubrikTest
mouseDown //button[@id='x-startbutton']
mouseOver //a[contains(text(),'Inhalt')]
waitForElementPresent //div[@class="x-layer x-menu"]
click //a[contains(text(),'Menue1')]
click //table[@id='id_add-rubrik']/tbody/tr/td[2]/em/button
type document.forms[0].elements[1] 1. Selenium Test Rubrik
type document.forms[0].elements[2] Neue Beschreibung
click //a[12]/em
click //div/table/tbody/tr/td[2]/em/button
waitForElementPresent //div[contains(text(),'1. Selenium Test Rubrik')]
mouseDown //tbody/tr/td[2]/div
click //td[3]/table/tbody/tr/td[2]/em/button
click //a[contains(text(),'löschen')]
waitForElementPresent //div[@class="x-window-tl"]
click //div[2]/div/div/div/div/div/table/tbody/tr/td[2]/table/tbody/tr/td[2]/em/button

Bearbeiten

Exceptions Fangen und Werfen - Teil 2

2009 4 April

Ein Phänomen welches leider häufiger auftaucht ist das sämtliche Exception gefangen werden und dann als eine bestimmte Exception weiter geschmissen werden. Dadurch geht leider die ursprüngliche Ursache der Exception verloren, was zu großen Verwirrungen führen kann.

class user {
public function save() {
$mail->send();
...
}
}
try{
$user = new User();
$user->setName();
$user->save();
} catch (Exception e) {
throw new UserNotSavedException();
}

Wenn hier jetzt die Mail nicht verschickt werden kann, weil z.B der Mailserver nicht da ist, dann wird trotzdem die UserNotSavedException geschmissen. Dies ist erstens nicht richtig und kann zweitens vor allem wenn es komplexer wird zu sehr verwirrenden Aussagen führen, die ein langes Debuggen erfordern können. Besser wäre es die Exception z.B. so zu behandeln:

try{
$user = new User();
$user->setName();
$user->save();
} catch (UserNotSavedException e) {
echo $e->getMessage();
} catch(MailExeception)){
echo $e->getMessage();
}

So ist immer klar was schief gelaufen ist und man kann entsprechend reagieren.


Bearbeiten

Exceptions Fangen und Werfen - Teil 1

2009 28 March

Leider sehe ich immer wieder seltsame Konstrukte wie Exceptions in php behandelt werden. Exceptions sollten zunächst einmal nur, wie der Name schon sagt, in Ausnahmen geschmissen werde. Wann eine Ausnahme ist bestimmt der Kontext. Es kann z.B in einem Fall notwendig sein, dass ein bestimmte Datei vorhanden ist um den Programmablauf fortsetzten zu können. In einem anderen Fall reicht es eventuell einfach ein NULL oder FALSE zurückzugeben, da es kein Einfluss auf den weiteren Programmverlauf hat.
Denn "Exception heißt nicht, dass sie nur ausnahmsweise richtig eingesetzt werden. :-)"

Wenn ich dann eine Exception schmeiße ist zunächst einmal wichtig den Stacktrace nicht zu verschlucken indem man z.B eine Exception fängt und gleich weiter wirft:

try {
//irgendetwas was schief geht
$life = new Life();
$life->solveAllProblems();
} catch ( Exception $e ) {
throw new Exception ( 'Es konnten nicht alle Fragen des Lebens geklärt werden' );
}

hierbei geht die Message bzw. der ganze Stacktrace des try Blocks verloren und wir bekommen nur "Es konnten nicht alle Fragen des Lebens geklärt werden" anstelle der speziellen Exception die eventuell in Life::solveAllProblems geworfen wurde.

Sinnvoll wäre es z.B:

try {
//irgendetwas was schief geht
$life = new Life();
$life->solveAllProblems();
} catch ( ProblemOfLifeAnDeathException $e ) {
// hier könnte man dann diese spezielle Ausnahme behandeln
// wenn jemand weiß was da zu tun ist :-)
// aber keine Sorge die wenigsten schmeißen diese Exception
}
$life->liveAHappyLife();

Dies ist sicherlich nur eine wichtige Grundregel für das richtige Werfen und Fangen von Exceptions, aber mal ein Anfang.


Bearbeiten

Tutorials in phpDoc einbinden

2009 24 March

Ich habe ein, mir neues Feature in phpDoc gefunden um Tutorials direkt in den generierten Code einzubinden.
Alles was man dafür tun muss ist in ein xml Dokument im docBook Format zu schreiben und dieses in ein bestimmtes Verzeichnis zu legen. PhpDoc findet darauf hin die Files automatisch und generiert das Tutorial zusammen mit der restlichen API Doc.
Das ebenso generierte Tutorial findet ihr hier hier


Bearbeiten

Benennung und Verantwortung von Testmethoden

2009 22 March

Für die Benennung von Tests sollte die selben Regeln gelten wie für die Benennung von Methodennamen, und zwar sollten sie möglichst beschreibend sein. Der Methodennamen soll beschreiben was getestet wird und zwar so, dass auch jemand der nicht viel von Programmierung versteht sofort weiß was hier getestet wird.

   public function testUserIsActiveUser() {
$this->assertTrue($this->user->isActive()):
}
public function testUserNotActiveUser() {
$this->assertFalse($this->user->isActive()):
}
public function testUserHasBlog() {
$this->assertType('Blog', $this->user->getBlog()):
}

und nicht sowas wie hier: Teste alles was so mit dem User zu tun hat

   public function testUser() {
$this->assertTrue($this->user->isActive()):
$this->user->setIsActive(false);
$this->assertFalse($this->user->isActive()):
$this->assertType('Blog', $this->user->getBlog()):
}

Dieser Fall ist noch einigermaßen übersichtlich, aber schon hier weiß man, bei fehlschlagenden Tests nicht was eigentlich nicht funktioniert, da einfach die Testmethode testUser fehlschlägt und nicht testUserIsActive.
Es ist also sehr wichtig nur eine Eigenschaft pro Testmethode zu testen und diese richtig zu benennen.
Hierfür gilt die Regel: Eine Testmethode für eine einfache Funktion und dann je ein weitere für eins der folgenden Keywords: if, while, for, foreach, AND, OR, case u.ä.


Bearbeiten
Torsten Zander


 RSS Feed abonnieren

Twitter  Auf Twitter folgen

Posts

Blogrolls