Benutzerschnittstellenkarten

Eine große Ebene bei der Arbeit mit UI-Tests sind Desktop-Anwendungen für Windows. In verschiedenen Artikeln wird dem Leser beim Schreiben von Benutzeroberflächenzuordnungen (PageObjects) angezeigt, wie er Locators mithilfe von UISpy manuell schreibt.

Vor fünf Jahren wurde die Anzahl solcher Elemente in meinen Tests zu groß, die Kontrollen wurden komplizierter und die Bibliotheken für UI-Tests begannen wie Pilze zu wachsen.

Es wurde beschlossen, die Routine, den erforderlichen XPath zu finden, in Freude umzuwandeln.

Zuerst habe ich Visual Studio UIMap Editor verwendet: Je komplizierter die Anwendungen, desto weniger passte es mir in Bezug auf Geschwindigkeit und Locator-Substitution. Ich werde die Gründe in einem separaten Artikel über UIAutomation und seine Wrapper (TestStack.White, Cuite, Microsoft UITest usw.) beschreiben.

Also die Herausforderung


Erstellen Sie einen einfachen PageObject-Editor. Hilfsprogramme: UIAVerify.

Allgemeine Grundsätze


  • Jedes Steuerelement des Desktops verfügt über Sucheigenschaften und kann untergeordnete Elemente enthalten
  • Steuerelemente sind in Elemente (Element) gruppiert, Elemente sind in Namespaces (Assemblies) gruppiert
  • Verkapselung, Vererbung, Polymorphismus
  • Die Fähigkeit, fertige Karten zu verwenden. Ich habe zum Beispiel fertige Karten und Erweiterungen für DevExpress, AvalonDock, OpenFileDialog usw. Ich übertrage sie zwischen Projekten

Was ist passiert?


Verwenden des Additionsbeispiels in einem Windows 10-Rechner:

  1. Ich erstelle im Karteneditor eine Karte für das Fenster "Rechner". Mit einem Klick übertrage ich alle Fensterobjekte und entferne den Überschuss. Locators werden automatisch angebracht. Sie können Elemente manuell hinzufügen (z. B. für Selen), der Flug der Fantasie ist unbegrenzt
  2. Ich schaue mir die generierten Elementnamen an. Wenn sie mir nicht gefallen, benenne ich sie manuell um
  3. Ich speichere die Map für den UIAutomation-Wrapper (Normal XML => C # -Konverter. Jeder Wrapper kann verwendet werden, Selen, MS UITest, TestStack.White)

Zeit für alles: ungefähr drei Minuten

Rechts ist ein Analogon des UIAVerify-Desktop-Baums zu sehen. Links: Karte

Bild

Ergebnis


4 Dateien werden unter Versionskontrolle gesendet:

Karte in XML


  
    
      
        
          Калькулятор 
          
            Close
          
...



Gebildete Wrapper-Karte UIAutomation
namespace Calc
{
	public partial class UIКалькуляторWindow : UIWindow
	{
		public UIКалькуляторWindow(UIControl control) { Wrap(control); }
		public UIКалькуляторWindow() {  }
		public static UIКалькуляторWindow Instance 
		{ 
			get { return Desktop.Instance.Get(XPath); }
		}
		public static By XPath { get { return By.Xpath("Name=Калькулятор"); } }
		/// 
		/// Button "plusButton"
		/// 
		public UIButton UIПлюсButton
		{
		 	get { return Get(By.Xpath(@"AutomationId=plusButton")); }
		}
...



MapExt.cs und verschiedene Erweiterungen
namespace Calc
{
	public static class UIКалькуляторWindowExt
	{ 
        public static int Result(this UIКалькуляторWindow  window)
        {
            var textValue = window.UIResultText.Text
                .Replace("На экране показано", "")
                .Replace(" ", "");
            return int.Parse(textValue);
        }
	}
}


CalculationTests.cs Test
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Calc;
using System.Diagnostics;
using System;
namespace CalcTests
{
    [TestClass]
    public class CalculationTests : IDisposable
    {
        public CalculationTests()
        {
            _process = Process.Start("calc.exe");
            _calc = UIКалькуляторWindow.Instance;
        }
        [TestMethod]
        public void Sum()
        {
            _calc.UIОдинButton.Click();
            _calc.UIПлюсButton.Click();
            _calc.UIПятьButton.Click();
            _calc.UIРавноButton.Click();
            Assert.AreEqual(6, _calc.Result(), "Не совпадает результат");
        }
        public UIКалькуляторWindow _calc { get; set; }
        Process _process;
        public void Dispose()
        {
            _calc.Close();
        }
    }
}


Ich denke, es gibt bereits viele alternative Lösungen, Links und erfolgreichere Beispiele in den Kommentaren.

Vielen Dank für Ihre Aufmerksamkeit!

Jetzt auch beliebt: