Как вы знаете, 2ГИС помогает найти самую разную актуальную информацию об организациях города. Она собирается из различных источников при помощи специализированных продуктов, с которыми работают картографы 2ГИС, специалисты call-центра и отдела продаж. Эти продукты мы называем внутренними, и кроме сбора информации они также умеют её обрабатывать, фильтровать, объединять и выгружать в нужных форматах конечным приложениям 2ГИС.

Внутренние продукты разрабатывают отдельные проектные команды, в основном, на стеке технологий Microsoft. Для отрисовки графического интерфейса используется WPF или наследственный WinForms. Одни приложения построены на элементах управления из «коробки», другие используют, например, библиотеку AvalonDock. Так же встреч��ются приложения, разработанные на платформе Catel.

Такое разнообразие порождает проблемы автоматизации тестирования. Мы их успешно решили в рамках проекта Cruciatus — собственного фреймворка, который позволяет упростить разработку тестов для проверки пользовательского интерфейса.

Несмотря на название, Cruciatus вполне легален и за его использование вас не упекут в Азкабан. В этой статье мы расскажем о Сruciatus подробнее.


Выбираем волшебную палочку инструмент




Основной задачей автоматизации функционального тестирования является воспроизведение шагов тест-кейса. То есть, автотест должен повторять те же действия и проверки, что делает тестировщик при ручном тестировании. Эти задачи решаются с помощью специализированных инструментов, позволяющих эмулировать пользовательские действия.

Для desktop-приложений под Windows мы рассмотрели несколько самых популярных инструментов: Visual Studio CodedUI, Ranorex, White и выбрали наиболее подходящее для тестирования наших внутренних продуктов. Ранее на Хабре мы писали, какими принципами руководствовались при выборе.

Напомним, что мы сделали свой выбор в пользу CodedUI. Он не выигрывал по всем пунктам, но имел весомое преимущество в том, что работа с ним происходит непосредственно в Visual Studio, которая является основной средой разработки для разработчиков и тестировщиков.

Зачем нам бумеранг, если у нас есть грабли


Рекордер является отличительной особенностью CodedUI, так как позволяет создавать тесты даже без навыков программирования.

По нашему опыту сценарий CodedUI-теста легко воспроизводится для приложений типа «калькулятор». Однако, если интерфейс содержит множество нестандартных или динамических контролов, то возникают ошибки при их определении. Кроме того проблематично вносить изменения в код теста, так как сгенерированный рекордером код очень массивный и запутанный.

Так как к тому времени мы уже имели представление о работе CodedUI, мы отложили рекордер в сторону и стали писать код тестов самостоятельно, используя классы, предоставляемые пространством имён Microsoft.VisualStudio.TestTools.UITesting (их использует и сам CodedUI при генерации кода). Это позволило нам получать тесты с понятным, компактным кодом, но не избавило от проблем поиска элементов и их доступности. Что заблокировало дальнейшее продвижение автоматизации тестирования пользовательского интерфейса.

Представить себе CodedUI в работе можно как инфраструктуру, состоящую из классов фреймворка, тестируемого приложения и самих тестов. Подробнее компоненты изображены на схеме:



Нас полностью устраивала работа компоненты, эмулирующей действия мыши и клавиатуры: классы Mouse & Keyboard прекрасно с этим справляются. В отличии от классов, которые отвечают за доступ к приложению и являются крайними за упомянутую проблему поиска и доступности элементов. В связи с этим хочется их вырезать и заменить!

Своя обертка ближе к телу


Для того, чтобы элемент приложения мог о себе что-то сказать, он должен реализовывать технологию Microsoft UI Automation. В таком случае он позволяет программно обращаться к нему, используя библиотеки из пространства имен System.Windows.Automation. Они применяются, например, в уже упомянутом на диаграмме классе WpfTestProvider. Мы попробовали напрямую использовать библиотеку Automation и получили отличный результат, избавившись от проблем поиска элемента и их доступности.

Однако, предоставляемый функционал библиотеки Automation не даёт возможности выполнять обычные действия (найти элемент, кликнуть по нему, получить его текст и т.п.) за один метод. Поэтому пользоваться библиотекой Automation тестировщику в лоб было бы неправильно.

Так, следующим этапом развития нашего проекта стала разработка обёртки над UI Automation, которая заменит неудовлетворяющие нас классы,



аккумулирует удовлетворяющие,



а для тестировщика будет универсальным и удобным в использовании инструментом.

Магическое преображение


Обёртка «выросла» и сейчас это инструмент для разработки функциональных тестов с кодовым названием Cruciatus. Приведем пример разработки тестового проекта с его использованием.

Для работы необходимо построить карту элементов интерфейса. В ней указать тип и уникальный идентификатор каждого элемента, участвующего в тестировании. Важно, что тип выбирается из доступных в Cruciatus. Использование карты позволит легко поддерживать тесты при изменениях в интерфейсе, а изобразить её можно в виде дерева:



Используя карту, пишем тесты. Ниже пример теста, проверяющего, что при установленной галочке (у элемента SwitchCheckBox) элемент ComboBox включен, и наоборот:

[CodedUITest]
public class Class1
{
    [TestMethod]
    public void CheckingSwitchCheckBox()
    {
        var app = new Application<MainWindow>("Application.exe", "WindowUid");
        app.Start();
        app.MainWindow.TabItem2.SwitchCheckBox.Uncheck(); // отключает ComboBox
        Assert.IsFalse(app.MainWindow.TabItem2.ComboBox.IsEnabled);
        app.MainWindow.TabItem2.SwitchCheckBox.Check(); // включает ComboBox
        Assert.IsTrue(app.MainWindow.TabItem2.ComboBox.IsEnabled);
        app.Close();
    }
}


Автоматизируй и реквестируй


Фреймворк доступен на GitHub, документация прилагается. Продукт полностью готов к использованию. Изначально Cruciatus разрабатывался для личного использования, но сейчас он вырос в самостоятельный продукт, который мы активно развиваем.

Скачивайте, форкайте, реквестируйте фичи. Мы рады вашим пожеланиям и предложениям.