Ranorex: Pixelfarbe ermitteln

Bei manchen Testfällen ist es notwendig die aktuelle Hintergrundfarbe eines Oberflächenelements zu ermitteln.
WinForms / VB6 / usw. Oberflächen stellen diesen Wert nicht als Eigenschaft bereit, aus diesem Grund muss dieser Wert über einen anderen Weg abgefragt werden.

Der einfachste Weg ist es, ein Screenshot des Elements zu erzeugen und diesen dann mit der GetPixel Methode abfragen.
Ranorex stellt dazu z.B. die Methode

Report.Screenshot(element);

bereit.
Bei dieser Methode wird allerdings das Bild lokal gespeichert, dieses Vorgehen ist etwas fehleranfällig und vor allem unnötig.
Nach einer längerer Suche, bin ich auf die Methode Imaging.CaptureCompressedImage() gestoßen, diese liefert ein Bitmap Objekt zur Laufzeit zurück, ohne dass Bilder lokal gespeichert werden müssen.
Als Parameter kann ein Element vom Typ Ranorex Adapter oder Ranorex Element übergeben werden.

Hier ist eine Beispiels-Methode, mit der vom übergebenen Control die Hintergrundfarben ermittelt werden können.
Natürlich können auch die Pixel verändert bzw. parametrisiert werden.

public static string Color(Adapter ui_control)
{
   Bitmap bmp = Imaging.CaptureCompressedImage(ui_control);
   Color cElementColor = bmp.GetPixel(2, 2);
   return cElementColor.Name;
}

Lesetipp: Automated Software Testing Magazine – obsolete

Leider ist die Kultur der Testautomatisierung in Deutschland (noch?) nicht so sehr verbereitet wie in anderen Ländern. So gibt es, neben gut ausgebauten und „lebendigen“ Foren, auch Magazine, die sich speziell dem Thema Testautomatisierung widmen.
Unter dem folgenden Link ist ein gutes „Testautomatisierungs – Magazin“, der Webseite automatedtestinginstitute.com, zu finden:
Automated Software Testing Magazige – PDF Datei(Link entfernt)
Themen u.a. sind:

  • So easy even a child can use it – Is Your Test Automation Architecture Usable?
  • Cells, Selenium, XPath and Labels – Using Labels to identify Dynamic Objects
  • Test Automation Experiences
  • Selenium vs. Watir… And the Winner is Webdriver

Waldemar – Nachtrag (11/2015):
Leider wurde die Zielseite entfernt und die PDF Datei ist nicht mehr auffindbar. Ich habe den dazugehörigen Link entfernt und den Artikel als obsolete gekennzeichnet.
Danke an Michael Grabowski, der mich darauf aufmerksam gemacht hat, dass der Link nicht mehr zu der gewünschten Seite führt.

Microsoft Test Manager: TimeOut für die Testdurchführung ausschalten

Manchmal ist es notwendig, dass einzelne Testfälle länger als 30 Minuten laufen. Die Durchführungszeit wird aber, per default, von MTM auf 30 Minuten festgelegt

Default TimeOut der Testdurchführung aus Microsoft Testmanager, wird in den Test Settings festgelegt.

Mit folgenden Schritten, kann die TimeOut Zeit angepasst werden:

  • MTM starten
  • Oben den Bereich von „Testing Center“ auf „Lab Center“ umschalten
  • im „Lab Center“ den Reiter „Test Settings Manager“ auswählen
  • Im „Settings Manager“ eine neue Test Setting anlegen oder eine bestehende öffnen
  • Im Bereich „Steps“, Oberknoten „Advanced“ auswählen, dann den Unterknoten „Timeouts“
  • „Set Mark an individual test as failed if its execution time exceeds: 30“ deaktivieren
  • Speichern
  • Fertig!
,

Ranorex: Problem beim dynamischen Zugriff auf eine Webtabelle

Bei der Automatisierung einer Web-Applikation mit Ranorex, bin ich vor kurzem auf folgendes Problem gestoßen:

Die Tabelle besteht aus ca 10 Zeilen und 2 Header Zeilen.
Um einen flexibelen Zugriff zu ermöglichen, setze ich mir den Ranorex Pfad (Ranorex XPath) selbst zusammen.
Der Zugriff sollte in diesem Fall über „Zeilen / Spalten – Nummer“ aus Sicht der Tabellenebene stattfinden.
Das Element setzte sich so zusammen:

element = tablepath + "//tr[" + row + "]/td[" + column + "]";

Alles soweit in Ordnung. Variablen row = 1 und column = 3 gesetzt, Ranorex Pfad wird richtig gefüllt und die td Zelle lässt sich, mit dem generierten Pfad, durch Ranorex Spy finden.

Der Versuch dieses Element per Methode TryFindSingle() während der Testdurchführung zu finden, ist aber gescheitert.

Host.Local.TryFindSingle(element, TimeSpan.FromSeconds(time), out tdElement))

Nach einer kurzen Try/Fail-Phase, habe ich versucht die Zelle über den Ranorex Typ „WebElement“ zu finden.
Dazu wird einfach das letzte Element (td) durch ein * ersetzt und mit TryFindSingle nach Typ „WebElement“ gesucht.
Dadurch kann jedes Element identifiziert werden, das den Suchkriterien entspricht. Als Result kam Tag TH (Head Element) raus.
Also row = 3 (von der Anzahl höher als das letzte TH Element) gesetzt, schon hat der Zugriff über TryFindSingle() funktioniert.
Reicht als Lösung des Problems natürlich nicht aus, die ersten beiden Zeilen sollen schließlich auch angesprochen werden können. Da kommt das Element tbody ins Spiel.
Durch tbody kann hier sichergestellt werden, dass der Zugriff wirklich auf den „Content“ der Tabelle stattfindet. Die Identifikation ist so eindeutig.
Also den Ranorex XPath Ausdruck angepasst, schon funktioniert die TryFindSingle() Suche fehlerfrei:

element = tablepath + "//tbody/tr[" + row + "]/td[" + column + "]";

Man könnte annehmen, dass //tr[1]/td[1] Kombination ausreichend wäre, dem war hier leider nicht so.
Warum dieser Pfad in Ranorex Spy richtig erkannt wird und per TryFindSingle() nicht, kann ich leider nicht sagen, aber durch diesen kleinen „Workaround“ kann an dieser Stelle weitergearbeitet werden.

Im Ranorex Forum gibt es ein ähnliches Problem: Beitrag im Ranorex Forum
Die dort vorgeschlagenen Lösungen, haben bei diesem Problem aber keine Besserung gebracht.

, , , ,

ClassCleanup() Verhalten

Um aus Microsoft Test Manager automatisierte Testfälle (Unit Tests, Coded UI Tests, Ranorex, Selenium usw.) ansprechen zu können, müssen diese in Testmethoden „verpackt“ werden. Weiterlesen

Tree (Baum) expandieren mit Tastenkombination

Es kann vorkommen, dass mit einigen Werkzeugen das Expandieren des kompletten Tree’s nicht oder nur fehlerhaft funktioniert. Um nicht jedes Element auf „expandierbar“ prüfen zu müssen, kann die Taste * vom Numblock auf den Oberknoten angewandt werden.

Also ein beliebiges Treeelement auswählen und * klicken. Probiert es einfach mal im Explorer aus, aber vorsicht, wählt dabei eine nicht zu tief verschachtelte Struktur, da sonst der Explorer sich aufhängen kann.

Es ist von Werkzeug zu Werkzeug unterschiedlich wie dieser Befehl an die Oberfläche übergeben werden kann. In VisualStudio kann der Befehl SendKeys() mit Parameter {MULTIPLY} auf einem Oberknoten verwendet werden.

QuickTest Pro: Zeichen einer Stelle ermitteln

Um in QuickTest Professional ein Zeichen auf einer bestimmten Position im String zu ermitteln, kann die Funktion Mid() verwendet werden.

Hier ein kleines Beispiel, wie jedes Zeichen eines Strings nacheinander ausgegeben werden kann:

For i=1 to Len("Tomate")
  msgbox Mid("Tomate", i, 1)
Next

