Automation einer Google-Suchanfrage (Professionelle Browser-Automation mit Selenium WebDriver, Teil 1)

Es gibt verschiedene Szenarien, in denen ich mir wünsche, der Web-Browser könne ganz ohne mein Zutun arbeiten, z.B. wenn ich

  • die Webseiten einer Webanwendung, die gerade neu entwickelt wird, wiederholt testen muss,
  • bestimmte Informationen von einer externen Website regelmäßig ablesen und archivieren möchte,
  • über einen längeren Zeitraum kontrollieren will, ob meine eigene Website ganz oben im Google-Ranking steht.

Die gute Nachricht: Der Browser kann es, und mit Selenium WebDriver1) (SelWD) sogar auf flexible Art und Weise. Im ersten Teil dieses Artikels demonstriere ich das generelle Vorgehen anhand einer automatisierten Suchanfrage an Google. In Teil 2 zeige ich, wie Sie durch Erweiterung des Objektmodells ein professionelles Projekt zum wiederholten Testen von Web-Formularen einrichten.

Einen ausführlichen Artikel zum Thema mit Fokus auf die Testautomation habe ich in der dotnetpro 5/20132) veröffentlicht.

Voraussetzungen

  • Windows 7 Professional SP 1
  • Visual Studio 2012

Hintergrund

SelWD ist aus einer Fusion der Open-Source-Projekte Selenium 1 und WebDriver hervorgegangen, die beide das gleiche Ziel hatten: Ein API für die Automation von Browser-Aktionen zur Verfügung zu stellen. Der Browser lässt sich mit SelWD also programmatisch steuern (in Java, C#, Ruby, Python, JavaScript und einigen anderen Sprachen) und somit in Software-Projekte einbinden. Verwechseln Sie SelWD aber nicht mit dem Produkt Selenium IDE, das im Wesentlichen ein aufgebohrter Makrorekorder ist und kein API bereitstellt.

Grundsätzlich arbeitet SelWD so, dass es das Verhalten eines echten Anwenders imitiert, indem es mit dem Webbrowser bzw. der geladenen Webseite interagiert. Sie können dabei sogar zusehen. Das Tool ist in der Lage, Elemente der Webseite über Selektoren zu finden und dann z.B. Textinhalte auszulesen, Einträge in Formularen zu machen und Buttons anzuklicken. Anschließend prüft es, ob sich die Webseite wie erwartet verhält.

Als Beispiel für eine einfache Browser-Automation soll ein C#-Programm dienen, welches das Google-Ranking der IKS GmbH überprüft. Wenn ich nach „IKS GmbH“ suche, erwarte ich, dass die Website der IKS auf dem ersten Platz erscheint. Ich benutze dazu Google allerdings nicht direkt, sondern stelle meine Suchanfrage an die alternative Suchmaschine startpage.com. Sie liefert ebenfalls Google-Suchergebnisse, besitzt aber besser strukturierten HTML-Code, mit dem sich leichter arbeiten lässt.

Installation & Konfiguration

Richten Sie Ihr System zunächst wie folgt ein:

  1. Legen Sie in Visual Studio ein neues Projekt vom Typ Konsolenanwendung an.
  2. Installieren Sie SelWD über NuGet3). Dazu führen Sie folgende Befehle in der Package Manager Konsole4) aus:
    Install-Package Selenium.WebDriver
    Install-Package Selenium.Support
  3. Laden Sie sich für jeden Browser, den Sie automatisieren wollen, den entsprechenden Treiber aus dem Download-Bereich der Selenium-Website5) herunter. Für Firefox wird kein separater Treiber benötigt. Legen Sie alle Browser-Treiber in ein gemeinsames Verzeichnis, z.B. C:\Selenium\Treiber\.
  4. Stellen Sie sicher, dass die Treiber vom Betriebssystem gefunden werden, indem Sie den Pfad des Verzeichnisses zur Windows-Umgebungsvariablen path hinzufügen.

Anlegen von Page Objects

Nun modellieren Sie die zu automatisierenden Webseiten. Jede Webseite, mit der Sie interagieren wollen, bekommt eine eigene Klasse, die dem Page-Object-Entwurfsmuster6) folgt. Hierbei werden Felder der Klasse über ein FindsBy-Attribut deklarativ an DOM-Elemente7) der Webseite gebunden. Dies geschieht über Selektoren, die in Tabelle 1 zusammengefasst sind.

Tabelle 1: Selektoren für DOM-Elemente

Selektor Auswahl des DOM-Elements anhand…
ClassName des Class-Attributs
CssSelector der Style-Eigenschaften
Custom selbst definierter Eigenschaften
Id des ID-Attributs
LinkText eines Hyperlink-Texts
Name des Name-Attributs
PartialLinkText eines Fragments eines Hyperlink-Texts
TagName des Tag-Namens
XPath eines XPath-Filters

