[Из песочницы] Карты пользовательского интерфейса

Большой пласт работы с тестами UI составляют Desktop приложения под Windows. В разных статьях во время написания карт пользовательского интерфейса (PageObject«s) читателю показывают написание локаторов вручную с помощью UISpy.

Пять лет назад количество таких элементов в моих тестах стало слишком велико, контролы стали сложнее, а библиотеки для UI тестирования начали расти как грибы.

Рутину по поиску необходимого XPath было решено преобразовать в радость.

Вначале использовал Visual Studio UIMap Editor: чем сложнее были приложения, тем меньше он меня не устраивал в плане скорости и подстановки локаторов. Причины опишу в отдельной статье по UIAutomation и его обертках (TestStack.White, Cuite, Microsoft UITest и т.д.).

Итак, задача


Сделать простой редактор PageObject«s. Вспомогательные инструменты: UIAVerify.

Общие принципы


  • каждый контрол (Control) рабочего стола обладает поисковыми свойствами и может содержать дочерние элементы
  • контролы группируются в элементы (Element), элементы группируются в пространства имен (Assemblies)
  • Инкапсуляция, наследование, полиморфизм
  • Возможность использовать уже готовые карты. Например, у меня есть уже готовые карты и расширения для DevExpress, AvalonDock, OpenFileDialog и т.д. Я их переношу между проектами

Что получилось


На примере сложения в калькуляторе Windows 10:
  1. Составляю карту для окна «Калькулятор», для этого в редакторе карт из дерева рабочего стола переношу все объекты окна, и убираю лишнее. Можно добавлять элементы и вручную (например, для Selenium), полет фантазии безграничен
  2. Смотрю на сгенерированные названия элементов. Если они мне не нравятся, переименовываю вручную
  3. Сохраняю карту для обертки UIAutomation (Обычный конвертер XML => C#. Обертка может использоваться любая, Selenium, MS UITest, TestStack.White)

Время на все: минуты три

Справа — аналог дерева рабочего стола UIAVerify. Слева: карта

image

Результат


Под версионный контроль отправляется 4 файла:
Карта в XML


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



Сформированная карта для обертки 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 и всевозможные расширения
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
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();
        }
    }
}


Думаю, альтернативных решений уже много, ссылки и более удачные примеры кидайте в комментариях.

Спасибо за внимание!

Комментарии (0)

© Habrahabr.ru