QuickTest Pro: Hintergrundfarbe ermitteln

Soll bei einer Automatisierung die Hintergrundfarbe ermittelt werden, gestaltet es sich in QuickTest recht schwierig, wenn es sich nicht um Webseiten oder WPF handelt, da die Hintergrundfarbe bei Win Oberfllächen keine abfragbare Eigenschaft von GUI Objekten ist.

Ein Lösungsansatz ist es, die Hintergrundfarbe über die WinAPI Funktion GetPixel (Beschreibung Microsoft) zu ermitteln. Diese Funktion liefert einen COLORREF Wert zurück. Dieser muss dann nur noch umgerechnet werden. In dem unteren Beispiel verwende ich dazu eine selbstgeschriebene Funktion. Es gibt aber auch einen saubereren Weg an die RGB Werte zu kommen (WinApi Funktionen: GetRValue, GetGValue und GetBValue -> siehe hier)

In diesem Beispiel wird bei dem Windows „Taschenrechner“ (calc, unter Windows 7) die Farbe des Buttons mit und ohne Hover Effekt geprüft.
Vor dem MouseMove hat der Button eine blaue, dannach eine orangene Farbe.

Dim Hintergrundfarbe1, Hintergrundfarbe2
Set Hintergrundfarbe1 = GetRGBValues(GetBackGroundColor(Window("Rechner").WinButton("Button")))

msgbox "Blau: " & Hintergrundfarbe1.Blue & " - Rot: " & Hintergrundfarbe1.Red & " - Grün: " & Hintergrundfarbe1.Green

Window("Rechner").WinButton("Button").MouseMove 1,1

Set Hintergrundfarbe2 = GetRGBValues(GetBackGroundColor(Window("Rechner").WinButton("Button")))
msgbox "Blau: " & Hintergrundfarbe2.Blue & " - Rot: " & Hintergrundfarbe2.Red & " - Grün " & Hintergrundfarbe2.Green

'Funktion zum Umrechnen der Werte in RGB
Function GetRGBValues(lngRGB)
  Dim Farbe
  'Neues Objekt definieren
  Set Farbe = new Farbe
  Farbe.Red = lngRGBAND &HFF&
  Farbe.Green = (lngRGB AND &H0000FF00&)/256
  Farbe.Blue = (lngRGB and &H00FF0000&)/65536

  set GetRGBValues = Farbe
End Function

Function GetBackGroundColor(dlgObject)
  Extern.Declare micLong, "GetPixel", "gdi32", "GetPixel", micLong, micLong, micLong
  Extern.Declare micLong, "ReleaseDC", "user32", "ReleaseDC", micLong, micLong
  Extern.Declare micLong, "GetDC", "user32", "GetDC", micLong
  Extern.Declare micLong, "SetForegroundWindow", "user32", "SetForegroundWindow", micLong

  Dim hDCSource, hWndSource, backColor

  hWndSource = dlgObject.GetROProperty("hwnd")
  Extern.SetForegroundWindow hWndSource
  hDCSource = CLng(Extern.GetDC(hWndSource))
  backColor = CLng(Extern.GetPixel(hDCSource, CLng(1), CLng(1)))

  Extern.ReleaseDC hWndSource, hDCSource
  GetBackGroundColor = backColor
End Function

Class Farbe
  Dim Red
  Dim Green
  Dim Blue
End Class

XML File mit QuickTest Pro lesen

XML ist in QuickTest Pro sehr nützlich. Die Hilfe von QuickTest dazu ist aber verbesserungswürdig. Hier ist eine Beispielfunktion, mit der alle XML Knoten rekursiv geöffnet werden.

Set xml = XMLUtil.CreateXML()
xml.LoadFile "C:\test.xml"
Set root = xml.GetRootElement()

'initialer Aufruf der Funktion
lese_xml root

Function lese_xml (element)
  set children = element.ChildElements()
  For i=1 to children.Count
    set child = children.Item(i)
    ' Hier können die unterschiedlichen Eigenschaften des Knotens abgefragt werden
    'z.B. Ausgabe des Namens
    print child.ElementName
    lese_xml child
  Next
End Function