In den meisten Fällen reichen die vorgegebenen Selektoren aus, um alle DOM-Elemente eindeutig zu identifizieren. Die erste Wahl ist immer der ID-Selektor. Besitzen einige Elemente allerdings kein ID-Attribut oder ist der Wert des ID-Attributs nicht deterministisch (z.B. weil er automatisch generiert wird), sind der CSS- und der XPath-Selektor leistungsstarke Alternativen. Dabei sollten Sie den CSS-Selektor bevorzugen, da er schneller arbeitet.

Außerdem erhalten die Klassen Hilfsmethoden, welche die Arbeit mit der Webseite erleichtern. So macht es Sinn, dem Page Object für eine Seite mit Suchfunktion eine Search(string text)-Methode zu spendieren, die dafür sorgt, dass der Suchbegriff in das richtige Formularfeld eingetragen und anschließend der Such-Button geklickt wird.

Der Titel und die URL der Seite werden in entsprechenden Eigenschaften der Klasse abgelegt. Diese Werte werden bei der Ausführung benutzt, um zur Seite zu navigieren und um testen zu können, ob die richtige Seite geladen wurde.

Listing 1 zeigt die Page-Object-Klasse für die Startseite (Homepage) von startpage.com, Listing 2 jene für die Suchergebnisseite (SearchResultsPage).

Listing 1: Die Klasse für das Page Object der Startseite

Listing 2: Die Klasse für das Page Object der Suchergebnisseite:

Testen des Google-Rankings

Die eigentliche Automation erfolgt in der Main-Methode der Anwendung und ist in Listing 3 dargestellt. Zunächst wird ein Browser-Treiber instanziert und mit einem Timeout versehen. Anschließend wird das Page Object der Startseite erstellt und initialisiert, wodurch die Bindung der Felder stattfindet. Nun navigiert der Browser zur Webseite. Wenn diese geladen ist, erfolgt ein Test auf den korrekten Seitentitel. Anschließend wird die Suche ausgeführt. Sobald die Ergebnisseite zurückgeliefert wird, wird auch deren Page Object initialisiert und auf den korrekten Titel geprüft. Zuletzt erfolgt der Test auf das richtige Suchergebnis (es wird geprüft, ob der erste Treffer die URL www.iks-gmbh.com enthält).

Der gesamte Vorgang wird mit drei verschiedenen Browsern durchgeführt und das Ergebnis im Konsolenfenster ausgegeben (Bild 1).

Listing 3: Die Testklasse

Bild 1: Ausgabe auf der Konsole – die Tests waren erfolgreich. Die Meldungen über dem Testresultat stammen von den beiden Browser-Treibern.

Medlung Testresultat_Ausgabe Konsole
Bild 1

Screenshots

Es kann sinnvoll sein, während des laufenden Tests Screenshots des Browsers anzufertigen, etwa wenn ein Testfall einer Webanwendung fehlschlägt, oder einfach zu Dokumentationszwecken. Hierfür bringt SelWD eigens eine GetScreenshot-Methode mit, die Sie wie folgt anwenden:

Setzen Sie dabei in der SaveAsFile-Methode für path den Zielpfad inkl. Dateinamen ein und wählen Sie eins der Bildformate aus, die System.Drawing.Imaging.ImageFormat zur Verfügung stellt.

Eigene Selektoren

Sollten die vorhandenen Selektoren für die eigenen Zwecke nicht ausreichen, können Sie weitere Selektoren erstellen. Hierzu leiten Sie eine Klasse von der OpenQA.Selenium.By-Klasse ab und implementieren die Methoden FindElementMethod und FindElementsMethod. In Listing 4 sehen Sie beispielhaft eine Selektoren-Klasse, die aus allen DOM-Elementen mit einem vorgegebenen Class-Attribut ein zufälliges Element auswählt und zurückgibt.

Listing 4: Ein selbst erstellter Selektor

Die deklarative Bindung in der Page-Object-Klasse sieht dann wie folgt aus:

Dabei ersetzen Sie <ClassName> mit dem Wert des gewünschten Class-Attributs.

 

In Teil 2 dieses Artikels zeige ich, wie Sie mit Hilfe der Erweiterung SeleniumFormExtensions ein professionelles Projekt zum wiederholten Testen von Web-Formularen einrichten.

Links   [ + ]

1. http://www.seleniumhq.org/projects/webdriver/
2. http://www.dotnetpro.de/articles/articlearchive1784.aspx
3. https://www.nuget.org/
4. https://docs.nuget.org/consume/package-manager-console
5. http://www.seleniumhq.org/download/
6. https://code.google.com/p/selenium/wiki/PageObjects
7. https://de.wikipedia.org/wiki/Document_Object_Model

Schreibe einen Kommentar

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