Руководство по улучшению качества

advertisement
ВВЕДЕНИЕ ...............................................................................................................................................................4
ВЫПУСКИ ЭТОГО ДОКУМЕНТА ..............................................................................................................................4
ПРЕДЛАГАЕМЫЙ ПЛАН ЧТЕНИЯ ...........................................................................................................................5
Приступая к работе ................................................................................................................................................6
ВВЕДЕНИЕ В ТЕСТИРОВАНИЕ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ.....................................................................6
КОМПЛЕКС МЕРОПРИЯТИЙ ПО ТЕСТИРОВАНИЮ .......................................................................................7
ВВЕДЕНИЕ В ПРОГРАММНЫЙ КОМПЛЕКС WPF...........................................................................................8

Object ............................................................................................................................................................11

DispatcherObject ...........................................................................................................................................11

DependencyObject (DO) ................................................................................................................................11

Freezable .......................................................................................................................................................11

Visual .............................................................................................................................................................11

UIElement ......................................................................................................................................................11

ContentElement.............................................................................................................................................11

FrameworkElement .......................................................................................................................................12

Control ...........................................................................................................................................................12

Shape .............................................................................................................................................................12

Panel ..............................................................................................................................................................12

ContentControl ..............................................................................................................................................12

ItemsControl ..................................................................................................................................................12

Best Practices for Designers ..........................................................................................................................13

Best Practices for Developers ........................................................................................................................13
МЕТОДОЛОГИЯ, ПЛАНИРОВАНИЕ И СТРАТЕГИИ ТЕСТИРОВАНИЯ ...........................................................13
АВТОМАТИЗИРОВАННОЕ ТЕСТИРОВАНИЕ .....................................................................................................15
УПРАВЛЯЕМОЕ ДАННЫМИ ТЕСТИРОВАНИЕ ..............................................................................................15
ТЕСТИРОВАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА .............................................................................21

Общие сведения об эффектах анимации ..................................................................................................41

Коллекция примеров анимации ................................................................................................................41

Общие сведения об анимации и системе управления временем ..........................................................41

Практическое руководство. Анимирование свойства с помощью раскадровки (класс Storyboard)....41
ТЕСТИРОВАНИЕ API И МОДУЛЬНОЕ ТЕСТИРОВАНИЕ ................................................................................41
ТЕСТИРОВАНИЕ ПРОИЗВОДИТЕЛЬНОСТИ И МАСШТАБИРУЕМОСТИ ......................................................42
ТЕСТИРОВАНИЕ БЕЗОПАСНОСТИ ................................................................................................................42
ТЕСТИРОВАНИЕ ГЛОБАЛИЗАЦИИ И ЛОКАЛИЗАЦИИ .................................................................................44

Globalization of the Test ...............................................................................................................................45

Localizability Testing ......................................................................................................................................45

Localization Testing .......................................................................................................................................45
ТЕСТИРОВАНИЕ СПЕЦИАЛЬНЫХ ВОЗМОЖНОСТЕЙ ..............................................................56
Практическое руководство. Использование разделов системных параметров ............................................58
Практическое руководство. Как использовать SystemParameters ..................................................................58
Практическое руководство. Использование SystemFonts ................................................................................58
Практическое руководство. Закраска области с помощью системной кисти ................................................58
Практическое руководство. Использование системных цветов в градиенте ................................................58

MSDN Accessibility Developer Center ...........................................................................................................62

Модель автоматизации пользовательского интерфейса и Microsoft Active Accessibility .....................62

Использование автоматизации пользовательского интерфейса для автоматизированного
тестирования ........................................................................................................................................................63
o
Windows Automation API 3.0 Overview .......................................................................................................63
ТЕСТИРОВАНИЕ СТАБИЛЬНОСТИ И НАГРУЗОЧНОЕ ТЕСТИРОВАНИЕ ...........................63
ПОЛЬЗОВАТЕЛЬСКИЕ ЭЛЕМЕНТЫ УПРАВЛЕНИЯ И ТЕСТИРОВАНИЕ
РАСШИРЯЕМОСТИ ................................................................................................................................71

Общие сведения о разработке элементов управления ...........................................................................75

Рекомендации по разработке элементов управления с возможностью использования стилей ........75

Настройка элементов управления WPF при помощи шаблонов .............................................................75
ТЕСТИРОВАНИЕ ИНТЕГРАЦИИ И СЦЕНАРИЕВ .........................................................................77

http://www.exforsys.com/tutorials/testing/integration-testing-whywhathow.html ..................................80

http://www.softwaretestingstuff.com/2008/12/integration-testing-four-step-procedure.html ................80

http://www.softwaretestingstuff.com/2008/12/how-to-do-integration-testing-writing.html ...................80
ТЕСТИРОВАНИЕ ВРУЧНУЮ, ЗАПИСЬ И ВОСПРОИЗВЕДЕНИЕ ТЕСТОВ ...............................82
ПРЕИМУЩЕСТВА И НЕДОСТАТКИ АВТОМАТИЗАЦИИ ТЕСТА ...........................................82
ПРИНЦИПЫ НАПИСАНИЯ ХОРОШЕГО РУЧНОГО ТЕСТА .....................................................82
ЗАПИСЬ РУЧНОГО ТЕСТА ..................................................................................................................84
СРЕДСТВА .....................................................................................................................................................86
TESTAPI ......................................................................................................................................................86
СРЕДСТВА АВТОМАТИЗАЦИИ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА ...........................89
СРЕДСТВА ОТЛАДКИ ............................................................................................................................90
СРЕДСТВА ПРОФИЛИРОВАНИЯ ПРОИЗВОДИТЕЛЬНОСТИ ...................................................90

Средства профилирования производительности для WPF......................................................................90
СРЕДСТВА РАЗРАБОТКИ И ПРОЕКТИРОВАНИЯ ПРИЛОЖЕНИЙ WPF ..............................91
СРЕДСТВА РЕДАКТИРОВАНИЯ XAML И НАДСТРОЙКИ VISUAL STUDIO .........................91
ДРУГИЕ ПОЛЕЗНЫЕ СРЕДСТВА ДЛЯ РАЗРАБОТЧИКОВ И ТЕСТЕРОВ WPF ....................92
РЕСУРСЫ .......................................................................................................................................................92
БЛАГОДАРНОСТИ ......................................................................................................................................92
ПРИЛОЖЕНИЯ.............................................................................................................................................93
ПРИЛОЖЕНИЕ 1. СОЗДАНИЕ НАБОРА ДЛЯ ТЕСТИРОВАНИЯ ПРИЛОЖЕНИЙ WPF С
ПОМОЩЬЮ VISUAL STUDIO TEAM SYSTEM ................................................................................94
ПРИЛОЖЕНИЕ 2. ПРИВЯЗКА ДАННЫХ И ОТЛАДКА В WPF....................................................98
ПРИЛОЖЕНИЕ 3. ВЗАИМОДЕЙСТВИЕ WPF ..................................................................................99

Общие сведения о взаимодействии WPF и Win32 ...................................................................................99

Руководство по созданию содержимого WPF, размещенного в приложении Win32...........................99

Учебник: создание приложения WPF, размещающего содержимое Win32 ..........................................99

Windows Forms и архитектура ввода взаимодействия WPF ....................................................................99

Сопоставление свойств Windows Forms и WPF .........................................................................................99

Элементы управления Windows Forms и эквивалентные элементы управления WPF .........................99

Разделы руководства по миграции и взаимодействию ...........................................................................99

WPF Interoperability FAQs ............................................................................................................................99
ПРИЛОЖЕНИЕ 4. НЕКОТОРЫЕ АСПЕКТЫ WPF-ПРИЛОЖЕНИЙ БРАУЗЕРА ....................99
Руководство по улучшению качества
приложении WPF
Вашему вниманию предлагается документ Руководство по улучшению качества приложений WPF v.0.5.
Из-за быстрого распространения платформы разработки WPF и по многочисленным просьбам
партнеров и заказчиков команда WPF в Microsoft с радостью представляет пятый предварительный
выпуск документа «Руководство по улучшению качества приложений WPF». Это руководство
планируется выпускать поэтапно, обновляя и уточняя его содержимое на основе присылаемых вами
отзывов и предложений. В текущем, пятом выпуске вы найдете обновленную схему для более удобного
чтения документа, позволяющую переходить сразу к интересующим разделам, тесты интеграции и
сценариев, обновленный раздел средств с обновленными ресурсами TestApi, приложение 1 о создании
набора для тестирования приложений WPF с помощью VSTS, NUnit или xUnit, а также приложение 4 о
некоторых аспектах WPF-приложений браузера.
Нам очень важно ваше мнение: вы можете оставить комментарии внизу статьи.
Последнее обновление: 28 апреля 2009 года.
ВВЕДЕНИЕ
В этом документе содержится обзор приложений и элементов управления платформы разработки
Windows Presentation Foundation (WPF). Он предназначен для разработчиков, инженеровтестировщиков и поставщиков, использующих технологии Microsoft WPF.
В документе рассматриваются следующие темы:

Базовое определение тестирования программного обеспечения.

Сведения о программном комплексе WPF.

Сведения о различных уровнях тестирования: от тестирования API, интеграции и до системного
тестирования.

Список доступных средств и ресурсов по теме.
В соответствующих случаях приводятся примеры кода. В каждой теме сначала рассматриваются
основные понятия и определения, затем приводятся рекомендации по разработке, методики
тестирования и — при необходимости — пример кода.
ВЫПУСКИ ЭТОГО ДОКУМЕНТА
Данный документ будет представлен в нескольких выпусках. Это третий выпуск. Разделы, не
включенные в настоящий документ, будут рассмотрены в будущих выпусках, как указано в тексте
документа.
Все вопросы и комментарии направляйте по адресу wpftbest@microsoft.com.
ПРЕДЛАГАЕМЫЙ ПЛАН ЧТЕНИЯ
Этот документ предназначен для различных сотрудников отдела проектирования ПО, от инженера по
контролю качества до разработчиков элементов управления. В следующей таблице приводится порядок
прочтения документа для различных должностей.
Должность
Роль
Создает и (или) выполняет
тесты вручную. Может
создавать
автоматизированные тесты
с помощью общих средств
тестирования (VisualTest и
др.) или сценариев
Предлагаемый план чтения
1. Введение в тестирование программного
обеспечения
2. Методология, планирование и
стратегии тестирования
3. Тестирование интеграции и сценариев
4. Тестирование вручную, запись и
воспроизведение тестов
5. Тестирование глобализации и
локализации
6. Тестирование специальных
возможностей
7. Другие полезные средства для
разработчиков и тестеров WPF
Разработчик
тестов
Создает автоматизированные
тесты и (или) средства
тестирования с помощью
неуправляемого (C++) или
управляемого кода (C#, Visual
Basic и др.)
1. Введение в тестирование программного
обеспечения (для разработчиков, не
имеющих опыта тестирования)
2. Введение в программный комплекс
WPF
3. Методология, планирование и
стратегии тестирования
4. Автоматизированное тестирование
5. Тестирование глобализации и
локализации
6. Тестирование стабильности и
нагрузочное тестирование
7. Тестирование специальных
возможностей
8. Приложение 1. Создание набора для
тестирования приложений WPF с
помощью VSTS, NUnit или xUnit
9. Средства (включая TestApi)
Разработчик
приложений
Создает приложения WPF
1. Введение в программный комплекс
WPF
2. Средства разработки и проектирования
приложений WPF
3. Средства отладки
4. Приложение 1. Создание набора для
тестирования приложений WPF с
помощью VSTS, NUnit или xUnit
5. Средства профилирования
производительности
6. Другие полезные средства для
Инженер по
контролю качества
или инженертестировщик
разработчиков и тестеров WPF
7. Приложение 3. Взаимодействие WPF
8. Приложение 4. Некоторые аспекты
WPF-приложений браузера
Разработчик
элементов
управления
Создает элементы
управления WPF и их
библиотеки
1. Введение в программный комплекс
WPF
2. Средства разработки и проектирования
приложений WPF
3. Средства отладки
4. Приложение 1. Создание набора для
тестирования приложений WPF с
помощью VSTS, NUnit или xUnit
5. Пользовательские элементы
управления и тестирование
расширяемости
6. Тестирование глобализации и
локализации
7. Тестирование специальных
возможностей
8. Другие полезные средства для
разработчиков и тестеров WPF
Приступая к работе
ВВЕДЕНИЕ В ТЕСТИРОВАНИЕ ПРОГРАММНОГО
ОБЕСПЕЧЕНИЯ
Существует множество определений тестирования программного обеспечения. Однако все они, по сути,
сводятся к одному: это контролируемое выполнение ПО для оценки программы или системы и
определения ее соответствия проектным требованиям (требованиям и спецификациям заказчика и др.).
В этом разделе описываются общие понятия тестирования, включая технологии, подходы, типы и
комплекс мероприятий по тестированию. Здесь также приводятся ссылки на дополнительные сведения
о тестировании ПО.
В зависимости от того, как в команде распределяются обязанности по тестированию и какой тип теста
выполняется (см. ниже), тестирование могут проводить инженеры-тестировщики, разработчики или
специалисты обеих категорий. Например, если в команде разработки заняты специально назначенные
инженеры-тестировщики, то модульное тестирование (см. ниже) выполняют разработчики.
Далее рассматривается ряд ключевых понятий тестирования ПО.
Цель
Цель тестирования ПО заключается в том, чтобы заранее предотвратить дефекты работы приложений и
улучшить их качество.
Технологии
Существуют следующие разновидности технологий тестирования:

Тестирование по принципу белого ящика. Это тестирование основано на знании реализации
приложения. Примерами такой технологии могут служить проверки кода и анализ покрытия
кода.

Тестирование по принципу черного ящика. Это тестирование основано только на данных,
полученных в ходе наблюдения за интерфейсом и поведением приложения, при этом о
реализации приложения ничего не известно.

Тестирование по принципу серого ящика. Это гибрид двух первых технологий: здесь
тестирование на основе наблюдения проводится с учетом некоторых знаний о реализации
приложения.
Подходы
При тестировании ПО применяются два различных подхода:

Ручные тесты. К ним обычно относятся тесты, которые наиболее эффективны при участии
человека: его зрительных, интеллектуальных и интуитивных способностей.

Автоматизированные тесты. Эти тесты можно написать и выполнить без вмешательства
пользователя. Они, как правило, характеризуются повторяемостью и могут выполняться
регулярно, постоянно снабжая разработчиков сведениями о функционировании ПО.
Типы
Обычно выделяют следующие уровни тестирования:

Модульное тестирование. С помощью тестирования по принципу белого ящика разработчики
могут выполнять модульное тестирование, проверяя надлежащее функционирование
определенных модулей кода. Модульное тестирование производится на базовом уровне: при
разработке модуля кода или реализации определенной функциональности.

Тестирование интеграции. Служит для проверки надлежащей координации двух и более
модулей. Тестирование интеграции помогает обнаружить дефекты взаимодействия между
различными модулями.

Функциональное тестирование. Служит для проверки соответствия системы функциональным
требованиям. Функциональное тестирование не охватывает внутренний код проекта. Вместо
этого проверяется, соответствует ли поведение системы ожидаемому.

Системное тестирование. Служит для оценки соответствия системы указанным требованиям,
таким как производительность, совместимость, безопасность, надежность, регрессия,
специальные возможности и др.

Приемочное тестирование. Проводится на системе до ее поставки, будь то от разработчиков к
инженерам-тестировщикам или от поставщика к заказчику (пользователю или клиенту). В
любом случае тестирование включает выполнение набора тестов на готовой системе для
проверки базовой функциональности.
КОМПЛЕКС МЕРОПРИЯТИЙ ПО ТЕСТИРОВАНИЮ
Проектирование тестов обычно регулируется теми же базовыми инженерными принципами, что и
проектирование ПО. Проектирование выполняется в несколько этапов — от разработки общей
стратегии до подробных процедур тестирования. В комплекс мероприятий по тестированию обычно
входят следующие:

разработка плана тестирования и спецификации тестирования (документации);

проектирование тестов (тестовых случаев);

выполнение тестов (вручную или автоматически);

запись и анализ результатов тестирования (ведение журнала и анализ сбоев);

определение проблем (изолирование ошибок и отчеты);

исправление проблем и повторение тестов по мере необходимости.
Обратите внимание, что протестировать продукт целиком и полностью невозможно. Ограничивающим
фактором в данном случае является сложность: большое число переменных, содержащихся во входных
данных, взаимодействиях функций, конфигурациях, ветвях кода и других компонентах приложения. В
определенный момент следует завершить тестирование ПО и выполнить поставку продукта либо
прекратить его разработку. Момент приостановки тестирования определяется оптимальным балансом
времени и бюджета (или других критериев команды тестирования) либо достижением заданных
критериев надежности ПО.
РЕСУРСЫ ПО ТЕСТИРОВАНИЮ
Подробнее об автоматизированном тестировании можно прочитать в следующих книгах:




Automated Software Testing: Introduction, Management, and Performance, Elfriede Dustin,
Jeff Rashka, John Paul. Addison-Wesley, 1999 г.
Just Enough Software Test Automation, Daniel J. Mosley, Bruce A. Posey. Yourdon Press,
2002 г.
Software Test Automation: Effective Use of Test Execution Tools, Mark Fewster, Dorothy
Graham. Addison-Wesley, 1999 г.
Testing Computer Software, Cem Kaner, Hung Quoc Nguyen, Jack Falk. Wiley, 1999 г.
Также сведения о тестировании можно найти на следующих веб-сайтах Microsoft:

Microsoft Tester Center на веб-сайте MSDN.

Testing Software Patterns на веб-сайте Microsoft Patterns & Practices.
В платформах и средствах модульного тестирования для создания, выполнения и анализа модульных
тестов может применяться решение Microsoft Visual Studio Team System Test Edition. В Visual Studio также
доступны среда тестирования кода и графический интерфейс пользователя для анализа результатов
теста. Список средств, с помощью которых можно создавать, профилировать, тестировать приложения
WPF и выполнять их отладку, приводится в разделе Средства настоящего документа.
ВВЕДЕНИЕ В ПРОГРАММНЫЙ КОМПЛЕКС WPF
В этом разделе рассматриваются следующие темы:

Архитектура WPF.

Принципы проектирования WPF.

Основные подсистемы WPF.

Общий процесс разработки приложения WPF.

Ресурсы с рекомендациями по созданию приложений WPF.
Архитектура WPF
В платформе WPF доступен обширный и высокоинтегрированный комплекс пользовательского
интерфейса, реализуемый через модель программирования .NET. На рис. 1 показана общая архитектура
и основные компоненты WPF.
РИС. 1. АРХИТЕКТУРА И ОСНОВНЫЕ КОМПОНЕНТЫ WPF
Новая платформа и новые средства помогают улучшить процесс разработки приложений, обеспечивая
повышенную производительность и более эффективную реализацию проекта приложения, а также
ускоренный вывод продукта на рынок.
Принципы проектирования WPF
Базовые принципы проектирования WPF можно разделить на следующие категории:

Интеграция. Платформа WPF предоставляет унифицированную модель программирования,
единую для всех элементов управления, графики, текста и служб мультимедиа, что обеспечивает
удобную интеграцию этих элементов в рамках приложения. Модель содержимого WPF
позволяет размещать в элементе управления любую группу других элементов управления. Для
упорядочения содержимого в фиксированном или потоковом макете в WPF доступны элементы
контейнера, реализующие различные алгоритмы макета независимо от типа их содержимого.
Более того, привязка данных, шаблоны, триггеры и анимация позволяют визуализировать
содержимое и оживить пользовательский интерфейс, обеспечивая интерактивность
взаимодействия пользователей с этим интерфейсом.

Векторная графика. В платформе WPF широко используются мощные возможности графических
процессоров (GPU), которыми оснащены современные компьютерные системы. Подсистема
формирования композиции основана на векторной графике, поэтому в WPF все выходные
данные адаптируются под разрешение того или иного устройства вывода. В ситуациях, когда
аппаратная визуализация невозможна, в качестве резервного варианта применяется
программная визуализация. Кроме того, благодаря логической системе пикселей с плавающей
точкой и поддержке 32-разрядных цветов ARGB изображение становится насыщенным и четким,
предвосхищая будущие технологические потребности, такие как дисплеи высокого разрешения.

Декларативное программирование. В платформе WPF впервые используется язык XAML,
основанный на языке XML и позволяющий создавать экземпляры объектов и заполнять
иерархии вложенных объектов. Структура XAML позволяет приложениям выполнять
синтаксический анализ и обработку элементов интерфейса во время выполнения. Модель с
выделенным кодом XAML поддерживается как средством проектирования Expression Studio, так
и средством разработки Visual Studio, гарантируя инженерам и разработчикам возможность
совместной работы над приложением.

Простое развертывание. Обеспечивая развертывание с помощью ClickOnce и поддерживая как
автономные, так и размещенные в браузере приложения, платформа WPF объединяет в себе
лучшее из обеих моделей развертывания.
ОСНОВНЫЕ ПОДСИСТЕМЫ WPF
Структура WPF состоит из подсистем или классов, определенных в различных пространствах имен.
Данные классы отличаются очень глубокой иерархией наследования. На рис. 2 показаны эти важные
классы и их взаимосвязи.
РИС. 2. КЛАССЫ ПОДСИСТЕМ WPF
Ниже описываются классы, образующие подсистемы WPF (ссылки ведут на документацию по каждому
отдельному классу на веб-сайте MSDN).







Object. Базовый класс для всех классов .NET Framework.
DispatcherObject. Базовый класс, обрабатывающий сообщения от других объектов.
DependencyObject (DO). Базовый класс для любого объекта, поддерживающего свойства
зависимостей (DP). Этот класс определяет методы GetValue и SetValue, которые являются
центральными методами в работе свойств зависимостей.
Freezable. Базовый класс для объектов, которые имеют изменяемое состояние и могут быть
«заморожены» в состоянии «только чтение» в целях повышения производительности.
Visual. Базовый класс для всех объектов, имеющих собственное визуальное представление. Этот
класс содержит дерево визуальных объектов, каждый из которых может включать инструкции
по прорисовке и метаданные о визуализации этих инструкций, такие как обрезка,
преобразование и др. Класс Visual — это точка входа для системы композиции WPF. Это также
точка взаимодействия двух подсистем: управляемого API и неуправляемого milcore (ядра
системы визуализации WPF).
UIElement. Базовый класс для всех визуальных объектов, обеспечивающий поддержку макета,
входных данных, фокуса и перенаправленных событий (совокупно — LIFE).
ContentElement. Базовый класс, сходный с классом UIElement, но относящийся к содержимому, у
которого отсутствует собственное поведение визуализации. Для визуализации в
пользовательском интерфейсе объекты ContentElement должны быть размещены в объекте,
производном от Visual.






FrameworkElement. Базовый класс, добавляющий поддержку стилей, привязки данных, ресурсов
и нескольких общих механизмов элементов управления Windows, таких как подсказки и
контекстные меню.
Control. Базовый класс, предоставляющий основные элементы для разработки графического
интерфейса пользователя, такие как Button, ListBox и др. Элементы управления относятся к
модели данных (свойства), модели взаимодействия (команды и события) и модели
отображения (шаблоны), позволяя разработчикам полностью изменить их внешний вид.
Shape. Базовый класс для фигур, таких как Ellipse, Polygon и Rectangle.
Panel. Базовый класс для всех элементов Panel, служащих для размещения и упорядочения
дочерних объектов в приложениях WPF.
ContentControl. Базовый класс для всех элементов управления, имеющих только один дочерний
элемент. Этот дочерний элемент может быть чем угодно — от строки до панели макета с
комбинацией других элементов управления и фигур.
ItemsControl. Базовый класс для элементов управления, с помощью которых можно представить
коллекцию элементов, таких как элементы управления ListBox и TreeView.
В следующей таблице перечислены наиболее важные из этих основных классов WPF и их базовые
функции.
Общий процесс разработки приложения WPF
Обзор платформы WPF и руководство по разработке приложений WPF см. в следующих статьях на вебсайте MSDN:


Введение в Windows Presentation Foundation. В этом руководстве содержатся краткие вводные
сведения по разработке приложений на платформе Windows Presentation Foundation (WPF).
Знакомство с Windows Presentation Foundation. В этом обзоре рассмотрены основные
возможности и понятия WPF.
Ресурсы с рекомендациями по созданию приложений WPF
Рекомендации для проектировщиков и разработчиков приложений WPF и сведения о шаблоне
проектирования приложений WPF см. в следующем техническом документе на веб-сайте Windows Client
и на сайте блога MSDN:



Best Practices for Designers.
Best Practices for Developers.
Запись блога Model/View/ViewModel pattern for building WPF apps, автор Джон Госсман (John
Gossman), сайт блога MSDN.
МЕТОДОЛОГИЯ, ПЛАНИРОВАНИЕ И СТРАТЕГИИ ТЕСТИРОВАНИЯ
Существует множество книг и ресурсов, описывающих методологии тестирования ПО, технологии
планирования и стратегии тестирования. (Список ресурсов см. в разделе Ресурсы по тестированию в
теме Введение в тестирование программного обеспечения этого документа.) В данном разделе
содержится краткий обзор общей методологии, планирования и стратегий тестирования.
Стратегия тестирования — это формулировка общего подхода к тестированию. Она определяет
уровни применяемого тестирования, а также используемые методы, технологии и средства.
Формирование четкой стратегии тестирования — это первый шаг в проектировании тестов. Лишь после
этого можно переходить к следующим мероприятиям по тестированию: разрабатывать планы
тестирования, определять структуру тестового случая, проводить тесты, собирать результаты их
выполнения, определять и исправлять ошибки.
Ниже приводятся основные факторы, надлежащий учет которых помогает сформировать правильную
стратегию тестирования и спланировать тестирование приложений WPF.





Внутрипроцессное и внепроцессное тестирование. Каждый подход по-разному влияет на
производительность и безопасность и т. д. В соответствии с требованиями приложения можно
выбрать один из этих подходов или их комбинацию.
Тестирование по принципу белого ящика, черного ящика либо комбинация обоих принципов
(тестирование потока управления, тестирование потока данных, тестирование случаев
использования и т. д.).
Ручное и автоматизированное тестирование (когда и какие тесты следует автоматизировать).
Модульное тестирование, системное тестирование и т. д.
Синхронизация и согласование по времени и т. д.
Существует множество стратегий тестирования. У каждой есть свои преимущества и недостатки,
зависящие, в частности, от общих потребностей бизнеса. Вот некоторые из стратегий тестирования:




Аналитические стратегии тестирования. В их основе лежит анализ. Это управляемая целью
стратегия, определяющая фокус тестирования на основе требований, проектирования и
внедрения. Для нее нужна предварительная подготовка и, соответственно, временные затраты.
Стратегии тестирования на основе модели. Они развивают модели поведения системы. Такая
стратегия зависит от способности инженера-тестировщика разрабатывать хорошие модели.
Методические стратегии тестирования. В них применяется относительно неформальный (и
вместе с тем регулярный и предсказуемый) подход к тому, где следует проводить тестирование.
Эта стратегия пригодна для относительно стабильных систем.
Стратегии тестирования, ориентированные на процессы. Эти стратегии включают процедуры
тестирования, определенные стандартом ISO, или гибкие облегченные процессы. Данные
стратегии часто используются для приемочного тестирования пользователями. Они также
подходят для реагирования на произошедшие изменения и успешно адаптируются для
небольших команд с низкой масштабируемостью продукта.
Принцип хорошего тестирования — согласование контекста проекта, цели и стратегии тестирования, а
также тактики. Чем тщательнее согласованы эти факторы, тем эффективнее пройдет тестирование.
Эффективное тестирование ПО обычно достигается при выполнении различных типов тестов, как
ручных, так и автоматизированных. Комбинации и количество тестов определяются требованиями к
качеству приложения. Является ли приложение критически важным? Является ли главным фактором
время выхода продукта на рынок?
Разработчики могут применять при модульном тестировании методологию разработки через
тестирование (TDD). Преимущества этой технологии заключаются в том, что большинство ошибок
обнаруживается в ходе модульных тестов на ранней стадии разработки, этап тестирования ПО
оказывается на порядок короче, а стоимость исправления ошибок уменьшается. Такая методология
может подойти для компаний и проектов с небольшим бюджетом отдела контроля качества или вовсе
без него. С ее помощью можно улучшить качество кода еще до того, как он достигнет стадии
тестирования.






Конечная цель этого руководства — улучшить качество и тестопригодность приложений WPF. К
преимуществам тестопригодности относятся доступность, гибкость, управляемость, надежность,
удобство использования и внесения изменений, а также отказоустойчивость. Ниже приводятся
общие рекомендации по улучшению тестопригодности приложений WPF.
Выполните рефакторинг, отделив бизнес-логику от пользовательского интерфейса с помощью
шаблона MVVM при проектировании и тестировании приложения. Дополнительные сведения о
шаблоне MVVM для приложений WPF см. в блоге Джона Госсмана.
Заранее выполняйте простые тесты, инвестируя в модульное тестирование. Это позволяет
обнаружить ошибки и дефекты на ранних этапах жизненного цикла продукта, а значит, для их
исправления потребуется намного меньше затрат.
Автоматизируйте тесты снизу вверх (см. ниже рис. 3). Сначала разрабатывайте модульные тесты,
затем функциональные, системные и т. д. Тестирование интеграции может быть связано со
значительными временными и финансовыми затратами. Поэтому, перед тем как перейти к
тестированию интеграции, создайте надежные модульные, функциональные и системные тесты.
Тестируйте пользовательский интерфейс и компоненты кода по отдельности.
Выполняйте тестирование интеграции на стабильном пользовательском интерфейсе и типичных
пользовательских сценариях.
РИС. 3. МОДЕЛЬ ДЛЯ АВТОМАТИЗАЦИИ ТЕСТОВ В НАПРАВЛЕНИИ СНИЗУ ВВЕРХ
Дополнительные сведения о различных методологиях, процессах планирования и разнообразных
стратегиях тестирования см. в разделе «Ресурсы по тестированию» в теме Введение в тестирование
программного обеспечения этого документа.
АВТОМАТИЗИРОВАННОЕ ТЕСТИРОВАНИЕ
УПРАВЛЯЕМОЕ ДАННЫМИ ТЕСТИРОВАНИЕ
ОБЗОР
Обычный набор тестирования состоит из сотен или тысяч разновидностей тестов. Среды тестирования
(vsUnit, NUnit и др.) предоставляют ряд способов объявления разновидностей, таких как маркировка
классов и методов с помощью атрибутов или иным образом. Часто разновидности тестов определяются
во время компиляции; инженер-тестировщик или разработчик обычно создает метод тестирования и
помечает его соответствующим образом.
Представьте, что вам необходимо протестировать следующий класс:
public class Person
{
public Person(string firstName, string lastName, int age);
public int Age { get; private set; }
public string FullName { get; private set; }
}
Традиционный модульный тест может выглядеть примерно так:
//
// This is a Visual Studio unit test, but the ideas are applicable to any
unit
// test framework.
//
[TestClass()]
public class PersonTests
{
...
[TestMethod()]
public void CreatePersonWithValidParameters()
{
string firstName = "John";
string lastName = "Smith";
int age = 21;
Person p = new Person(firstName, lastName, age);
Assert.AreEqual(firstName + " " + lastName , p.FullName);
Assert.AreEqual(age, p.Age);
}
[TestMethod()]
[ExpectedException(typeof(System.ArgumentException))]
public void CreatePersonWithInvalidAge()
{
string firstName = "Peter";
string lastName = "Jones";
int age = -5;
Person p = new Person(firstName, lastName, age);
// The code above assumes the c’tor of Person will throw upon
invalid age.
}
}
Хотя данный подход эффективен в сценариях модульного тестирования, он имеет ряд недостатков:





чтобы добавить, удалить или изменить тест, придется повторно компилировать весь набор
тестов или его часть;
код может дублироваться;
тестовый код может быть не полностью пригоден для повторного использования;
могут возникать проблемы с фильтрацией тестов и выполнением подмножеств тестов;
данный подход может миновать процедуру надлежащего планирования тестирования.
Альтернативой этому подходу является управляемое данными тестирование. В ходе такого
тестирования разновидности тестов (или их часть) создаются во время выполнения, а не компиляции.
Обычно разновидности считываются из внешнего файла, хотя иногда могут быть закодированы в такой
структуре данных, как массив.
На основе следующего примера создается возможная реализация управляемого данными теста,
состоящего из нескольких этапов.
1. Инженер-тестировщик определяет схему для представления всех разновидностей теста с
помощью XML, как в следующем примере:
<!-- MyVariations.xml -->
<Variations>
<Variation Id="1"
FirstName="John" LastName="Smith" Age="21"
ExpectedFullName="John Smith" ExpectedAge="21"
ExpectedExceptionType="null"
/>
<Variation Id="2"
FirstName="Peter" LastName="Jones" Age="-5"
ExpectedFullName="Peter Jones" ExpectedAge="0"
ExpectedExceptionType="ArgumentException"
/>
...
</Variations>
2. Тестовый код десериализует разновидности в памяти, создавая один или несколько
объектов описания разновидностей.
3. Тестовый код выполняет разновидности, проходя по коллекции объектов описания
разновидностей, с помощью следующего кода:
[TestClass()]
public class PersonTests
{
...
[TestMethod()]
public void CreatePerson()
{
//
// The code assumes the existence of ReadVariationsFromFile,
which
// deserializes the variations from the MyVariations.xml file
shown above.
//
List<Variation> variations =
ReadVariationsFromFile("MyVariations.xml");
foreach (Variation v in variations)
{
Person p = null;
Type actualExceptionType = null;
string actualFullName = String.Empty;
int actualAge = 0;
try
{
p = new Person(v.FirstName, v.LastName, v.Age);
actualFullName = p.FullName;
actualAge = p.Age;
}
catch (Exception e)
{
actualExceptionType = typeof(e);
}
//
// The verifications below can be and often are encapsulated
in a
// separate verifier. Often verifiers are specified as part
of the
// data-file schema and are created dynamically by a
factory.
//
if (v.ExpectedFullName == actualFullName &&
v.ExpectedAge = actualAge &&
v.ExpectedExceptionType == actualExceptionType)
{
// Pass. You may want to log details about the pass here
}
else
{
// Fail. Log the expected and actual results for failure
analysis.
Assert.Fail(
"FullName: exp: {0}, act: {1}; Age: exp: {2}, act:
{3}; ExceptionType: exp: {4}, act: {5}",
v.ExpectedFullName, actualFullName,
v.ExpectedAge, actualAge,
v.ExpectedExceptionType, actualExceptionType);
}
}
}
}
В качестве иллюстрации приведем пример кода для класса Variation:
public class Variation
{
public Variation(XmlNode variationNode)
{
this.Id = variationNode.Attributes["Id"].Value;
this.FirstName = variationNode.Attributes["FirstName"].Value;
this.LastName = variationNode.Attributes["LastName"].Value;
this.Age =
Int32.Parse(variationNode.Attributes["Age"].Value);
this.ExpectedFullName =
variationNode.Attributes["ExpectedFullName"].Value;
this.ExpectedAge =
Int32.Parse(variationNode.Attributes["ExpectedAge"].Value);
this.ExpectedExceptionType =
Type.GetType(variationNode.Attributes["ExpectedExceptionType"].Value)
;
}
public string Id { get; private set; }
//
// Expected input values
//
public string FirstName { get; private set; }
public string LastName { get; private set; }
public int Age { get; private set; }
//
// Expected output values
//
public string ExpectedFullName { get; private set; }
public int ExpectedAge { get; private set; }
public Type ExpectedExceptionType { get; private set; }
}
А метод ReadVariationsFromFile может выглядеть следующим образом (этот метод часто включается в
качестве статического в сам класс Variation или в класс VariationUtilities вместе с другими функциями,
относящимися к обработке экземпляров класса Variation):
...
public static List<Variation> ReadVariationsFromFile(string filename)
{
List<Variation> list = new List<Variation>();
XmlDocument doc = new XmlDocument();
doc.Load(filename);
foreach (XmlNode n in doc.GetElementsByTagName("Variation"))
{
Variation v = new Variation(n);
list.Add(v);
}
return list;
}
Код в предыдущем примере несколько более сложен, чем эквивалентный код модульного
тестирования. Однако он предоставляет следующие преимущества:






Можно легко добавлять, удалять, изменять и временно отключать новые разновидности тестов.
Можно создавать комбинаторные разновидности.
Упрощается отладка тестов, поскольку обычно есть одна структура, содержащая все данные,
сопоставленные разновидности.
Стратегии проверки можно определять во время выполнения. Инженеры-тестировщики могут
инициализировать объекты верификации из файла данных так же, как и разновидности.
Код можно использовать повторно, снижается и степень дублирования кода. Тщательное
планирование управляемого данными теста позволяет получить ряд повторно используемых
классов (фабрики, верификаторы и т. д.). Крупные фрагменты тестового кода можно повторно
использовать для нагрузочных тестов, тестов на масштабируемость, функциональных тестов и
др.
Можно улучшить процесс планирования тестов. Например, перед реализацией теста инженертестировщик может составить список показателей теста, которые необходимо разнообразить, и
наблюдаемых результатов, которые требуется проверить.
Некоторые преимущества становятся очевидными лишь после того, как число разновидностей тестов
достигнет нескольких тысяч.
С другой стороны, управляемое данными тестирование имеет ряд недостатков.



В результате появления дополнительных файлов данных несколько увеличиваются затраты на
развертывание и контроль тестов.
По сравнению с модульными тестами код может усложниться.
Из-за динамической природы управляемых данными тестов не выполняются некоторые
проверки во время компиляции.
Более сложные тесты и технологии тестирования, такие как тестирование на основе модели, нечеткое
тестирование и др., обычно сводятся к использованию тестов, управляемых данными.
Важно отметить, что множество существующих сред модульного тестирования (Mb Unit, MSTest, xUnit)
успешно поддерживают управляемые данными тесты. Управляемое данными тестирование на основе
XML, рассмотренное выше, — это лишь одна из возможных реализаций управляемых данными тестов,
которая вовсе не обязательно подойдет для сред модульного тестирования, поддерживающих
описанный подход. Вышеприведенный пример — это лишь демонстрация общей концепции, а не
деталей реализации. Поэтому разработчикам и инженерам-тестировщикам настоятельно
рекомендуется применять возможности управляемого данными тестирования, которые доступны в
используемой среде модульного тестирования.
МЕТОДОЛОГИЯ
Ниже приводятся этапы, описывающие общую методологию создания управляемых данными
тестов.
1. Инженер-тестировщик указывает все показатели (и соответствующие им значения),
которые планируется разнообразить в ходе тестирования, и все наблюдаемые
результаты, которые необходимо проверить. Это называется матрицей тестирования.
Матрица тестирования для вышеприведенного примера может быть следующей:
Показатель
Имя в
конструкторе
Тип
Строка
Возможные значения
o
o
o
o
o
o
o
o
Фамилия в
конструкторе
Возраст в
конструкторе
Строка
(См. выше.)
Целое число
o
o
...
Допустимое имя
Недопустимая строка
Строка, содержащая любые из следующих
символов: число в начале или в конце,
неалфавитные символы, неверное применение
заглавных букв
Одна буква
Пустая строка
Очень длинная строка
Строка, содержащая специальные символы
(невидимые символы и др.)
null
Допустимое
Недопустимое (отрицательное, неоправданно
большое и др.)
...
Обратите внимание, что некоторые отслеживаемые в матрице показатели могут быть
показателями среды (язык системы, ОС и др.). В приведенную таблицу эти показатели не
включены, однако обычная матрица содержит не менее двух таких показателей.
Наблюдаемые результаты
Значение объекта — null
Создано исключение из конструктора
Создано исключение из свойств
Проверено ожидаемое состояние объекта (свойства возвращают
правильные значения и т. д.)
2. Инженер-тестировщик обсуждает матрицу тестирования с разработчиком, который
обычно предлагает дополнить ее.
3. Инженер-тестировщик перечисляет основные сценарии и высокоприоритетные тесты.
4. Инженер-тестировщик создает схему данных для хранения всех данных, связанных с
одной разновидностью.
5. Инженер-тестировщик создает комбинаторные разновидности с помощью специального
средства. (Большинство таких средств позволяют сократить число разновидностей.)
Основные сценарии и высокоприоритетные тесты получают соответствующие
обозначения (вручную или с помощью средства).
6. Инженер-тестировщик проектирует и реализует необходимые фрагменты для
повторного использования (например, верификаторы) и проводит тесты.
7. Инженер-тестировщик планирует и реализует другие основные тесты
(производительности, масштабируемости, безопасности и др.).
ЗАКЛЮЧЕНИЕ
Управляемое данными тестирование — это важная модель, которая позволяет улучшить повторное
использование кода, возможность отладки и общую структуру тестового кода при условии, что будет
проведено надлежащее предварительное планирование тестов. Множество существующих сред
модульного тестирования включают функции поддержки управляемого данными тестирования, с
помощью которых можно развернуть управляемые данными тесты.
Управляемое данными тестирование не отменяет модульное тестирование. Оба подхода
преимущественно дополняют друг друга, при этом управляемые данными тесты — это своего рода
расширение фундаментальных модульных тестов.
ТЕСТИРОВАНИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
ОСНОВНЫЕ РЕКОМЕНДАЦИИ ПО ОБЕСПЕЧЕНИЮ ДОСТУПНОСТИ
ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
Возможность уникальным образом идентифицировать и найти любой элемент управления в рамках
пользовательского интерфейса — основное условие для обработки этого интерфейса
автоматизированными приложениями для тестирования. Для программного доступа к элементам
пользовательского интерфейса эти элементы должны быть помечены, значения свойств —
предоставлены, а соответствующие события — вызваны. В случае со стандартными элементами
управления WPF большая часть этих требований уже выполнена с помощью класса AutomationPeer.
Что касается пользовательских элементов, то для надлежащей реализации программного доступа к
этим элементам необходимы дополнительные действия.
ОБЕСПЕЧЕНИЕ ПРОГРАММНОГО ДОСТУПА КО ВСЕМ ЭЛЕМЕНТАМ И ТЕКСТУ
ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
Элементы пользовательского интерфейса следует настроить для обеспечения программного доступа. В
стандартные элементы управления WPF поддержка программного доступа уже встроена. Напротив, в
случае с пользовательскими элементами управления (производными от существующих или
непосредственно от класса Control) необходимо проверить, нет ли в реализации соответствующего
класса AutomationPeer областей, требующих изменения. Чтобы улучшить тестопригодность, убедитесь,
что каждому элементу управления в приложении сопоставлено значение свойства AutomationId
(одного из основных свойств модели автоматизации пользовательского интерфейса Microsoft) —
уникального и не зависящего от языка свойства. Значение AutomationId, единое для каждой сборки,
позволяет быстро (по сравнению с другими методами поиска) найти элемент управления в визуальном
дереве.
ДОБАВЛЕНИЕ К ОБЪЕКТАМ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА ИМЕН,
ТЕКСТА СПРАВКИ, НАЗВАНИЙ И ОПИСАНИЙ
Специальные возможности, особенно программы чтения с экрана, определяют расположение рамки,
объекта или страницы в схеме навигации на основе их названий. Поэтому название должно быть
описательным. Аналогично, для элементов управления WPF важными для устройств специальных
возможностей и автоматизированного тестирования являются значения свойств NameProperty и
HelpTextProperty. Это особенно важно для объектов WPF ItemsControl (TreeView, ListBox,
ComboBox и др.), поскольку значение AutomationId отдельного элемента может использоваться
повторно в другом поддереве общего родительского дерева.
Если экземпляр ItemsControl привязан к источнику XML-данных, то специальная возможность
(например, приложение экранного диктора) получает значение каждого элемента в экземпляре
ItemsControl с помощью метода ToString. Это значение имеет вид строки System.Xml.XmlElement.
Чтобы предоставить программе экранного диктора осмысленное значение, можно связать свойство
AutomationProperties.Name со свойством источника данных, отображаемым в экземпляре
ItemsControl.
ОБЕСПЕЧЕНИЕ ВЫЗОВА ПРОГРАММНЫХ СОБЫТИЙ ВСЕМИ ВИДАМИ
АКТИВНОСТИ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
Если элемент управления является производным от стандартного элемента управления или от класса
Control, следует проверить, нет ли в соответствующем классе AutomationPeer областей, требующих
изменения. Следует также надлежащим образом предоставить соответствующие события для нового
элемента управления. Выполнение этих рекомендаций гарантирует, что средства специальных
возможностей будут своевременно уведомляться об изменениях в пользовательском интерфейсе и
смогут сообщать о них пользователю. Дополнительные сведения о создании пользовательского
элемента управления с помощью класса AutomationPeer см. ниже в разделе Пользовательские
элементы управления и тестирование расширяемости этого документа. Дополнительные сведения об
обеспечении доступности пользовательского интерфейса см. в статье Рекомендации по специальным
возможностям на веб-сайте MSDN.
Средство UI Spy (Wispy.exe) помогает быстрее находить визуальные элементы в дереве
пользовательского интерфейса, обнаруживать их свойства и вызываемые ими события, а также
взаимодействовать с визуальными элементами. Средство UI Spy входит в файл для загрузки Windows
SDK, доступный на веб-сайте Центра загрузки Microsoft.
ОБНАРУЖЕНИЕ ЭЛЕМЕНТОВ ИНТЕРФЕЙСА
В этом разделе описывается использование модели автоматизации пользовательского интерфейса
Microsoft для автоматизированного тестирования. В нем содержится краткий обзор объектной модели
автоматизации пользовательского интерфейса Microsoft, перечисляются этапы внедрения этой модели
в приложениях WPF, а также рекомендации и различные подходы к выделению элементов
пользовательского интерфейса, а затем приводятся примеры кода для этих подходов.
ОБЪЕКТНАЯ МОДЕЛЬ API АВТОМАТИЗАЦИИ ПОЛЬЗОВАТЕЛЬСКОГО
ИНТЕРФЕЙСА
Каждый элемент пользовательского интерфейса, будь то окно, кнопка или иной элемент, представлен
производным от AutomationElement классом в пространстве имен System.Windows.Automation сборки
UIAutomationClient. Экземпляр класса AutomationElement соответствует элементу пользовательского
интерфейса независимо от платформы (WPF или Win32). Все элементы автоматизации являются
частью дерева, в котором корневому элементу соответствует рабочий стол Windows. С помощью
статического свойства AutomationElement.RootElement можно получить ссылку на элемент рабочего
стола Windows и оттуда найти любой дочерний элемент пользовательского интерфейса.
Объекты AutomationElement предоставляют шаблоны элементов управления со свойствами и
событиями для стандартных элементов управления (окна, кнопки, флажки и др.). В свою очередь,
шаблоны управления предоставляют методы, с помощью которых клиенты могут получить
дополнительные сведения об элементе и предоставить элементу входные данные.
ЭТАПЫ РЕАЛИЗАЦИИ МОДЕЛИ АВТОМАТИЗАЦИИ ПОЛЬЗОВАТЕЛЬСКОГО
ИНТЕРФЕЙСА
В следующей таблице перечислены этапы реализации модели автоматизации пользовательского
интерфейса в приложении WPF.
Этапы реализации модели автоматизации пользовательского интерфейса в приложении
WPF
Этап
Описание
Добавление ссылок модели
автоматизации пользовательского
интерфейса
Необходимо добавить следующие библиотеки DLL модели
автоматизации пользовательского интерфейса:



UIAutomationClient.dll. Предоставляет доступ к
клиентским API модели автоматизации
пользовательского интерфейса.
UIAutomationClientSideProvider.dll. Позволяет
автоматизировать элементы управления Win32, а также
элементы управления WPF, взаимодействующие с
возможностями Win32. Дополнительные сведения см.
на странице Поддержка автоматизации
пользовательского интерфейса для стандартных
элементов управления.
UIAutomationTypes.dll. Предоставляет доступ к типам,
определенным в модели автоматизации
пользовательского интерфейса.
Добавление пространства имен
System.Windows.Automation
В этом пространстве имен содержится все, что требуется
клиентам модели автоматизации пользовательского
интерфейса для использования ее возможностей (за
исключением обработки текста).
Добавление пространства имен
System.Windows.Automation.Text
В этом пространстве имен содержится все, что требуется
клиентам модели автоматизации пользовательского
интерфейса для использования её возможностей обработки
текста.
Поиск интересующих элементов
управления
Автоматизированные сценарии находят элементы модели
автоматизации пользовательского интерфейса,
соответствующие элементам управления в дереве
автоматизации. Ссылки на элементы модели автоматизации
пользовательского интерфейса можно получить следующими
способами:

Запросить элемент пользовательского интерфейса с
помощью оператора Condition. Обычно это делается
при использовании не зависящего от языка
значения AutomationId.
Примечание
Значение AutomationIdProperty можно получить с
помощью такого средства, как UI Spy (UISpy.exe),
позволяющего детализировать свойства
автоматизации элемента управления.



Использовать класс TreeWalker для прохода всего
дерева автоматизации или его подмножества.
Отследить фокус.
Использовать расположение на экране, например
расположение указателя.
Дополнительные сведения см. в статье Получение элементов
автоматизации пользовательского интерфейса на веб-сайте
MSDN.
Получение шаблонов элементов
управления
Шаблоны элементов управления предоставляют общие типы
поведения для сходных по функциональности элементов
управления. Когда сценарии автоматизированного
тестирования находят требующие тестирования элементы
управления, они получают из них интересующие шаблоны
элементов управления, такие как InvokePattern для типовой
функциональности кнопки или WindowPattern для
функциональности окна.
Дополнительные сведения см. в статье Общие сведения о
шаблонах элементов управления модели автоматизации
пользовательского интерфейса на веб-сайте MSDN.
Автоматизация пользовательского
интерфейса
После получения шаблона элемента управления сценарии
автоматизированного тестирования могут управлять любым
пользовательским интерфейсом с платформы
пользовательского интерфейса, используя сведения и функции,
предоставляемые шаблонами элементов управления модели
автоматизации пользовательского интерфейса.
РЕКОМЕНДАЦИИ ПО ПОЛУЧЕНИЮ ЭЛЕМЕНТОВ МОДЕЛИ АВТОМАТИЗАЦИИ
ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
Ниже приводятся рекомендации для получения элементов модели автоматизации пользовательского
интерфейса.





Как правило, получают только прямые дочерние объекты объекта RootElement. Поиск потомков
может пройти через сотни и даже тысячи элементов, вызвав переполнение стека. Если
необходимо получить конкретный элемент на более низком уровне, необходимо начать поиск с
окна приложения или контейнера на более низком уровне.
Чтобы найти известный элемент (определяемый свойством Name, AutomationId или другим
свойством либо комбинацией свойств), лучше всего воспользоваться методом FindFirst. Если
искомый элемент — это окно приложения, начальным пунктом поиска может быть объект
RootElement.
Чтобы найти все элементы, удовлетворяющие определенным критериям и связанные с
известным элементом, используйте метод FindAll. Например, с помощью этого метода можно
получить соответствующие элементы из списка или меню либо определить все элементы
управления в диалоговом окне.
Если вы не знаете заранее, с какими приложениями будет использоваться ваш клиент, можно
построить поддерево всех искомых элементов с помощью класса TreeWalker. Ваше приложение
может сделать это в ответ на событие изменения фокуса. То есть, когда приложение или
элемент управления получает фокус входных данных, клиент модели автоматизации
пользовательского интерфейса исследует дочерние объекты и все потомки элемента,
получившего фокус.
Когда будут найдены поддерживаемые шаблоны для заданного элемента интерфейса
пользователя, настоятельно рекомендуется не вызывать метод GetSupportedPatterns. В
противном случае может серьезно снизиться производительность, поскольку такой метод
внутренне вызывает метод GetCurrentPattern для каждого существующего шаблона элемента
управления. При возможности метод GetCurrentPattern следует вызывать только для избранных
шаблонов.
СПОСОБЫ ОБНАРУЖЕНИЯ ЭЛЕМЕНТОВ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
С ПОМОЩЬЮ МОДЕЛИ АВТОМАТИЗАЦИИ ПОЛЬЗОВАТЕЛЬСКОГО
ИНТЕРФЕЙСА
Разработчики и инженеры-тестировщики могут применять следующие способы для поиска элемента с
помощью упомянутой модели:









Поиск значения AutomationId данного элемента. Обратите внимание, что значение AutomationId
может повторно использоваться в потомках. Дополнительные сведения см. в статье
Использование свойства AutomationID на веб-сайте MSDN.
Поиск на основе локализованного имени элемента управления.
Поиск на основе типа элемента управления.
Поиск на основе значения PropertyCondition.
Получение ссылки на элемент управления в обработчике событий.
Поиск объекта ListItem.
Поиск на основе значения свойства ClassName.
Создание в приложении многопотокового подразделения (MTA) потока однопотокового
подразделения (STA) для доступа к пользовательскому интерфейсу, который может быть
неисправен.
Использование объекта WPF Dispatcher для автоматизации объекта AutomationElement в потоке
пользовательского интерфейса.
Если клиентское приложение может пытаться искать элементы в собственном пользовательском
интерфейсе, разработчики и инженер-тестировщик должны выполнять все вызовы модели
автоматизации пользовательского интерфейса в отдельном потоке. Дополнительные сведения см. на
странице Проблемы потока модели автоматизации пользовательского интерфейса.
ПРИМЕРЫ КОДА ДЛЯ ПОИСКА ЭЛЕМЕНТОВ ПОЛЬЗОВАТЕЛЬСКОГО
ИНТЕРФЕЙСА
В этом разделе приводятся примеры кода, демонстрирующие обнаружение элементов
пользовательского интерфейса. Данные примеры — это фрагменты кода, доступного в примере проекта
тестирования, который можно найти ниже в разделе «Создание пользовательских элементов
управления и пример тестирования» этого документа.
Пример 1. В этом примере показано, как найти в приложении WPF кнопку со значением AutomationID,
равным button1, и нажать ее.
/// <summary>
/// Finds a UI Automation child element by AutomationID.
/// </summary>
/// <param name="automationID">AutomationID of the control, such as
"button1".</param>
/// <param name="rootElement">Parent element, such as an application
window, or
/// AutomationElement.RootElement object when searching for the application
/// window.</param>
/// <returns>The UI Automation element.</returns>
private AutomationElement FindElementByID(String automationID,
AutomationElement rootElement)
{
if ((automationID == "") || (rootElement == null))
{
throw new ArgumentException("Argument cannot be null or empty.");
}
// Set a property condition that will be used to find the control.
Condition c = new PropertyCondition(
AutomationElement.AutomationIdProperty, automationID,
PropertyConditionFlags.IgnoreCase);
// Find the element.
return rootElement.FindFirst(TreeScope.Element | TreeScope.Children, c);
}
Пример 2. В этом примере показано, как найти элемент управления по его имени.
/// <summary>
/// Finds a UI Automation child element by name.
/// </summary>
/// <param name="controlName">Name of the control, such as
"button1".</param>
/// <param name="rootElement">Parent element, such as an application
window, or
/// AutomationElement.RootElement object when searching for the
application
/// window.</param>
/// <returns>The UI Automation element.</returns>
private AutomationElement FindElementByName(String controlName,
AutomationElement rootElement)
{
if ((controlName == "") || (rootElement == null))
{
throw new ArgumentException("Argument cannot be null or empty.");
}
// Set a property condition that will be used to find the control.
Condition c = new PropertyCondition(
AutomationElement.NameProperty, controlName,
PropertyConditionFlags.IgnoreCase);
// Find the element.
return rootElement.FindFirst(TreeScope.Element | TreeScope.Children,
c);
}
Пример 3. В этом примере показано, как найти элемент управления по его типу.
/// <summary>
/// Finds a UI Automation child element by control type.
/// </summary>
/// <param name="controlType">Control type of the control, such as
Button.</param>
/// <param name="rootElement">Parent element, such as an application
window, or
/// AutomationElement.RootElement when searching for the application
window.</param>
/// <returns>The UI Automation element.</returns>
private AutomationElement FindElementByType(ControlType controlType,
AutomationElement rootElement)
{
if ((controlType == null) || (rootElement == null))
{
throw new ArgumentException("Argument cannot be null.");
}
// Set a property condition that will be used to find the control.
Condition c = new PropertyCondition(
AutomationElement.ControlTypeProperty, controlType);
// Find the element.
return rootElement.FindFirst(TreeScope.Element | TreeScope.Children, c);
}
Пример 4. В этом примере показано, как найти элемент управления по его состоянию (например, все
включенные кнопки).
/// <summary>
/// Finds all enabled buttons in the specified root element.
/// </summary>
/// <param name="rootElement">The parent element.</param>
/// <returns>A collection of elements that meet the conditions.</returns>
AutomationElementCollection FindByMultipleConditions(AutomationElement
rootElement)
{
if (rootElement == null)
{
throw new ArgumentException();
}
Condition c = new AndCondition(
new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty,
ControlType.Button)
);
// Find all children that match the specified conditions.
return rootElement.FindAll(TreeScope.Children, c);
}
Пример 5. В этом примере показано, как найти элемент в событии. Когда приложение получает событие
модели автоматизации пользовательского интерфейса, исходный объект, передаваемый обработчику
событий, — это экземпляр AutomationElement.
// Shows how to track the Start button’s Invoke event.
// start is the AutomationElement object that represents the Start button.
// Register an event handler for the InvokedEvent method of the Start
button.
Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent, start,
TreeScope.Element,
new AutomationEventHandler(OnStartInvoke));
// The event handler.
private void OnStartInvoke(object src, AutomationEventArgs e)
{
MessageBox.Show("Start has been invoked");
}
Пример 6. В этом примере показано, как найти элемент в элементе списка. Здесь используется метод
FindAll для получения указанного элемента списка. Для элементов управления WPF это более быстрый
способ, чем применение класса TreeWalker.
/// <summary>
/// Retrieves an element in a list by using the FindAll method.
/// </summary>
/// <param name="parent">The list element.</param>
/// <param name="index"> The index of the element to find.</param>
/// <returns>The list item.</returns>
AutomationElement FindListItemByIndex(AutomationElement parent, int index)
{
if (parent == null)
{
throw new ArgumentException();
}
Condition c = new AndCondition(
new PropertyCondition(AutomationElement.IsControlElementProperty, true));
// Find all children that match the specified conditions.
AutomationElementCollection found = parent.FindAll(TreeScope.Children, c);
return found[index];
}
Пример 7. В этом примере показано, как найти элемент пользовательского интерфейса по имени класса.
/// <summary>
/// Finds an element by its class name starting from a specific root
element.
/// </summary>
/// <param name="root">The root element to start from.</param>
/// <param name="type">The class name of the control type to find.</param>
/// <returns>The list item.</returns>
AutomationElement FindListItemByType(AutomationElement root, String type)
{
if ((root == null) || (type == ""))
{
throw new ArgumentException("Argument cannot be null or empty.");
}
Condition c = new AndCondition(
new PropertyCondition(AutomationElement.ClassNameProperty, type));
// Find all children that match the specified conditions.
AutomationElementCollection found = root.FindAll(TreeScope.Children, c);
return found[index];
}
Пример 8. Иногда удобно автоматизировать приложение из того же процесса — по сути, приложение
автоматизирует само себя. Это может быть удобно, поскольку у теста есть доступ к внутреннему
состоянию приложения, к которому нелегко получить доступ из другого процесса. Однако нужно быть
осторожным: если заблокировать основной поток пользовательского интерфейса, приложение может
зависнуть. Поэтому код UIAutomation выполняется в отдельном потоке. В примерах 8 и 9 показано, как
этого достичь.
В примере 8 демонстрируется создание потока STA для доступа к пользовательскому интерфейсу,
который может быть неисправен, в приложении MTA. Наиболее распространенный сценарий этой
ситуации — использование некоторых сборок Internet Explorer. В этих случаях в HTML не будет дерева
UIAutomation. Сообщение исключения:
Сообщение: навигация по дереву автоматизации неисправна. Родительский объект одного из потомков
существует, но потомок не является дочерним объектом родительского.
Проблема с браузером Internet Explorer — не единственный возможный источник такой ошибки, но в
случае с приложениями MTA инженерам-тестировщикам рекомендуется попробовать подход,
показанный в следующем примере. Этот подход — общая рекомендация для доступа к содержимому
HTML, поскольку инженерам-тестировщикам неизвестна платформа или версия Internet Explorer на
компьютере пользователя. Дополнительные сведения о потоках в .NET Framework см. в статье
Управляемая поточность на веб-сайте MSDN.
ParameterizedThreadStart workerThread = new
ParameterizedThreadStart(handleWindowNewThread);
Thread thread = new Thread(workerThread);
thread.SetApartmentState(ApartmentState.STA);
thread.Start(<single object for argument to method>);
thread.Join();
...
private void handleWindowNewThread(object arguments) {...}
Пример 9. В этом примере показано, как с помощью объекта WPF Dispatcher создать отдельный поток
для автоматизации объекта AutomationElement в потоке пользовательского интерфейса.
private Dispatcher dispatcher = null;
private delegate void SimpleDelegate();
public void PerformAutomationOperations()
{
dispatcher = Dispatcher.CurrentDispatcher;
Thread automationThread =
new Thread(new ThreadStart(ProcessAutomationElementOnThread));
automationThread.SetApartmentState(System.Threading.ApartmentState.STA);
automationThread.Start();
}
private void ProcessAutomationElementOnThread()
{
AutomationElement element = AutomationElement.FocusedElement;
// Perform operations on the AutomationElement object.
dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
new SystemDelegate(ReturnBacktoUiThread));
}
private void ReturnBackToUiThread()
{
Application.Current.MainWindow.Title = "Back on the UI Thread";
}
СОБЫТИЯ И ВЗАИМОДЕЙСТВИЕ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
Будет рассмотрено в следующих выпусках.
ТЕСТИРОВАНИЕ МЕТОДОМ ВИЗУАЛЬНОЙ ПРОВЕРКИ
Тестирование методом визуальной проверки служит для подтверждения того, что приложение или его
компонент визуализируется на экране ожидаемым образом. В сущности, есть два типа тестирования
методом визуальной проверки: проверка на основе главного изображения и аналитическая визуальная
проверка. Эти методы отличаются лишь способом получения ожидаемого изображения.
ПРОВЕРКА НА ОСНОВЕ ГЛАВНОГО ИЗОБРАЖЕНИЯ
Для проведения проверки на основе главного изображения инженеры-тестировщики должны получить
это главное изображение. Обычно для этого выполняется первоначальный запуск тестового случая с
последующим сохранением снимка экрана. Инженер-тестировщик визуально проверяет корректность
снимка экрана. Корректный снимок помечается и сохраняется как главное изображение для этого
тестового случая. При всех последующих проходах теста изображение, полученное в ходе тестирования,
сравнивается с главным.
Этот подход довольно прост, но не лишен недостатков.


Обычно главные изображения привязаны к разрешению экрана, платформе, хрому и стилю
окна. Теоретически инженерам-тестировщикам пришлось бы создавать главные изображения
для всех комбинаций этих переменных. Однако они могут сократить число сохраненных
изображений, создавая главные изображения, включающие только клиентскую область окна, а
не весь набор элементов хрома. Кроме того инженеры-тестировщики могут преобразовать
масштаб сравниваемых изображений, адаптировав их под разрешение главного изображения.
В зависимости от числа тестов и комбинаций платформы и разрешения число главных
изображений может стать довольно большим. Для обновления главных изображений
необходимо, чтобы инженер-тестировщик проверил правильность каждого главного
изображения. При большом количестве главных изображений у набора тестов может оказаться
очень высокая стоимость текущей поддержки. Кроме того, общий размер сохраненных главных
изображений может потребовать значительного пространства для хранения, в результате чего
увеличиваются сроки настройки, выполнения и очистки тестов. Поэтому очень важно
ограничивать размер и количество главных изображений. Один из способов — захватывать
небольшие области окна (а не окна целиком), содержащие интегрированное содержимое (а не
создавать главное изображение для каждого базового элемента).
В целом проверка на основе главного изображения будет выполняться независимо от способа создания
этих изображений. Инженеры-тестировщики не обязаны знать принципы внутренней работы
компонента, поскольку они отвечают за окончательное утверждение главного изображения,
используемого для тестирования.
АНАЛИТИЧЕСКАЯ ВИЗУАЛЬНАЯ ПРОВЕРКА
Второй, более сложный, метод визуального тестирования — это аналитическая визуальная проверка.
При этом методе проверки вместо набора главных изображений оперативно создается сравнительное
изображение. Предполагается, что созданное изображение является визуально корректным, и оно
сравнивается с изображением, полученным во время тестирования. В данной схеме проверки
инженеры-тестировщики или разработчики должны обеспечить способ создания изображения-образца
— в идеале полностью независимый от пользовательского компонента. Создание генератора
изображений-образцов напрямую связано с деталями реализации пользовательского компонента, и в
зависимости от типа проверяемого содержимого требуются различные решения.
В некоторых случаях средство аналитической проверки может быть средством визуализации
изображения-образца. В других случаях обнаружение и проверку элементов в визуализированном
изображении выполняет система визуального распознавания. Например, она может подтвердить, что в
изображении есть синий прямоугольник определенного размера и положения или нечто подобное.
При визуальной проверке объектов Animation разработчик или инженер-тестировщик может создать
калькулятор ожидаемого значения. С помощью калькулятора инженер-тестировщик создаст
статическую версию анимированной сцены в определенный момент анимации, которая будет
изображением-образцом. Для проверки во время тестирования снимок экрана анимированной сцены
должен соответствовать статическому снимку экрана, созданному аналитическим способом.
При оперативном создании изображения-образца не возникает проблем, связанных с его проверкой и
различиями в платформах, разрешениях и др. Обладая более фундаментальными знаниями о
визуализируемой сцене, инженеры-тестировщики могут создавать маски для удаления частей сцены и
разрешать дополнительные отклонения в тех случаях, когда важен видеоадаптер или другое
оборудование. Аналитическая визуальная проверка более надежна, но предполагает затраты на
создание инструмента визуализации для аналитической проверки.
СРАВНЕНИЕ ОЖИДАЕМОГО ИЗОБРАЖЕНИЯ С РЕАЛЬНЫМ
На последнем этапе сравниваются два изображения. Наименее надежный вариант — прямое сравнение
изображений и констатация неудачи даже при различиях в один пиксель. Более эффективное решение
— допустить определенный уровень отклонения при сравнении изображений. Существуют различные
подходы к допуску отклонений, и выбор нужного зависит от масштаба и сложности требуемого
отклонения. В простом случае считается количество различающихся пикселей: при превышении
определенного процентного отношения тест считается непройденным. Добавив уровни сложности,
можно не только подсчитывать различающиеся пиксели, но и измерять цветовые различия пикселей с
учетом предельно допустимой кривой отклонений.
Более сложный подход — использовать предварительно заданные профили отклонений. По сути,
профили отклонений — это гистограммы на основе различий в пикселях. Например, профиль
отклонений может иметь следующий вид: «Не более 10 различий по одному пикселю, не более 2
различий по два пикселя, не более 0 различий по три и более последовательных пикселя». Тест
считается пройденным, если наблюдаемые различия ниже значений, заданных в профиле отклонений.
Для обеспечения максимальной гибкости и надежности набора тестов визуальной проверки
рекомендуется предусмотреть способ регулировки отклонений при сравнении.
ТЕСТИРОВАНИЕ МУЛЬТИМЕДИА
Проверка мультимедиа связана с рядом специфических проблем, обусловленных асинхронной
природой воспроизведения мультимедиа и скоростью обновления видеокадров во время
воспроизведения (обычно 30 кадров в секунду). Это означает, что для одноминутного видеоклипа
необходимо 1800 кадров (30 кадр/с × 60 с). Визуальную проверку точности кадра при воспроизведении
видео невозможно выполнить с помощью традиционного метода главного изображения, описанного в
разделе Тестирование методом визуальной проверки: это связано с большим количеством главных
изображений и сложностями захвата целевого кадра в видеозаписи.
С учетом этих проблем была разработана новая система проверки, помогающая достичь следующих
целей тестирования:





возможность проверки последовательности или числа видеокадров;
возможность проверки цветопередачи кадра;
возможность проверки точности и завершенности видеокадра;
возможность проверки видеокадра независимо от системного разрешения и размера
визуализируемого видео;
возможность проверки видео без использования главного изображения (сделать видео
самопроверяющимся).
Один из вариантов решения — создать пользовательское видео из последовательности составных
кадров (картинок, получаемых в результате наложения полей кадра). В каждом кадре
пользовательского видео содержится несколько декодируемых разделов — частей кадра. В данном
подходе захватываемый кадр (независимо от его типа) всегда содержит сведения, которые можно
декодировать в данные кадра, такие как номер кадра, ориентация кадра, содержимое кадра (для
проверки полноты и точности) и фактическая цветовая последовательность (для проверки
цветопередачи).
На рис. 4 показан пример составного кадра.
РИС. 4. СОСТАВНОЙ КАДР С ЧАСТЯМИ КАДРА
ЧАСТИ СОСТАВНОГО КАДРА
Составной кадр, показанный на рис. 4, состоит из следующих частей:

Часть ориентации кадра (в середине слева). Данная часть кадра состоит из двухбитового
шаблона и показывает ориентацию кадра. Порядок 1 (черный) и 0 (белый) указывает, что кадр




находится в горизонтальном положении. Порядок 0 — 1 означал бы, что кадр отображен по
вертикали.
Часть номера кадра (справа от части ориентации кадра). Эта часть содержит текущий номер
кадра в двоичной форме. Значение имеет вид 12-битового шаблона, состоящего из черных (1) и
белых (0) квадратов. Шаблон уникален для каждого кадра и основан на смещении номера кадра
от первого. Например, шаблон ББББББББЧБЧБ соответствует двоичному значению 000000001010
(в десятичном исчислении — десятому кадру). Двенадцать бит данных предоставляют сведения
о видео со скоростью 30 кадр/с с максимальной продолжительностью 2,27 мин (212 = 4096
кадров, 4096 кадров / 30 кадр/с = 136 с, 136 с = 2,27 мин). Обратите внимание, что обычно
тестовое видео длится не более 30 секунд.
Части сведений о кадре (справа от части номера кадра). Эти части содержат удобочитаемые
сведения о текущем кадре, такие как декодированные двоичные биты номера кадра,
ожидаемые значения цветовой последовательности и номер кадра в десятичной форме. Они
полезны при анализе в случае неудачного тестирования.
Часть цветовой палитры (в середине справа). Этот раздел состоит из четырех цветных
квадратов, соответствующих каналам RGB и альфа-каналам (альфа-канал позволяет полностью
или частично проверить прозрачность). Цветные квадраты могут отображаться в различной
последовательности (зависит от номера кадра). Во время проверки цвета из каждого квадрата
берется однопиксельная проба, преобразуемая в значение цвета, которое затем сравнивается с
ожидаемым цветом. Из-за потери данных во время кодировки и декодировки необходимо
установить значение отклонения.
Часть содержимого кадра (четыре угла кадра). Эта часть состоит из четырех идентичных
сегментов, расположенных в четырех углах составного кадра. Они служат для проверки четкости
кадра путем сравнения двух любых частей на предмет наличия визуальных дефектов. Из-за
потери данных во время кодировки и декодировки видео сегменты могут несколько отличаться.
Для учета этих различий используется значение отклонения.
При выполнении проверки с помощью составных кадров инженерам-тестировщикам не требуются
главные изображения: каждый кадр видео содержит все сведения, необходимые для его проверки,
включая цветовой бит для полной или частичной проверки прозрачности. Кроме того, проверка может
выполняться независимо от разрешения видео и количества точек на дюйм, поскольку в вычислениях
на основе частей кадра используются процентные, а не абсолютные значения. С помощью этой
методологии инженер может проверить скорость воспроизведения видео, сравнивая ее с ожидаемым
номером кадра.
ПРОВЕРКА АНИМАЦИИ И ДРУГИХ ПЕРЕХОДОВ
Параметры, используемые в процессе добавления анимации, могут влиять на ее тестирование и
проверку. В этом разделе описываются распространенные методы проверки анимации, а также
параметры проектирования, которые упрощают ее тестирование. Дополнительные сведения об
анимации см. в статье Общие сведения об эффектах анимации в разделе WPF веб-сайта MSDN.
СПОСОБЫ ПРИМЕНЕНИЯ АНИМАЦИИ
Существует три способа анимирования содержимого в WPF: с помощью только XAML, только кода, а
также комбинации XAML и кода. При использовании подходов «только XAML» и «XAML и код»
создаются структуры раскадровки, вызываемые в ответ на триггер. В XAML-анимации триггеры можно
задавать с помощью атрибутов EventTrigger, PropertyTrigger (триггеры, используемые внутри стилей)
и DataTrigger. В анимациях, созданных с помощью XAML и кода, отдельные раскадровки можно
вызывать по необходимости вне вызова RoutedEvent с помощью элемента BeginStoryboard или иными
способами. Кроме того, раскадровки могут управляться интерактивно.
Существует несколько различных вариантов создания и добавления анимации с помощью кода.
Раскадровки могут создаваться и применяться аналогично подходу «XAML и код»: либо с помощью кода
создаются триггеры, либо методы BeginStoryboard или Storyboard.Begin вызываются напрямую.
Помимо метода раскадровки, можно создать и напрямую добавить к парам
DependencyObject/DependencyProperty (DO/DP) целые интерактивные деревья часов. Такой подход
часто оказывается проще раскадровки, поскольку разработчик может применить анимацию в виде
объекта Animation или Clock непосредственно к паре DO/DP, не создавая объекты PropertyPath,
означающие анимацию свойства. Однако в этом случае разработчик должен начать или контролировать
интерактивные аспекты анимации.
В следующем примере кода показана XAML-анимация.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowTitle="Fading Rectangle Example">
<StackPanel Margin="10">
<Rectangle Name="MyRectangle" Width="100" Height="100" Fill="Blue">
<Rectangle.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</StackPanel>
</Page>
В следующем примере кода показано создание анимации с помощью методов BeginAnimation и
ApplyAnimationClock.
using
using
using
using
using
using
System;
System.Windows;
System.Windows.Controls;
System.Windows.Media;
System.Windows.Shapes;
System.Windows.Media.Animation;
namespace Microsoft.Samples.Animation.TimingBehaviors
{
public class AnimationClockExample : Page
{
ScaleTransform myScaleTransform;
public AnimationClockExample()
{
this.WindowTitle = "Opacity Animation Example";
this.Background = Brushes.White;
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(20);
// Create a button that with a ScaleTransform object.
// The ScaleTransform object animates when the
// button is clicked.
Button myButton = new Button();
myButton.Margin = new Thickness(50);
myButton.HorizontalAlignment = HorizontalAlignment.Left;
myButton.Content = "Animate";
myScaleTransform = new ScaleTransform(1,1);
myButton.RenderTransform = myScaleTransform;
// Associate an event handler with the
// button's Click event.
myButton.Click += new RoutedEventHandler(myButton_Clicked);
myStackPanel.Children.Add(myButton);
this.Content = myStackPanel;
}
// Create and apply and animation when the button is clicked.
private void myButton_Clicked(object sender, RoutedEventArgs e)
{
// Create a DoubleAnimation instance to animate the
// ScaleTransform object.
DoubleAnimation myAnimation =
new DoubleAnimation(
1, // "From" value
5, // "To" value
new Duration(TimeSpan.FromSeconds(5))
);
myAnimation.AutoReverse = true;
// Create a clock for the animation.
AnimationClock myClock = myAnimation.CreateClock();
// Associate the clock's ScaleX and
// ScaleY properties of the button's
// ScaleTransform object.
myScaleTransform.ApplyAnimationClock(
ScaleTransform.ScaleXProperty, myClock);
myScaleTransform.ApplyAnimationClock(
ScaleTransform.ScaleYProperty, myClock);
}
}
}
СПОСОБЫ ТЕСТИРОВАНИЯ АНИМАЦИИ
Знание способов тестирования анимации может помочь разработчикам эффективно применять
анимации к пользовательскому коду. Предположим, что анимация уже создана и добавлена. Убедиться
в том, что она выполняется заданным образом, поможет один из трех различных способов проверки:
1. периодические снимки экрана или сравнения значений;
2. снимки экрана с проверкой значения при завершении;
3. проверка полных значений.
ПЕРИОДИЧЕСКИЕ СНИМКИ ЭКРАНА ИЛИ СРАВНЕНИЯ ЗНАЧЕНИЙ
Анимация — это просто функция, описывающая изменение с течением времени. Поэтому самый
основной метод проверки — это проверка объема изменений, произошедших в заданный промежуток
времени. Чтобы выполнить визуальную проверку, можно сделать снимки экрана и сравнить их с
предыдущими снимками на предмет наличия изменений. Чтобы сравнить значения, инженерытестировщики могут воспользоваться значениями, возвращенными свойством, к которому применяется
анимация, или самой анимацией.
Проверка наличия изменений — это самый простой метод проверки анимации, но для увеличения его
надежности требуются определенные знания о проверяемой анимации. Вот некоторые предпосылки
для использования этого метода:



Знание о том, когда начинается или заканчивается анимация, а также о ее ожидаемой
продолжительности (если анимация не повторяющаяся). Очевидно, что проверка коэффициента
изменения в то время, когда анимация активно не выполняется или уже закончилась, не
покажет никаких изменений. Чтобы проверка была надежной, разработчики, добавлявшие
анимацию, должны предоставить средство получения этой информации.
При проверке периодических значений требуется средство получения анимации (путем вызова
GetCurrentValue) или анимируемого свойства DependencyProperty: только при его наличии
можно получить текущее значение анимации.
В идеале текущий ход выполнения анимации предоставляется в виде значения только для
чтения, чтобы обеспечить проверку анимации. Однако свойства BeginTime и Duration могут
помочь определить, закончилась ли анимация. Кроме того, эти предоставленные значения
позволяют при необходимости провести проверку полных значений.
СНИМКИ ЭКРАНА С ПРОВЕРКОЙ ЗНАЧЕНИЯ ПРИ ЗАВЕРШЕНИИ
Помимо проверки на основе снимков экрана, инженеры-тестировщики могут добавить дополнительную
точку проверки, чтобы убедиться: анимация не только выполняется, но и завершается с ожидаемым
значением. Если инженеры-тестировщики знакомы с анимацией, они могут логически вывести ее
конечное значение, не реализуя полностью калькулятор ожидаемых значений. В случае с наиболее
распространенными типами анимации (From-To, To и From-By) инженеры-тестировщики могут без труда
определить ее конечное значение. У анимации типов From-To и To конечное значение должно быть
равно значению, указанному в свойстве To данной анимации. У анимации типа From-By конечное
значение должно быть равно значению By, добавленному непосредственно к значению From. Это
простое вычисление быстро становится достаточно сложным, если заданы свойства AutoReverse или
RepeatCount, при этом значение IsAdditive или IsCumulative равно true.
У наиболее распространенных типов анимации (From-To и To) результат вычисления конечного
значения всегда будет равен значению To независимо от значений repeatCount и IsAdditive или
IsCumulative. Однако для параметра AutoReverse требуется другое вычисление. У анимации типа
From-To, значение AutoReverse которой равно true, конечное значение всегда будет равно значению
From. У анимации типа To конечное значение возвращается к исходному значению свойства
DependencyProperty перед применением анимации. Очевидно, что с повышением сложности
применяемой анимации увеличиваются и трудности с вычислением конечного значения.
При наличии одной точки проверки при завершении часто удобнее жестко закодировать в тесте
ожидаемое значение (если оно известно). В этом случае не придется тратить время и силы на
реализацию калькулятора конечных значений.
По мере усложнения тестов анимации инженерам-тестировщикам требуется все больше сведений об
анимации и объекте, к которому она применяется. Лишь при наличии подробных сведений они смогут
надлежащим образом проверить ход выполнения анимации. Чтобы вычислить конечное значение при
завершении, инженерам-тестировщикам необходим доступ практически ко всем свойствам анимации,
таким как From, To, By, AutoReverse, BeginTime, Duration и, по возможности, IsAdditive или
IsCumulative.
Для проверки на основе снимков экрана или конечного значения инженеры-тестировщики могут
получить нужные сведения из шаблона Animation, используемого для анимации. Каждый объект
AnimationTimeline используется внутренне для создания отдельного экземпляра AnimationClock,
поэтому при предоставлении фактической анимации предоставляется только шаблон. Если разработчик
разрешает доступ для чтения к шаблону анимации, инженер-тестировщик может получить все
необходимые сведения, чтобы вычислить конечное значение и убедиться в выполнении анимации.
ПРОВЕРКА ПОЛНЫХ ЗНАЧЕНИЙ
Для проверки полных значений анимации инженерам-тестировщикам требуется либо результат
выполнения метода GetCurrentValue, либо значение GetValue свойства DependencyProperty
анимируемого объекта. При использовании метода GetCurrentValue исходное значение инженерытестировщики могут получить с помощью метода GetAnimationBaseValue объектов UIElement или
Animatable. Конечное значение не используется для определения текущего значения анимации в
распространенных типах анимации From-To, To и By — оно используется только для анимации типа
From. Чтобы пользоваться методом GetValue объекта DependencyObject, инженерам-тестировщикам
необходим доступ к анимируемому объекту DependencyObject.
Метод получения анимированного значения определяется в зависимости от внутреннего анимируемого
объекта и возможности предоставить объект DependencyObject для целей тестирования. Если имеется
несколько внутренних объектов и разработчики хотели бы ограничить их предоставление, то проще
всего предоставить результат метода GetCurrentValue. Если анимация выполняется на уже
предоставленном компоненте, рекомендуется использовать метод GetValue.
Для проверки полных значений инженерам-тестировщикам необходимо значение CurrentProgress
всех нуждающихся в тестировании тактов анимации. На основе значения CurrentProgress
вычисляется ожидаемое значение анимации. Значение CurrentProgress можно также вычислить на
основе свойств шаблона анимации и текущего времени, прошедшего с момента запуска приложения.
Для этого применяется, например, следующее вычисление:
CurrentProgress = (CurrentTime – BeginTime) % Duration
Чтобы вычислить ожидаемые значения анимации, инженеры-тестировщики должны определить
диапазон анимации и умножить его на ход выполнения. Для каждого типа анимации применяется своя
вычислительная функция, как показано в следующем списке:

(FromTo) currentValue = From + (To – From) * currentProgress




(To) currentValue = DO.BaseValue + (To – DO.BaseValue) *
currentProgress
(FromBy) currentValue = From + By * currentProgress
(By) currentValue = DO.BaseValue + By * currentProgress
(From) currentValue = DO.BaseValue - From * (1 – currentProgress)
Значение CurrentProgress обычно находится в диапазоне от 0 до 1. Однако в случае с
повторяющейся анимацией это значение будет увеличиваться при каждом повторении. Например, при
первом проходе анимации диапазон выполнения будет находиться в пределах от 1 до 2, при
последующем проходе (первое повторение) — от 2 до 3 и т. д. Для всех типов анимации, в которых не
заданы значения IsCumulative или IsAdditive, при выполнении вышеприведенных вычислений
следует считать, что значение CurrentProgress находится в диапазоне от 0 до 1. Анимация, параметр
AutoReverse которой имеет значение true, будет выполняться от 0 до 1, а затем снова до 0.
Проверка анимаций, заданных со значениями Repeat, AutoReverse и IsCumulative или IsAdditive,
— это более сложная процедура, которая в данном документе не описывается. Объединение анимаций
с помощью свойств ClockGroup или SnapShotAndReplace и Compose HandoffBehavior еще больше
усложняет вычисления. В целом в составных анимациях важен порядок, в котором они обрабатываются
(порядок их применения или добавления в группу или к триггерам и др.). Вычисленное значение
каждой конкретной анимации передается следующей анимации в виде обновленного свойства
BaseValue. В случае с несколькими составными или взаимодействующими анимациями проще всего
проверять наличие последовательных изменений, периодически делая снимки экрана или проверяя
значения.
API АНИМАЦИИ, ВЛИЯЮЩИЕ НА ХОД ВЫПОЛНЕНИЯ
На вычисление хода выполнения анимации влияют следующие свойства и методы анимации:



Свойство Repeat. Значение CurrentProgress увеличивается с каждым новым повтором. При
первом проходе анимации оно увеличивается от 0 до 1. При первом повторе значение
увеличивается от 1 до 2 и т. д. В случае с неаддитивными или кумулятивными анимациями
следует считать, что значение CurrentProgress увеличивается только от 0 до 1.
Свойство AutoReverse. При автореверсе значение CurrentProgress возвращается в начальную
точку. Например, значение хода выполнения увеличивается от 0 до 1 и затем возвращается к 0,
увеличивается от 1 до 2 и возвращается к 1 и т. д.
Методы Seek, Pause и Resume. В процессе поиска значение CurrentProgress обновляется до
указанной точки в следующем такте. При установке параметра SeekAlignedToLastTick
выполняется поиск до указанной позиции, начиная с текущего такта. Состояние паузы и
возобновления можно проверить с помощью свойства IsPaused экземпляра AnimationClock.
РЕКОМЕНДАЦИИ ДЛЯ РАЗРАБОТЧИКА И ИНЖЕНЕРА-ТЕСТИРОВЩИКА
В зависимости от требуемого типа проверки анимации разработчики могут адаптировать
предоставление элементов анимации пользовательских компонентов. Для простой проверки
инженеры-тестировщики могут периодически делать снимки экрана и сравнивать их, чтобы обнаружить
изменения с помощью средств захвата снимков экрана и сравнения изображений. В случае с
анимациями, вызываемыми внутри компонента, процесс захвата можно начинать после вызова
анимации. Проверку внешних анимаций можно начать в любое время.
Для более сложной проверки компоненты должны предоставить больше информации. Для
определения конечного значения анимации следует предоставить шаблон анимации, из которого
инженеры-тестировщики могут получить необходимые для этой операции значения свойств анимации.
Если предоставление шаблона анимации невозможно, то ожидаемое значение следует жестко
закодировать в тесте.
Чем сложнее схема проверки, тем больше сведений необходимо предоставить. Как минимум,
инженеру-тестировщику требуется пара DependencyObject/DependencyProperty (DO/DP) для
каждой применяемой анимации, либо текущий результат значения GetValue, а также доступ к
значению CurrentProgress экземпляра AnimationClock. Чтобы предоставить экземпляры
AnimationClock, вызовы BeginAnimation следует заменить на вызовы ApplyAnimationClock для
всех пар DO/DP. Для объектов Storyboard может использоваться метод Storyboard.CreateClock.
Уровень предоставления, который разработчик встраивает в компонент, определяет уровень проверки
анимации, который может реализовать инженер-тестировщик. Для простых анимаций типов From-To, To
или By предоставление пары DO/DP (или даже просто результата GetValue) и значения
CurrentProgress тактов анимации имеет наибольшую ценность, обеспечивая инженерутестировщику полную свободу и возможность проверять анимацию любыми способами. Требуемый
уровень проверки анимации должен определять уровень предоставления внутренних компонентов.
Однако в большинстве случаев простые периодические снимки экрана могут быть вполне
достаточными, чтобы удостовериться в нормальной работе анимации.
ОТСУТСТВИЕ ДОСТУПА К АНИМАЦИИ
Если в анимации не предоставляется достаточных сведений для подробного тестирования, инженерытестировщики все же могут выполнить некоторые тесты. Периодически создавая снимки экрана для
проверки изменений, они по-прежнему могут удостовериться в том, что анимация была применена и
выполняется. Изменения в ходе выполнения анимации отражаются и в выходных данных метода
DependencyProperty.GetValue.
ТЕСТИРОВАНИЕ АНИМАЦИЙ, ВЗАИМОДЕЙСТВУЮЩИХ С БАЗОВЫМИ ЗНАЧЕНИЯМИ И
FILLBEHAVIOR
Еще один фактор, который следует учитывать во время тестирования анимации, — это взаимодействие
дополнительных анимаций, которое может применяться к коду или компоненту. Разработчики должны
помнить, что к пользовательскому компоненту можно применять дополнительные анимации и что
анимации, вызываемые из разных уровней, компонуются в одну. Анимации WPF компонуются в
порядке их применения, а значит, приложение может иногда работать не так, как ожидают конечные
пользователи.
Например, при поведении заполнения, по умолчанию присущем свойству HoldEnd, любая анимация,
применяемая к свойству, продолжает влиять на свойство даже после своего окончания. Если внутренняя
анимация From-To применяется к свойству Width пользовательского компонента, у которого значение
FillBehavior по умолчанию равно HoldEnd, то по завершении анимации пользователь не может
изменить свойство Width. Независимо от указанного базового значения часть анимации To всегда
остается в удерживаемом значении. Разработчики могут указать, что значение FillBehavior равно
Stop: в этом случае анимация при завершении отделяется и результаты значения возвращаются к
базовому значению. Обычно это не самое желательное поведение, особенно для анимаций без
автореверса. Поэтому обычно анимация остается в конечном значении, не блокируя при этом
изменения. Этого можно достичь путем обработки события Completed. В обработчике событий нужно
заменить базовое значение новым, а затем отделить анимацию, как показано в следующем примере
кода:
someAnimation.Completed += delegate
{
yourObject.yourDP = someAnimation.To;
// Calling BeginAnimation with null removes any existing animations.
yourObject.BeginAnimation(yourObject.yourDPProperty,null);
}
Любые тесты, проверяющие это поведение, должны определить, по-прежнему ли применяется
анимация. Если у анимаций From-To, From-By и To свойство FillBehavior имеет значение по
умолчанию, то при задании базового значения после завершения анимации значение GetValue не
изменяется. У анимаций типа By метод GetValue всегда возвращает анимированное значение плюс
значение By (в сущности, он возвращает все что угодно, только не примененное базовое значение).
Поэтому проверку можно выполнить, не располагая никакими сведениями о заданной анимации. Если
инженер-тестировщик может гарантировать, что внутренние анимации не будут влиять на другие
анимации, компонент будет хорошо взаимодействовать с этими дополнительными анимациями.
ТЕСТИРОВАНИЕ АНИМАЦИЙ, ВЗАИМОДЕЙСТВУЮЩИХ С ВНЕШНИМИ ТРИГГЕРАМИ
Чтобы проверить налаженность взаимодействия внутренних анимаций с вызванными, можно
применить сходную методологию тестирования. Если внутренняя анимация удаляется после
завершения и заменяет конечное значение, то любые внешние анимации, вызванные впоследствии,
могут легко анимировать это значение. Внутренняя анимация, примененная вне уровня триггера,
вычисляется перед ним и не прерывается внешне примененным триггером.
РЕКОМЕНДАЦИИ ПО АНИМАЦИЯМ
Сведения о рекомендациях по созданию анимаций см. в статье Советы и рекомендации по анимации в
разделе WPF веб-сайта MSDN.
ПРИМЕРЫ АНИМАЦИЙ
Примеры анимаций WPF можно найти на веб-сайте MSDN в следующих статьях:




Общие сведения об эффектах анимации.
Коллекция примеров анимации. В этом примере показано, как анимировать разнообразные
объекты, включать текст, двухмерные и трехмерные преобразования. В нем также
демонстрируются интерполяция сплайнами, анимации по траекториям и пользовательские
анимации.
Общие сведения об анимации и системе управления временем.
Практическое руководство. Анимирование свойства с помощью раскадровки (класс Storyboard).
ТЕСТИРОВАНИЕ ГРАФИКИ И ТРЕХМЕРНОГО СОДЕРЖИМОГО
Будет рассмотрено в следующих выпусках.
ТЕСТИРОВАНИЕ API И МОДУЛЬНОЕ ТЕСТИРОВАНИЕ
Будет рассмотрено в следующих выпусках.
ТЕСТИРОВАНИЕ ПРОИЗВОДИТЕЛЬНОСТИ И МАСШТАБИРУЕМОСТИ
Тестирование производительности позволяет определить, насколько быстро система работает при
определенной рабочей нагрузке. Оно также служит для проверки других атрибутов системы, таких как
масштабируемость, надежность и использование ресурсов. При тестировании масштабируемости
выясняется, насколько быстро приложение реагирует на повышение и понижение нагрузки.
Примечание. В этом выпуске документа приводятся ссылки на рекомендации по разработке,
позволяющие улучшить производительности приложений WPF. Рекомендации по тестированию
производительности и масштабируемости будут освещены в одном из следующих выпусков.
РЕКОМЕНДАЦИИ И СПРАВОЧНЫЕ МАТЕРИАЛЫ ПО РАЗВЕРТЫВАНИЮ
Рекомендации по разработке для WPF можно найти на веб-сайте MSDN в следующих статьях:


Улучшение производительности приложений WPF (статья).
Improving Scrolling Performance in Windows Presentation Foundation (загружаемый
технический документ).
В следующих записях блогов можно найти дополнительные сведения по данной теме:






Maximizing WPF 3D Performance on Tier-2 Hardware.
Finding Memory Leaks in WPF-based Applications, автор Джоссеф Гольдберг (Jossef
Goldberg), руководитель программы в команде WPF Performance.
Performance Improvements in WPF in .NET 3.5 / 3.0 SP1.
What's New for Performance in WPF in .NET 3.5 SP1.
Improving WPF Applications Startup Time.
Splash Screen to Improve WPF Application Perceived Cold Startup Performance.
РЕКОМЕНДАЦИИ ПО ТЕСТИРОВАНИЮ
Будет рассмотрено в одном из следующих выпусков.
ТЕСТИРОВАНИЕ БЕЗОПАСНОСТИ
Тестирование безопасности помогает определить, насколько хорошо система или приложение
защищены от несанкционированного доступа и подделки данных или кода. Тестирование безопасности
позволяет определить дефекты ПО, которые могут привести к нарушениям безопасности, а также
проверить эффективность мер безопасности.
Проблемы, на решение которых направлено тестирование безопасности, известны под общим
названием STRIDE: спуфинг, подделка, отказ, раскрытие информации, отказ в обслуживании и
несанкционированное получение прав. Сведения о каждой из этих категорий см. в записи блога Threat
Modeling Again, STRIDE Ларри Остермана (Larry Osterman).
РЕКОМЕНДАЦИИ ПО РАЗРАБОТКЕ ЗАЩИЩЕННЫХ ПРИЛОЖЕНИЙ WPF
Рекомендации по разработке защищенных приложений WPF можно найти на веб-сайте MSDN в
следующих статьях:

Сведения об общей безопасности управляемого кода см. в статье Patterns and Practices Security
Guidance for Applications.

Сведения об управлении доступом для кода (CAS) см. в статье Code Access Security.

Сведения о безопасности и ClickOnce см. в статье Обзор развертывания ClickOnce.

Сведения о моделировании угроз см. в статье Threat Modeling.

Сведения о безопасности в WPF см. в статье Безопасность частичного доверия Windows
Presentation Foundation.
Сведения о модели безопасности в модели автоматизации пользовательского интерфейса см. в
статье Общие сведения о безопасности модели автоматизации пользовательского интерфейса.

РЕКОМЕНДАЦИИ ПО ТЕСТИРОВАНИЮ
Общий подход к тестированию безопасности в любой области — это задать вопрос: «К чему
злоумышленник не должен получить доступ?» Например, если приложению разрешено чтение любого
файла на жестком диске компьютера, хакеры могут воспользоваться этим, чтобы украсть персональные
данные или найти достаточно сведений, чтобы нарушить конфиденциальность компьютера.
Любые входные данные, поступающие извне (например, от пользователя, из системных файлов,
разделов реестра или Интернета), должны тщательно проверяться, чтобы убедиться в невозможности
их подделки, либо надлежащим образом тестироваться, чтобы принимались только допустимые
данные.
МОДЕЛИРОВАНИЕ УГРОЗ
В ходе моделирования угроз возможность исследуется на предмет того, какие угрозы безопасности
представляют для нее риск, а также определяются методы подавления этих угроз. Команда разработки
должна создать модель угроз для областей, в которых могут возникнуть проблемы безопасности.
Инженеры-тестировщики должны понимать модель угроз, стараться предусмотреть возможные угрозы,
не включенные в эту модель, и тестировать наличие всех описанных способов предотвращения
нарушений безопасности.
При тестировании частично доверенных приложений .NET Framework, таких как приложения .xbap,
инженеры-тестировщики должны руководствоваться следующими рекомендациями:


Не следует использовать обходные пути, чтобы достичь полного доверия изнутри приложения
.xbap. Распространенный способ внедрения этого обходного пути — поместить сборку с полным
доверием в глобальный кэш сборок и задать выполнение с помощью этой сборки операций с
повышенным доверием. Этот пользовательский сценарий не является реалистичным, и его
следует избегать во всех случаях, кроме тех, когда такие операции не связаны с тестируемыми
сценариями.
При выполнение тестов в Windows Vista следует учитывать уровень повышения прав
конкретного процесса. Ошибки, связанные с безопасностью (и не только), могут не проявляться
при выполнении теста из процесса с более высоким уровнем привилегий. По возможности
инженеры-тестировщики должны выполнять применимые сценарии в Windows Vista как в виде
процессов с ограниченными, так и повышенными привилегиями.
ТЕСТИРОВАНИЕ ГЛОБАЛИЗАЦИИ И ЛОКАЛИЗАЦИИ
В данный раздел включены следующие темы:






Основные понятия глобализации и локализации.
Рекомендации по глобализации приложений WPF.
Создание в WPF локализуемых макетов пользовательского интерфейса.
Подходы к локализации приложений WPF.
Последовательность операций процесса локализации BAML.
Дополнительные ресурсы.
Основные понятия глобализации и локализации
В следующей таблице содержатся определения терминов и сводные данные о базовых понятиях,
связанных с тестирование глобализации и локализации.
Термин
Описание
Глобализация
Процесс проектирования и разработки программного продукта,
работающего в различных культурах и языковых стандартах
Интернационализация
Термин, используемый за пределами Microsoft, для обозначения
глобализации и локализуемости
Локализуемость
Проект программной базы кода и ресурсов, разработанный таким
образом, что программа может быть выпущена на различных языках
без изменения исходного кода
Локализация
Процесс адаптации глобализованного приложения, которое уже
проверено на локализуемость, к определенной культуре и языковому
стандарту. Процесс локализации включает перевод
пользовательского интерфейса приложения или адаптацию графики к
определенной культуре или языку
Псевдолокализация
Процесс имитации локализации путем расширения или заполнения
английских строковых ресурсов не-ASCII-символами. Эта процедура
входит в процесс тестирования на локализуемость
Культура и язык
пользовательского интерфейса
Язык, на котором в операционной системе отображаются меню,
файлы справки и диалоговые окна. Этот параметр определяет выбор
набора ресурсов
Текущая культура и
региональные параметры
пользователя
Набор правил и данных для конкретного языка и географического
региона. Региональные параметры пользователя, представленные
параметром CurrentCulture в .NET Framework, включают сведения о
правилах сортировки, формате даты и времени, числовых и
денежных преобразованиях, а также классификации символов
Инвариантная культура
Значение культуры, передаваемое учитывающим культуру методам
(таким как string.Compare), чтобы обеспечить единое поведение
независимо от параметров системы или версии операционной
системы. Инвариантная культура должна использоваться только
процессами, которым требуются независимые от культуры и языка
результаты, например, системными службами. В иных случаях
применение этого значения может привести к тому, что результаты
будут лингвистически некорректными или не соответствующими
культуре
Язык системы
Определяет, какой набор символов применяется для приложений, не
поддерживающих Юникод. Этот языковой стандарт, как видно из
приложений, эмулируется самой системой. Поэтому управляемый
код не должен зависеть от языка системы
Следующий рисунок иллюстрирует отношения между понятиями, перечисленными в предыдущей
таблице.
РИС. 5. ПОНЯТИЯ ГЛОБАЛИЗАЦИИ И ЛОКАЛИЗАЦИИ
Рекомендации по глобализации приложений WPF
Рекомендации по разработке глобализованных приложений WPF, в сущности, мало чем отличаются от
рекомендаций по разработке любых глобализованных приложений (за исключением некоторых
аспектов разработки приложений .NET Framework и WPF). Все эти рекомендации сосредоточены вокруг
трех основных процессов, необходимых для создания международных приложений: глобализации,
проектирования с учетом необходимости локализации и самой локализации.
Прежде всего, разработчику следует посетить веб-сайт Microsoft World Ready Guide — универсальный
справочный ресурс для всех этапов проектирования и тестирования международных приложений. В
этом руководстве рассматриваются следующие темы:

Testing for World-Readiness Overview и World-Ready Approach to Testing — вводные разделы по
данной теме.



Globalization of the Test.
Localizability Testing.
Localization Testing.
В руководстве World-Ready Guide также предлагаются несколько примеров тестовых случаев по
глобализации и локализуемости. В этих примерах хорошо представлены области тестирования
глобализации для развертывания и общей функциональности, обработки текста и учета языка. Данные
примеры доступны на странице Sample International Test Cases пошагового руководства.
Сведения о глобализации и локализации в .NET Framework см. на странице Глобализация и локализация
приложений на веб-сайте MSDN, на которой есть ссылка на отличную статью — Рекомендации по
разработке международных приложений. Ознакомившись с данными рекомендациями по .NET
Framework, вернитесь на веб-сайт MSDN к статье WPF Глобализация и локализация, содержащей ссылку
на подробную статью Общие сведения о глобализации и локализации WPF.
НЕКОТОРЫЕ АСПЕКТЫ ТЕСТИРОВАНИЯ ПРИЛОЖЕНИЙ WPF
В этом разделе приводятся сведения об общих проблемах тестирования глобализации в приложениях
WPF.
ТЕСТИРОВАНИЕ РАЗВЕРТЫВАНИЯ ГЛОБАЛИЗОВАННЫХ ПРИЛОЖЕНИЙ
Проводите тестирование на правильно выбранной платформе. Приложения WPF могут выполняться на
различных платформах. Если приложение предназначено для нескольких платформ, его развертывание
и функциональность должны быть единообразны. В локализованных операционных системах могут
быть локализованные имена учетных записей, системных папок, другой набор шрифтов и различные
методы ввода данных.
Приведем несколько примеров переменных платформ, которые следует учитывать при развертывании:



развертывание на Windows XP и развертывание на Windows Vista;
развертывание на локализованных версиях операционной системы;
развертывание на англоязычных операционных системах с установленным многоязыковым
интерфейсом пользователя.
Убедитесь, что приложения создаются корректно и могут развертываться и выполняться в различных
языковых средах. Распространенная проблема при создании глобализованного приложения —
незаданное свойство UltimateResourceFallback в файле AssemblyInfo при заданном свойстве UICulture в
файле проекта. При незаданном базовом языке приложение может функционировать только в
одноязыковой среде и прекращать работу при выполнении на другом языке. (Данные параметры
описываются в этом документе ниже.)
ТЕСТИРОВАНИЕ ОБЩЕЙ ФУНКЦИОНАЛЬНОСТИ
Выберите надлежащую среду тестирования для используемой платформы.

Региональные параметры пользователя системы (представленные в WPF классом
CurrentCulture) — это важная переменная в тестировании приложений WPF. Данная переменная
влияет на сортировку, формат даты, вид календаря, формат валюты и другие операции, важные
для многих приложений. При установке в Windows региональных параметров пользователя для
другого языка среда тестирования становится идеальной средой для поиска проблем. Особенно
это касается случаев, когда выбирается язык, с которым связаны особые проблемы для
приложений, такие как сортировка с турецкой буквой i или использование разделителей в
европейских языках.


Манипулирование региональными параметрами пользователя также помогает обнаружить
некорректное использование класса CultureInfo в проекте приложения. В таких операциях, как
синтаксический анализ, внутренняя сортировка и выбор регистра, InvariantCulture передается в
качестве параметра культуры вместо CurrentCulture. (CurrentCulture передается только в случае,
когда приложение выводит какие-то данные на экран.) При некорректном использовании
параметра InvariantCulture изменение региональных параметров пользователя операционной
системы часто приводит к сбою приложения.
Изменение языка системы обычно не влияет на тестирование приложений WPF, кроме случаев,
когда тестируемое приложение взаимодействует с данными, не поддерживающими Юникод.
ТЕСТИРОВАНИЕ ОБРАБОТКИ ТЕКСТА И ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
Обратите особое внимание на раздел xml:lang, поскольку атрибут xml:lang (или свойство Language)
отвечает за обработку международного текста в пользовательском интерфейсе. Разработчики должны
обязательно добавлять атрибут xml:lang, который используется в приложениях WPF для следующих
целей:



Задание шрифта для кодовых позиций Юникода в составном шрифте. Это критически важный
аспект для языков, у которых общие кодовые позиции, отображаемые с помощью различных
глифов (такие как японский, корейский, китайский языки).
Определение замены цифр для таких языков, как арабский.
Определение языка проверки правописания и расстановки переносов в тексте.
Дополнительные сведения о тестировании обработки текста и пользовательского интерфейса
приводятся в следующем разделе.
Создание в WPF локализуемых макетов пользовательского интерфейса
Для успешной локализации приложения WPF необходимо убедиться, что его пользовательский
интерфейс сможет адаптироваться к новым ресурсам после завершения локализации. Способы
достижения этой цели на платформе WPF аналогичны тем, что применяются для других технологий
представления: например, не следует использовать в локализуемых строках элементы управления с
фиксированной шириной. Однако в WPF реализована расширенная поддержка автоматической
разметки, поэтому при локализации приложений WPF в них не требуется вносить много изменений,
чтобы добиться нормального отображения и работы пользовательского интерфейса с локализованным
содержимым.
В целом при создании локализуемых пользовательских интерфейсов в WPF рекомендуется учитывать
следующее:


Пользовательский интерфейс лучше создавать на языке XAML, избегая кода. Интерфейс,
созданный с помощью XAML, автоматически задействует встроенные API локализации.
Не рекомендуется применять абсолютные положения и фиксированные размеры при
компоновке содержимого. Вместо этого лучше использовать относительные или автоматические
размеры, в том числе:
 применять свойство SizeToContent и устанавливать значения ширины и высоты равными
Auto;
 не применять при компоновке пользовательских интерфейсов элемент Canvas;
использовать элемент управления Grid и его возможность общих размеров.
На полях необходимо оставлять дополнительное пространство, поскольку для локализованного
текста часто требуется больше места. Это пространство позволяет вместить выступающие за
конец строки символы.
Чтобы избежать обрезки текста, следует включить свойство TextWrapping класса TextBlock.
Обязательно задавайте атрибут xml:lang. Этот атрибут описывает культуру конкретного элемента
и его дочерних элементов. Значение данного свойства в WPF изменяет поведение нескольких
возможностей, таких как расстановка переносов, проверка орфографии, замена формата чисел,
оформление сложных знаков и резервные шрифты. Дополнительные сведения см. в статье
Обработка xml:lang в XAML на веб-сайте MSDN.
Создавайте настраиваемые составные шрифты, чтобы улучшить управление шрифтами,
используемыми для различных языков. По умолчанию в WPF используется шрифт
GlobalUserInterface.composite в каталоге Windows\Fonts. Дополнительные сведения о составных
шрифтах см. в разделе «Составные шрифты» статьи FontFamily — класс на веб-сайте MSDN.
При проектировании навигации в приложениях, в которых при локализации текст может
отображаться справа налево, следует явно задать свойство FlowDirection каждой страницы,
чтобы страница не наследовала параметр FlowDirection от объекта NavigationWindow.
При создании приложений навигации, размещенных вне браузера, свойство StartupUri для
начального приложения должно иметь значение NavigationWindow вместо страницы. Например,
выполните следующую настройку:







<Application StartupUri="NavigationWindow.xaml">
Это позволяет изменить свойство FlowDirection окна и панели навигации.
Дополнительные сведения см. в статье Пример создания локализованной домашней
страницы на веб-сайте MSDN.
Помимо рекомендаций, приведенных в предыдущем списке, при создании международных
приложений WPF необходимо учитывать следующее:




Свойство FlowDirection должно быть явно задано только для элементов, всегда сохраняющих
статическое направление. Направление других элементов определяется локализацией.
Исключение — класс Image, не наследующий значение FlowDirection от родительского
элемента.
Если наследование свойства не применяется (например, в случае с экземпляром HWND
взаимодействия), следует явно задать значение свойства FlowDirection равным RightToLeft.
При возможности всегда используйте элементы управления DockPanel и StackPanel.
Не указывайте сведения экземпляра Font, такие как имя шрифта и размер шрифта, кроме
случаев, когда в пользовательском интерфейсе требуется конкретный шрифт и когда это
необходимое условие для работы приложения. В некоторых языках может отсутствовать
сопоставление для указанного шрифта, поэтому при указании сведений экземпляра Font
локализаторам придется выполнять дополнительную адаптацию. Если шрифт в
пользовательском интерфейсе не указан, в WPF по умолчанию используется шрифт
GlobalUserInterface.composite, в котором доступен механизм резервных шрифтов для
отображения текста на любом языке. Если этого механизма для приложения недостаточно, его
можно дополнить составным шрифтом.
НЕКОТОРЫЕ АСПЕКТЫ ТЕСТИРОВАНИЯ
В нижеприведенном списке содержится ряд указаний, которые следует учитывать при тестировании
глобализации приложений WPF.





При тестировании приложений WPF необходимо ознакомиться со всеми рекомендациями по
проектированию международных приложений, рассмотренными в этом разделе выше, и
поставить вопрос, если эти рекомендации не применяются.
При использовании элемента Path убедитесь, что в языках с порядком чтения справа налево
поведение элемента управления корректно. Если зеркальное отображение элемента Path
выполнять не требуется, явно задайте в стилях ресурса значение параметра FlowDirection
равным LeftToRight.
При использовании экранных координат в таких операциях, как перетаскивание, убедитесь, что
порядок справа налево функционирует корректно.
Для тестирования границ пользовательского интерфейса используйте псевдолокализацию.
Чтобы имитировать локализацию, замените строки в пользовательском интерфейсе более
длинными строками.
Вручную задайте значение свойства FlowDirection в корне пользовательского интерфейса
равным RightToLeft и проверьте, как выглядит интерфейс в двунаправленных языках. Убедитесь,
что функциональность не изменяется.
Подходы к локализации приложений WPF
Существуют различные подходы к локализации приложений WPF. Выбор требуемого подхода зависит
от различных факторов, включая следующие:







размер локализуемого содержимого: одна страница или тысяча страниц;
сложность содержимого: простая таблица строк или элементы, образующие сложный
пользовательский интерфейс;
наличие старых, уже локализованных или еще не локализованных ресурсов;
необходимость локализации перед, во время или после процесса разработки или на различных
этапах разработки;
наличие у локализатора технических знаний и знаний о приложении и платформе;
бюджет локализации;
доступный срок выполнения локализации.
В оставшейся части данного раздела представлен обзор следующих подходов:


локализация из разметки, куда входят локализация BAML и локализация на основе расширений
разметки в XAML;
локализация из кода с использованием объектов ResourceManager.
Выберите подход, который полнее всего удовлетворяет требованиям локализации проекта. Если в
приложении немного старых ресурсов, рекомендуется выбрать локализацию BAML.
ЛОКАЛИЗАЦИЯ BAML
Файлы XAML компилируются в ресурсы BAML — двоичное представление исходной декларативной
разметки. Каждому файлу XAML соответствует ресурс BAML в скомпилированной конечной сборке.
Например, файл MyDialog.xaml создаст ресурс с ключом MyDialog.baml.
Ресурсы BAML локализуются для различных культур: для них не используются ресурсы с парами «ключ
— объект» (файлы RESX), применяемые для приложений Windows Forms. Это означает, что
локализовать можно любой элемент разметки с надлежащими атрибутами. Например, локализуется
фоновый цвет элемента управления Grid или свойство FontSize метки.
Хотя ресурсы BAML содержат весь пользовательский интерфейс и локализуются для каждой культуры,
для локализации предоставляется не вся разметка, что значительно упрощает работу локализатора.
Единственные элементы, предоставляющие локализуемые ресурсы, — это те, у которых атрибуты
локализации заданы в классе, в коде приложения или в XAML. Эти элементы предоставляют
локализаторам контекст с помощью комментариев, категории локализации или просто
идентификатора.
Дополнительные сведения о выполнении локализации BAML см. ниже в разделе Последовательность
операций процесса локализации BAML этого документа.
ЛОКАЛИЗАЦИЯ НА ОСНОВЕ РАСШИРЕНИЙ РАЗМЕТКИ В XAML
Еще один подход к локализации приложений WPF — это расширения разметки. Расширения разметки
позволяют связывать ресурсы из отдельного контейнера с пользовательским интерфейсом. После
локализации контейнер может автоматически загружаться платформой или вызываться кодом внутри
приложения.
Доступны следующие расширения разметки:




Binding. Это расширение позволяет хранить ресурсы в любом экземпляре DependencyProperty и
выполнять к ним привязку, используя выражения привязки к таблице строк.
StaticResource. Это расширение позволяет заменить свойство XAML ресурсом, уже
определенным в объекте ResourceDictionary, которым может быть отдельный файл XAML.
DynamicResource. Это расширение похоже на расширение StaticResource, но оно принудительно
запускает поиск ресурсов при каждом доступе к ресурсу. С помощью этого метода можно
сменить язык пользовательского интерфейса приложения во время выполнения.
x:Static. Это расширение позволяет загружать ресурсы из любой статической конструкции, где
могут храниться ресурсы. Например, с его помощью можно сослаться на ресурсы в файле RESX
из файла XAML, что позволяет выполнять локализацию во время проектирования.
ЛОКАЛИЗАЦИЯ ПУТЕМ ПРИМЕНЕНИЯ КЛАССА RESOURCEMANAGER В КОДЕ
Еще один вариант локализации — использование класса ResourceManager. Этот подход применяется
только в том случае, если в коде используются ссылки на локализуемый пользовательский интерфейс.
Ресурсы можно хранить в таблице строк RESX, а затем обращаться к ним напрямую в коде с помощью
класса ResourceManager.
ПОСЛЕДОВАТЕЛЬНОСТЬ ОПЕРАЦИЙ ПРОЦЕССА ЛОКАЛИЗАЦИИ BAML
В этом разделе рассматривается локализация приложения WPF в ходе процесса локализации BAML.
Раздел включает следующие темы:


Создание локализуемых файлов XAML.
Встраивание локализуемых файлов XAML в проект.

Локализация файлов BAML (скомпилированные файлы XAML).
СОЗДАНИЕ ЛОКАЛИЗУЕМЫХ ФАЙЛОВ XAML
Для применения локализации BAML нужно сделать локализуемыми файлы XAML (процедура
описывается ниже).
ИСПОЛЬЗОВАНИЕ АТРИБУТА X:UID
Чтобы пометить элемент для локализации, добавьте к нему атрибут x:Uid. Значение Uid должно быть
уникальным идентификатором в рамках текущей области, т. е. текущего файла разметки (XAML). В
каждом файле XAML есть собственный набор ресурсов, поэтому одно и то же значение Uid может
применяться в различных файлах XAML.
В следующем примере показан элемент TextBlock с набором атрибутов x:Uid:
<TextBlock x:Uid="TextBlock_LicencedTo">Licensed To:</TextBlock>
По умолчанию атрибуты элемента Content или Text помечаются для локализации. В следующем
примере показано, как достичь того же результата, что и в предыдущем примере:
<TextBlock x:Uid="TextBlock_LicencedTo" Text="Licensed To:" />
Можно автоматически добавить атрибуты x:Uid в файлы XAML при создании проекта, указав параметр
/t: (целевой объект) в команде MSBuild для построения проекта, как показано в следующем примере:
msbuild /t:UpdateUid MyApp.proj
Целевой объект UpdateUid выполняет разрешение дублирующихся Uid и добавляет недостающие
атрибуты и значения Uid.
Чтобы проверить атрибуты Uid в проекте, можно выполнить следующую команду:
msbuild /t:CheckUid MyApp.proj
Текущая версия целевых объектов CheckUid и UpdateUid определяется с помощью средства
синтаксического анализа XML. Он добавляет атрибут x:Uid к каждому элементу XML в каждом файле
XAML, включенном в файл проекта. Это средство не распознает и исключает нелокализуемые элементы
XAML.
Преимущество такого подхода состоит в том, что при добавлении атрибутов Uid ко всем элементам
невозможно пропустить атрибуты Uid для тех частей пользовательского интерфейса, которые подлежат
локализации или служат в качестве ее контекста. Если элемент не содержит атрибут Uid, свойство
элемента без атрибута Uid не будет предоставлено для локализации. Более того, это свойство
невозможно предоставить после определения языка пользовательского интерфейса по умолчанию.
Добавление атрибутов Uid к каждому элементу файла XAML имеет следующие недостатки:


Файлы XAML становятся менее читабельными.
Если приложение включает много больших файлов XAML, может снизиться производительность
во время выполнения.


В файле XAML могут содержаться элементы, не поддерживающие свойство x:Uid, такие как
MC:Choice. И если атрибут Uid не удалить вручную, проект не скомпилируется.
Некоторые части пользовательского интерфейса не локализуются в принципе, и при добавлении
атрибутов Uid к этим элементам код может стать излишне перегруженным. В этом случае можно
поместить нелокализуемый интерфейс в отдельный файл XAML, пометив его тегом
<Localizable>False</Localizable> внутри файла проекта, чтобы избежать его встраивания в сборку
локализуемых ресурсов.
Преимущество наличия атрибутов Uid во всех локализуемых файлах XAML заключается в том, что
локализаторы могут полностью контролировать элементы XAML и решать множество проблем
локализации. Атрибуты Uid также помогают при тестировании, поскольку обеспечивают поиск ресурсов
BAML. Кроме того, значение Uid становится значением AutomationID элемента, которое остается
постоянным даже при изменениях пользовательского интерфейса.
В большинстве сценариев настоятельно рекомендуется добавлять атрибуты Uid с помощью средств Uid
и сохранять их для каждого отображаемого элемента, даже если локализация каких-то элементов не
предусмотрена. Впоследствии локализацией можно управлять с помощью параметров
Localization.Attributes, как описывается в следующем разделе.
Для определения локализуемых элементов можно пользоваться API локализации WPF в пространстве
имен System.Windows.Markup.Localizer, а также атрибутами, заданными разработчиком и
локализатором.
АТРИБУТЫ ЛОКАЛИЗАЦИИ И КОММЕНТАРИИ
Локализация XAML — это не просто перевод пар «ключ — значение». WPF поддерживает возможность
указания дополнительной информации для локализуемого атрибута, как в следующих примерах:
<TextBlock x:Uid="TextBlock_LicencedTo"
Localization.Comments="Text (This is localizable text)"
Text="Licensed To:" />
<TextBlock x:Uid="TextBlock_LicencedTo"
Localization.Comments="$Content (This is localizable text)">
Licensed To:
</TextBlock>
В первом примере комментарий «This is localizable text» добавляется к атрибуту Text элемента
TextBlock, значение Uid которого равно TextBlock_LicencedTo. Второй пример практически аналогичен,
только у свойства Content данного элемента есть комментарий (указанный с помощью выражения
$Content) для именованного атрибута.
Чтобы пометить для локализации другие атрибуты свойства, добавьте к полю Localization.Comments
дополнительные записи. (При желании комментарий к свойству $Content можно пропустить.) В
следующем примере показано, как помечать другие атрибуты свойства:
<TextBlock x:Uid="TextBlock_LicencedTo"
FontSize="30pt"
Localization.Comments="$Content (This is localizable text)
FontSize (Font size of the TextBlock with licensing text.
Don’t make it larger than 35pt.)">
Licensed To:
</TextBlock>
В предыдущем примере к свойству FontSize элемента TextBlock, значение Uid которого равно
TextBlock_LicencedTo, добавляется комментарий в свободной форме. Этот комментарий локализуется
локализатором.
Комментарии к локализации не обязательно компилировать в XAML. В WPF доступна задача MSBuild,
позволяющая извлечь комментарии к локализации в отдельный файл, который может обрабатываться
средствами локализации.
В WPF также доступно свойство Localization.Attributes, с помощью которого можно объявить тип
локализации, применимый к атрибуту элемента. Обратите внимание, что атрибуты, указанные в файле
XAML, переопределяют атрибуты исходного элемента (элемента управления). Например, можно
пометить элемент TextBlock как неизменяемый, так как по умолчанию он может изменяться
локализаторами.
Для каждого свойства элемента указываются следующие три поля (разделяются пробелами):



Категория локализации. Это тип локализуемого ресурса. Список значений см. в статье
LocalizationCategory — перечисление на веб-сайте MSDN. Возможны и другие значения.
Удобочитаемость локализации, указывающая возможность чтения свойства локализатором.
Список значений см. в статье Readability — перечисление на веб-сайте MSDN.
Изменяемость локализации. Указывает, может ли локализатор изменять это значение. Список
значений см. в статье Modifiability — перечисление на веб-сайте MSDN.
В следующем примере показано, как задавать атрибуты локализации для элемента Button:
<Button FontSize="20pt"
Localization.Comments="$Content (Button Content)
FontSize (Size of typeface)"
Localization.Attributes="$Content (Button Readable Modifiable)
FontSize (Font Readable Unmodifiable)">
Hello
</Button>
В предыдущем примере устанавливаются следующие правила локализуемости:


Содержимое элемента попадает в категорию локализации Button, оно доступно для чтения
(просмотра) и изменения локализатором.
Свойство FontSize кнопки попадает в категорию Font. Локализаторы могут читать его, но не могут
изменять.
Это подробный пример для простой кнопки. Однако атрибуты локализации требуются только в том
случае, если переопределяется поведение по умолчанию для элементов управления WPF.
При создании пользовательских элементов управления в WPF (классы, производные от типов
пользовательского интерфейса WPF) атрибут Localizability позволяет переопределить используемую по
умолчанию локализуемость классов, методов и свойств. Данный атрибут принимает те же аргументы,
что и вышеописанное свойство XAML Localization.Attributes. В следующем примере показано, как
применять атрибут Localizability:
[Localizability(LocalizationCategory.Button,
Modifiability=Modifiability.Modifiable,
Readability=Readability.Readable)]
public class MyAmazingControl : Control
{
[Localizability(LocalizationCategory.Text)]
public string MyProperty { get; set; }
}
В предыдущем примере показано, как добавить атрибуты локализуемости элемента управления Button
к пользовательскому классу и как назначить атрибуты Text свойству класса, чтобы сделать его
локализуемым. Либо можно добавить атрибут LocalizationCategory.NeverLocalize к классу, в котором
точно нет локализуемого содержимого. В этом случае локализуемый пользовательский интерфейс его
наследовать не будет.
Средства локализации — это дополнительный способ контроля локализуемости пользовательского
интерфейса WPF. Средства могут переопределять все атрибуты локализации, заданные в коде или
XAML. Это удобно в случае, если локализуемое свойство не предоставляется для локализации или если
в таблице пар «ключ — значение» отображается слишком много нелокализуемых записей, которые
требуется скрыть.
ВСТРАИВАНИЕ ЛОКАЛИЗУЕМЫХ ФАЙЛОВ XAML В ПРОЕКТ
При локализации приложений WPF рекомендуется поместить все локализуемые ресурсы во
вспомогательную сборку, включая ресурсы на языке по умолчанию. Ресурсы BAML могут сильно
увеличить размер сборки. Поэтому, включив ресурсы на языке по умолчанию во вспомогательную
сборку, вы сэкономите дисковое пространство на компьютерах заказчиков: у них будет только одна
копия ресурсов BAML вместо двух (в основной и вспомогательной сборках). При отделении ресурсов от
главной сборки также разделяются код и ресурсы, а значит, независимая от языка часть приложения
будет обслуживаться отдельно от локализуемых ресурсов.
СОЗДАНИЕ ВСПОМОГАТЕЛЬНОЙ СБОРКИ .RESOURCES.DLL
Для успешного выполнения локализации все зависимые от культуры ресурсы (такие как сборка BAML)
следует скомпилировать во вспомогательную сборку, чтобы основная сборка оставалась независимой
от культуры. Чтобы настроить это, измените файл проекта, добавив следующие параметры.
Нижеследующее означает, что все ресурсы в проекте рассматриваются как английские и компилируются
во вспомогательную сборку.
<PropertyGroup>
<UICulture>en</UICulture>
</PropertyGroup>
Обратите внимание, что при удалении нейтральных ресурсов из основной сборки может произойти
сбой приложения, если оно будет использоваться с языковыми стандартами, для которых не созданы
вспомогательные сборки. Чтобы избежать этого, назначьте одну из вспомогательных сборок резервным
ресурсом по умолчанию, задав расположение UltimateResourceFallback в файле AssemblyInfo вашего
проекта.
В следующем примере показано, как назначить вспомогательную сборку конечным резервным
ресурсом:
[assembly: NeutralResourcesLanguage("en",
UltimateResourceFallbackLocation.Satellite)])
Внеся изменения в файл проекта, создайте проект. После завершения откройте папку выходных данных
построения (например, bin\debug) и убедитесь, что в ней находится каталог «en» с английской
вспомогательной сборкой. Например, в проекте могут быть следующие файлы:


bin\debug\MyApp.dll
bin\debug\en\MyApp.resources.dll
СБОРКИ СО СМЕШАННЫМИ РЕСУРСАМИ
Если в сборке содержатся ресурсы из файлов XAML и RESX, то при создании проекта ресурсы из XAML
окажутся во вспомогательной сборке, а из RESX — в основной. Таково ограничение команды MSBuild.
Чтобы обойти это ограничение, можно переименовать файлы RESX, включив в имя культуру. Тогда
ресурсы из файлов RESX будут помещены во вспомогательную сборку указанной культуры. Например,
ресурсы из файла Resources.resx могут быть принудительно помещены в следующее расположение:
bin\debug\en\MyApp.resources.dll
Для этого измените имя файла на Resources.en.resx.
Для проверки успешного обхода этого ограничения исследуйте вспомогательную сборку с помощью
средства .NET Reflector, убедившись в наличии всех нужных ресурсов BAML и RESX. Кроме того, можно
воспользоваться надстройкой BAML Viewer для .NET Reflector, отображающей BAML в сборке в виде
XAML.
РЕСУРСЫ, НЕ ПОДЛЕЖАЩИЕ ЛОКАЛИЗАЦИИ
Если в файле проекта содержатся изображения (например, такой элемент, как <Resource
Include="MyIcon.png">) и свойство UICulture задано, то по умолчанию данный ресурс помещается в
версию «en» вспомогательной сборки. Если локализовать изображения не планируется, их можно
исключить из вспомогательной сборки и хранить в основной. Этот же подход можно применить и для
других ресурсов, включая файлы XAML, локализация которых не планируется.
Чтобы избежать локализации ресурсов, их следует пометить как нелокализуемые и встроить в основную
сборку вместо вспомогательной. В следующем примере показана соответствующая разметка файла
проекта:
<ItemGroup>
<Resource Include="MyIcon.png">
<Localizable>False</Localizable>
</Resource>
</ItemGroup>
ЛОКАЛИЗАЦИЯ ФАЙЛОВ BAML (СКОМПИЛИРОВАННЫЕ ФАЙЛЫ XAML)
Существуют следующие варианты локализации приложений путем локализации файлов BAML:

Использование примера средства LocBaml, описанного в статье Практическое руководство.
Локализация приложения на веб-сайте MSDN. Здесь описываются пример использования API
локализации WPF, а также локализация BAML внутри сборки ресурсов. Это не поддерживаемое



средство, а пример, на основе которого можно создать собственное решение для своих нужд
локализации. Технология, показанная в этом примере, вполне достаточна для локализации
небольших приложений. Однако для более крупных проектов требуется дополнительная
пользовательская настройка.
Создание собственного средства локализации. Каждое приложение уникально, поэтому не
существует единого решения для локализации, удовлетворяющего всем возможным
требованиям. Поэтому для крупных проектов рекомендуется создавать собственные средства
локализации на основе API локализации WPF, как описано в статье на сайте MSDN и в примере
создания средства LocBaml.
Использование средства локализации WPF Visual Localization. Это еще один пример средства,
которое в настоящий момент находится в разработке. Проверьте доступность этого средства в
блоге по тестированию WPF в январе 2009 года. Средство позволит решить известные проблемы
со средством LocBaml и визуально отобразить содержимое файлов BAML в процессе
локализации.
Использование сторонних средств локализации. В Интернете становится все больше различных
средств, обеспечивающих улучшенную поддержку существующих решений локализации, а
также новых подходов, во многих из которых используются расширения разметки. По мере
роста масштабов освоения WPF ожидается улучшение поддержки как со стороны Microsoft, так и
со стороны других производителей.
ДОПОЛНИТЕЛЬНЫЕ РЕСУРСЫ



Запись Best Practices for Globalization and Localization in WPF в блоге Windows Presentation
Foundation SDK.
Запись An App for Help Test WPF Applications in Different Cultures в блоге Windows Presentation
Foundation SDK (включает исходный код).
Статья Localizing WPF Applications using Locbaml на сайте CodePlex (включает исходный код).
ТЕСТИРОВАНИЕ СПЕЦИАЛЬНЫХ ВОЗМОЖНОСТЕЙ
В данный раздел включены следующие темы:




Основные понятия специальных возможностей.
Реализация пользовательского интерфейса специальных возможностей WPF.
Рекомендации по тестированию специальных возможностей.
Основные ресурсы по тестированию специальных возможностей.
ОСНОВНЫЕ ПОНЯТИЯ СПЕЦИАЛЬНЫХ ВОЗМОЖНОСТЕЙ
Термин специальные возможности используется для описания возможностей интерфейса,
обеспечивающих доступ к информации для максимально широкой аудитории. Проект приложения WPF
позволяет определить его специальные возможности. Приложения WPF должны быть доступны
пользователям с ограниченными возможностями здоровья в соответствии со стандартами,
устанавливаемыми, в частности, разделом 508 Закона о защите прав нетрудоспособных граждан США
(http://www.section508.gov) и рекомендациями консорциума W3C по специальным возможностям вебсодержимого (http://www.w3.org/TR/WCAG10/).
Специальные возможности приложений реализуются на разных уровнях и ориентированы на
улучшение или решение проблем взаимодействия с ПО. Сюда относятся следующие разноуровневые
возможности:
Параметры операционной системы: большие шрифты, дисплей с высоким DPI, контрастные темы,
частота мигания курсора, параметры некоторых функций (залипание клавиш, фильтрация ввода,
управление указателем с клавиатуры, альтернативные устройства ввода, озвучивание переключений),
разрешение экрана, пользовательские настройки мыши и ввод с экранной клавиатуры.
Специальные возможности, встроенные в приложение или содержимое, такие как порядок вкладок,
сочетания клавиш и поддержка мультимодальности.
API, включающие такие платформы, как MSAA, UIA, UIA-Ex и OM, где разработчики могут создавать
приложения, которые успешно взаимодействуют со средствами поддержки специальных
возможностей.
Средства поддержки специальных возможностей, такие как программы чтения с экрана, экранные
лупы, программы распознавания речи и речевого ввода.
РЕАЛИЗАЦИЯ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА СПЕЦИАЛЬНЫХ
ВОЗМОЖНОСТЕЙ WPF
Поддержка специальных возможностей встраивается в платформу WPF благодаря интеграции с
платформой модели автоматизации пользовательского интерфейса Microsoft. Модель автоматизации
пользовательского интерфейса Microsoft — это новая платформа специальных возможностей для
Microsoft Windows, с помощью которой разработчики элементов управления и приложений могут
сделать свои продукты более доступными.
В этой платформе каждый элемент пользовательского интерфейса предоставляется клиентским
приложениям в виде объекта AutomationElement, содержащегося в структуре дерева, корень которого
— рабочий стол. У каждого элемента есть свойства, шаблоны элементов управления и методы, которые
могут применяться для описания его поведения и управления им.
Стандартные элементы управления WPF предоставляют поддержку специальных возможностей с
помощью объектов AutomationPeer — реализации в WPF интерфейсов поставщика модели
автоматизации пользовательского интерфейса. Общие рекомендации по специальным возможностям в
WPF следующие:





Обеспечьте программный доступ к элементам управления и приложениям. Дополнительные
сведения об обеспечении доступности элементов пользовательского интерфейса см. в разделе
Основные рекомендации по обеспечению доступности пользовательского интерфейса данного
руководства.
Не переопределяйте параметры специальных возможностей системы.
Не выполняйте жесткое кодирование цветов.
Обеспечьте поддержку всех высококонтрастных настроек.
Обеспечьте поддержку дисплея с высоким DPI. Приложения WPF автоматически определяют
DPI, поскольку в них используются координаты, выраженные в независимых от устройства
единицах (DIU). Одна DIU равна 1/96 дюйма. (В этом отличие приложений WPF от приложений
Win32, где используются координаты, выраженные в единицах на основе физических пикселей.)


Чтобы убедиться в надлежащем масштабировании растровой графики, следуйте инструкциям в
разделе Scaling bitmapped graphics статьи Creating a DPI-Aware Application на веб-сайте MSDN. В
целом необходимо создавать несколько версий каждого элемента интерфейсной графики.
Впоследствии при визуализации пользовательского интерфейса приложение сопоставляет
точечный рисунок системному параметру DPI.
Обеспечьте клавиатурный вызов с позициями табуляции для всех элементов управления, с
которыми может взаимодействовать пользователь, и убедитесь в видимости фокуса ввода с
клавиатуры.
Обеспечьте альтернативы для визуальных элементов, такие как замещающий текст для графики.
Сведения о создании пользовательских элементов управления WPF с поддержкой автоматизации и
специальных возможностей см. в статье Модель автоматизации пользовательского интерфейса
пользовательского элемента управления WPF на веб-сайте MSDN. В этой статье описывается создание
пользовательского элемента управления WPF, а также содержится пример кода, демонстрирующий
добавление объекта AutomationPeer и предоставление элемента управления в XAML.
Сведения о том, как добиться, чтобы приложения и пользовательские элементы управления WPF
наследовали системные параметры, см. в статье SystemParameters — класс на веб-сайте MSDN, а также
см. следующие статьи на веб-сайте MSDN:
Практическое руководство. Использование разделов системных параметров
Практическое руководство. Как использовать SystemParameters
Практическое руководство. Использование SystemFonts
Практическое руководство. Закраска области с помощью системной кисти
Практическое руководство. Использование системных цветов в градиенте
Ниже приводятся общие рекомендации по разработке специальных возможностей для
пользовательского интерфейса, включая интерфейсы приложений WPF.


Если в элементе управления содержится точечный рисунок, но нет метки, данный точечный
рисунок должен быть уникален и использоваться единообразно во всем приложении. Данная
рекомендация согласуется с подразделом 1194.21 (e) раздела 508: «Если точечные изображения
служат для обозначения элементов управления, индикаторов состояния или других
программных элементов, то значение, присвоенное этим изображениям, должно быть единым
во всех операциях приложения».
Если предусмотрено редактирование текста, то необходимо сообщать расположение точки
вставки (IP) наложенным системным курсором (например, вызывать CreateCaret API для
размещения системного курсора в том месте, где находится пользовательский курсор).
Приложение также должно поддерживать текстовые службы, такие как IME, на основе
инфраструктуры текстовой службы. Благодаря этому пользователи, которые применяют
приложения поддержки специальных возможностей, могут редактировать сложные языки, а
сами такие приложения — получать доступ к расположению курсора. Данная рекомендация
согласуется с подразделом 1194.21 (f) раздела 508: «Текстовые сведения должны
предоставляться с помощью функций операционной системы, предназначенных для
отображения текста. Минимальный набор доступных сведений — содержимое текста,
расположение курсора для ввода текста и атрибуты текста».






Если для сообщения сведений используется анимация, то должно поддерживаться отключение
анимации без ущерба для сообщаемых сведений. Обычно в этом случае должна
поддерживаться работа через подключение к серверу терминалов. Данная рекомендация
согласуется с подразделом 1194.21 (h) раздела 508: «Если предусмотрено отображение
анимации, то аналогичные сведения должны демонстрироваться хотя бы в одном
неанимированном режиме представления по выбору пользователя».
Если используется цвет, то он не должен быть единственным средством передачи информации.
Примером нарушения этого требования является выделение нескольких элементов списка
красным цветом, чтобы сообщить об их высоком приоритете. Если в этой ситуации используется
цвет, то у элемента должна быть еще какая-нибудь визуальная подсказка, сообщающая ту же
информацию. В этом примере элементы с высоким приоритетом могут быть также выделены
полужирным шрифтом (помимо красного цвета). Для соблюдения этого требования
рекомендуется визуализировать возможность на черно-белом мониторе. Данная рекомендация
согласуется с подразделом 1194.21 (i) раздела 508: «Цветокодирование не должно быть
единственным средством сообщения информации, указания действия, требования ответа или
выделения визуального элемента».
Избегайте применения мигающих, мерцающих или пульсирующих элементов. Если
пульсирующие элементы действительно необходимы (например, как в случае с кнопкой Office),
убедитесь, что частота пульсации ниже 2 Гц или выше 55 Гц. Любые мерцающие или
пульсирующие элементы на экране могут вызывать припадки и даже привести к смерти больных
эпилепсией. Данная рекомендация согласуется с подразделом 1194.21 (k) раздела 508: «В
программном обеспечении не должны использоваться мерцающий или мигающий текст,
объекты или другие элементы, частота мерцания или мигания которых выше 2 Гц и ниже 55 Гц».
Необходимо обеспечить поддержку связывания текста с любым объектом, вставляемым в
документ, т. е. поддержку замещающего текста (иначе — alt text). Благодаря этому программа
чтения с экрана сможет прочитать описание объекта пользователю с нарушениями зрения.
Примерами таких объектов могут служить картинки, диаграммы, коллекции картинок и формы.
Данная рекомендация согласуется с подразделом 1194.22 (a) раздела 508: «Необходимо
предоставлять текстовый эквивалент для каждого нетекстового элемента (например, с помощью
тегов alt, longdesc или внутриэлементного содержимого)».
Любая видеозапись должна включать голосовое сопровождение происходящего на экране или
выводить аналогичные сведения в программу чтения с экрана для людей с нарушениями
зрения. Видеозапись также должна включать субтитры по требованию или сопоставленный ей
письменный текст для людей с нарушениями слуха (также рекомендуется звуковое описание).
Данная рекомендация согласуется с подразделом 1194.22 (b) раздела 508: «Эквивалентные
альтернативы для любых мультимедийных представлений должны быть синхронизованы с
ними».
Не должно быть пользовательского интерфейса взаимодействия, который исчезает через
определенное время ожидания. Иначе люди с серьезными нарушениями двигательной функции
не смогут вовремя отреагировать на пользовательский интерфейс. Это требование не
применяется к таким функциям, как сохранение, печать и открытие, которые сопровождаются
строкой выполнения, исчезающей при завершении действия. Данная рекомендация согласуется
с подразделом 1194.22 (p) раздела 508: «Если временные рамки реагирования ограничены,
пользователь должен получить соответствующее предупреждение и достаточное время, чтобы
сообщить о необходимости дополнительного времени». В операционных системах Windows
доступно несколько полезных системных параметров, и рекомендуется максимально тщательно
учитывать эти параметры времени ожидания и другие параметры времени.
Дополнительные сведения о модели автоматизации пользовательского интерфейса Microsoft и
рекомендациях по специальным возможностям для приложений WPF см. в следующих материалах вебсайта MSDN:




Рекомендации по специальным возможностям. В этой статье содержатся дополнительные
сведения по вышеперечисленным рекомендациям.
Общие сведения о модели автоматизации пользовательского интерфейса. В этой статье
приводится обзор платформы модели автоматизации пользовательского интерфейса, включая
основные компоненты и ресурсы.
Справка по управляемому коду для модели автоматизации пользовательского интерфейса. В
этой статье перечисляются типы в пространстве имен System.Windows.Automation,
обеспечивающие поддержку клиентов WPF модели автоматизации пользовательского
интерфейса.
Active Accessibility Bridge to UI Automation. В этой статье описывается технология Active
Accessibility Bridge, которая позволяет приложениям, реализующим Active Accessibility, получать
доступ к приложениям, реализующим модель автоматизации пользовательского интерфейса.
РЕКОМЕНДАЦИИ ПО ТЕСТИРОВАНИЮ СПЕЦИАЛЬНЫХ ВОЗМОЖНОСТЕЙ
В общем, для тестирования поддержки специальных возможностей в приложениях WPF выполняются
следующие задачи:





Проверка правильной работы пользовательского интерфейса на дисплее с высоким DPI.
Проверка правильной работы пользовательского интерфейса при высококонтрастном режиме.
Выполнение проверок пользовательского интерфейса в средствах UIA Verifier и AccChecker и
изучение всех ошибок. Сюда относится проверка выходных данных вкладки Screen reader
(«Программа чтения с экрана») средства AccChecker на предмет наличия необычной или
непонятной звуковой информации.
Проверка правильной работы пользовательского интерфейса при использовании экранной лупы
(средство Magnifier.exe).
Проверка доступности с клавиатуры элементов управления пользовательского интерфейса.
Чтобы проверить, поддерживают ли элементы управления и приложения WPF модель автоматизации
пользовательского интерфейса и специальные возможности, обратитесь к следующим средствам:



Платформа автоматизации тестирования UI Automation Verify. UIA Verify — это платформа
автоматизации тестирования, включающая библиотеку UIA Test Library и средство с графическим
интерфейсом пользователя Visual UIA Verify. Эта платформа облегчает ручное и автоматическое
тестирование реализаций UIA, включая элементы управления и приложения WPF.
AccChecker. С помощью этого средства инженеры-тестировщики без опыта MSAA могут легко
обнаружить проблемы с реализациями MSAA в пользовательском интерфейсе приложения.
UI Spy. С помощью этого средства разработчики и инженеры-тестировщики могут просматривать
элементы пользовательского интерфейса приложения и взаимодействовать с ним.
Просматривая иерархическую структуру пользовательского интерфейса, значения свойств и
возникшие события, разработчики и инженеры-тестировщики могут проверить, является ли
создаваемый интерфейс программно доступным для устройств поддержки специальных
возможностей, таких как устройства чтения с экрана. Средство UI Spy входит в пакет Windows
SDK.

Photosensitive Epilepsy Analysis Tool (PEAT) — средство для тестирования мерцающих визуальных
элементов.
При тестировании специальных возможностей приложений WPF, используемых как автономные
клиентские интерфейсы, браузерных приложений XAML (файлов XBAP) или отдельных файлов XAML
следует выполнить следующие задачи:







Проверку визуальных режимов, включая большие шрифты, высокие значения DPI,
высококонтрастные темы, частоту мигания курсора и его ширину.
Тестирование поддержки мультимодальности. Если отображается содержимое, то оно должно
быть мультимодальным — иными словами, доступно для восприятия различными органами
чувств. Например, если возможность представлена звуком, предусмотрены ли в ней субтитры по
требованию или текстовое сопровождение в реальном времени?
Тестирование доступности клавиатуры: вся функциональность приложения должна быть
доступна с клавиатуры. Можно ли выполнить основные функции за пять (или менее) нажатий
клавиш? Является ли модель клавиатуры достаточно практичной, удобной и унифицированной?
Тестирование программного доступа. Проверка надлежащей поддержки модели UIA для
пользования сторонними технологиями специальных возможностей.
Тестирование совместимости со средствами поддержки специальных возможностей, таких как
программа чтения с экрана, диктор, экранная лупа и Jaws, чтобы убедиться в надлежащем
функционировании пользовательского интерфейса.
Тестирование других показателей системы. Тестирование должно определить, соответствует ли
ожидаемому поведение в отношении системных параметров. Сюда относятся надлежащее
масштабирование на основе разрешения экрана, обработка пользовательских параметров
мыши и обработка входных данных с экранных клавиатур.
Тестирование международных специальных возможностей. Специальные возможности — это
общемировая цель, поэтому необходимо проверять международную пригодность и
локализуемость визуальных режимов, доступ с клавиатуры и программный доступ. Большинство
сведений, предоставляемых свойствами модели автоматизации пользовательского интерфейса,
— это строковые данные, но локализуются не все строки. Все значения, относящиеся к
идентификаторам элементов управления или формальным именам типов, локализации не
подлежат. Следующие свойства локализуются в соответствии с языком пользовательского
интерфейса приложения. Содержимое свойства Name должно соответствовать экранному тексту
связанного элемента пользовательского интерфейса (или замещающему тексту для нетекстовых
объектов).
o
o
o
o
o
o
o
AcceleratorKey
AccessKey
HelpText
ItemStatus
ItemType
LocalizedControlType
Name
Свойство Name — это строка для текстового представления элемента. Свойство Name должно всегда
соответствовать тексту метки на экране. Например, для элемента Button с меткой «Обзор…» свойство
Name должно иметь значение «Обзор…». Свойство Name не должно содержать мнемонических
символов для клавиши доступа (то есть символов с префиксом &), подчеркиваемых в текстовом
представлении пользовательского интерфейса. Кроме того, свойство Name не следует расширять или
изменять любым образом, отличным от текста на экране. В противном случае несоответствие
визуальному тексту может запутать пользователей.
Если соответствующий текст метки не отображается на экране или заменяется графикой, следует
выбрать замещающий текст. Замещающий текст должен быть кратким, интуитивно понятным и
локализованным на язык пользовательского интерфейса приложения или язык интерфейса
операционной системы по умолчанию. Хороший замещающий текст — это не подробное описание
внешнего вида элемента, а краткое описание функции или возможности пользовательского интерфейса.
Например, замещающий текст для кнопки «Пуск» Microsoft Vista может быть «Пуск» вместо «Эмблема
Windows на голубом фоне, круглый рисунок». Сведения о рекомендациях по созданию замещающего
текста см. в статье Creating Text Equivalents for Images на веб-сайте MSDN.
Если в метке пользовательского интерфейса используется текстовая графика (например, «>>» для
кнопки, которая служит для копирования или перемещения элемента слева направо), то свойство Name
следует переопределить соответствующей текстовой альтернативой (например, «Добавить»). Тем не
менее, не рекомендуется применять текстовую графику в метках пользовательского интерфейса: это
связано с проблемами локализуемости и специальных возможностей.
В свойстве Name не следует указывать роль элемента управления или вводить такие данные, как
«кнопка» или «список». В противном случае возникнет конфликт с текстом свойства
LocalizedControlType.
Свойство Name необязательно должно быть уникальным идентификатором элемента среди
родственных элементов. Однако если оно одинаково во всем представлении пользовательского
интерфейса, то одно и то же значение Name может поддерживаться несколькими одноранговыми
элементами.
Для автоматизации тестирования следует вместо этого воспользоваться свойствами AutomationId или
RuntimeId.
Пример применения свойства Name в привязке данных для приложения WPF см. в записи Accessible
Data: Making your data available for all блога команды WPF SDK.
ОСНОВНЫЕ РЕСУРСЫ
Для получения дополнительных сведений о проектировании специальных возможностей ознакомьтесь
со следующими ресурсами. Кроме веб-сайта по разделу 508, все остальные ресурсы — это статьи на
веб-сайте MSDN.



Section 508. На данном веб-сайте изложены технические стандарты в соответствии с разделом
508 Закона США о реабилитации с поправками от 1998 года. Согласно разделу 508, все
электронные и информационные технологии, поставляемые, разрабатываемые или
эксплуатируемые федеральными органами, должны быть доступны для людей с ограниченными
возможностями. Правительственные организации США должны учитывать поддержку
специальных возможностей при исследовании рынка решений и приобретать технологии,
которые максимально соответствуют требованиям к специальным возможностям.
MSDN Accessibility Developer Center.
Модель автоматизации пользовательского интерфейса и Microsoft Active Accessibility. В этой
статье предоставляются сведения о модели автоматизации пользовательского интерфейса и ее




отличиях от Active Accessibility. Это полезный справочный ресурс для специалистов, уже
знакомых с Active Accessibility и желающих внедрить поддержку модели автоматизации
пользовательского интерфейса.
Testing for Accessibility. В данной статье содержатся практические рекомендации по
тестированию доступности клавиатуры, высокой контрастности и совместимости со
специальными возможностями.
Примеры реализации специальных возможностей. Эта статья включает примеры реализации
поставщика модели автоматизации пользовательского интерфейса и шаблонов элементов
управления.
Использование автоматизации пользовательского интерфейса для автоматизированного
тестирования. В статье описывается, как модель автоматизации пользовательского интерфейса
Microsoft может служить средой программного доступа в сценариях автоматизированного
тестирования.
Статья Windows Automation API 3.0 Overview и еще несколько полезных статей на сайте журнала
CoDe Magazine, в том числе следующие:
o Open Accessibility
o Windows Automation API 3.0 Overview
o What’s New in Windows 7 Automation API
o Creating Accessibility-aware Silverlight 2 Content
o Microsoft Accessibility Testing Tools vs. the Ten-ton Gorilla of Accessibility Guidelines
Compliance
o A Pragmatic Approach to WPF Accessibility
o Writing a UI Automation Provider for a Win32-based Custom Control
o Creating UI Automation Client Applications
ТЕСТИРОВАНИЕ СТАБИЛЬНОСТИ И НАГРУЗОЧНОЕ ТЕСТИРОВАНИЕ
В данный раздел включены следующие темы:







Что такое нагрузочное тестирование и тестирование надежности?
Зачем выполнять нагрузочные тесты?
Принципы нагрузочного тестирования.
Проектирование тестовых случаев для нагрузочного тестирования.
Рекомендации по нагрузочному тестированию.
Перехват ошибок и отчеты об ошибках.
Показатели нагрузочного тестирования и контроль качества.
ЧТО ТАКОЕ НАГРУЗОЧНОЕ ТЕСТИРОВАНИЕ И ТЕСТИРОВАНИЕ НАДЕЖНОСТИ?
Нагрузочное тестирование — это процесс выполнения тестируемого приложения в экстремальных
условиях. Например, это может быть отправка многочисленных запросов на сервер, многократные
операции запуска и остановки службы или переполнение пользовательского интерфейса приложения
данными, вводимыми с помощью мыши и клавиатуры. Таким образом, под нагрузочным
тестированием понимается вызов любого вида активности, при которой исследуемое приложение
начинает усиленную работу — работу под высокой нагрузкой.
Разработчики WPF могут применять разнообразные нагрузочные тесты. Это и динамические изменения
управления стилем, и постоянные обновления элементов в объекте DataSource, и моделирование
взаимодействия пользователей с компонентами интерфейса и др. Независимо от выбранного вида
нагрузочного тестирования приложения в ходе процесса обычно выполняются долгосрочные,
одновременные операции, которые намного превышают ожидаемую активность пользователей при
реальной работе с приложением.
Нагрузочное тестирование во многом отличается от функционального. Хотя нагрузочные тесты и
моделируют поведение пользователя, они обычно повышают его интенсивность до нереальных
масштабов. Нагрузочные тесты, как правило, выполняются намного дольше функциональных. Кроме
того, несколько нагрузочных тестов выполняются одновременно, что нетипично для других форм
тестирования. Нагрузочные тесты не выполняют проверку. Они служат для обнаружения серьезных
проблем приложения, таких как сбои, зависания, ошибочные утверждения и утечки памяти. Одним
словом, нагрузочные тесты — это создание максимально жестких условий, какие только возможны при
работе приложения, чтобы обнаружить все его слабые места.
ЗАЧЕМ ВЫПОЛНЯТЬ НАГРУЗОЧНЫЕ ТЕСТЫ?
Существует две причины для выполнения нагрузочных тестов. Первая — определение надежности
приложения. Измеряя нагрузку, которую способно выдержать приложение, можно точнее вычислить
среднее ожидаемое время безотказной работы и степень надежности приложения в производственной
среде. Периодически выполняя нагрузочные тесты в ходе разработки приложения, можно отследить
изменения его надежности в ответ на модификации и получить более обширное представление о
серьезности тех или иных ошибок в зависимости от того, как часто они случаются во время нагрузочного
тестирования.
Вторая причина для выполнения нагрузочных тестов — это, без сомнения, поиск ошибок. При
нагрузочном тестировании выполняются попытки определить ошибки приложения, вызывающие три
типа проблем:



понижение производительности с течением времени;
понижение производительности при увеличении нагрузки;
понижение производительности при запуске одновременных процессов.
Эти проблемы, как правило, доставляют больше всего неприятностей пользователям, так как могут
вызвать сбой приложения и потерю данных.
НЕКОТОРЫЕ АСПЕКТЫ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
Проектируя нагрузочные тесты, следует учитывать два фактора:


ресурсы, влияющие на работу приложения;
само исследуемое приложение.
Один из первых методов нагрузочного тестирования приложения — отказ в необходимых ему ресурсах.
Сюда относятся память, дисковое пространство, пропускная способность сети и др. Большую часть
времени компьютеры, используемые в производственной среде, потребляют значительный объем
доступных ресурсов, поэтому важно смоделировать условия нехватки ресурсов. Еще один аспект этого
управления ресурсами — создание случайных файлов. Этот метод применяется при работе с файлами.
Генератор случайных файлов создает большое число файлов для обработки приложением. Если в
приложении используется собственный формат файлов, то такой генератор придется создавать
самостоятельно.
Взяв ресурсы под контроль, переходим к нагрузке самого приложения. Этот аспект подробно
рассматривается в следующих разделах.
ПРИНЦИПЫ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
Нагрузочное тестирование каждого приложения имеет свои особенности. Однако существует несколько
общих принципов, которые справедливы для нагрузочных тестов практически всех приложений.






Создание пула действий на основе сценариев. Нагрузочное действие должно быть атомарным и
основываться на реальном поведении. Некоторые из этих действий могут быть произвольными,
а некоторые — целенаправленными. Например, можно выполнить произвольные щелчки
мышью по всему пользовательскому интерфейсу и целенаправленно — по некоторым
элементам управления. Однако все производимые действия должны быть правдоподобными —
такими, которые действительно могут произойти в реальных условиях. Чем проще по структуре
каждое действие, тем удобнее создавать их различные сочетания, увеличивая охват различных
аспектов работы приложения.
Комбинирование действий. Создавайте долгосрочные (и даже бессрочные) тесты, в ходе
которых последовательно выполняются произвольно выбранные действия. В результате
создается сложный и постоянно изменяющийся набор тестов, генерирующий гораздо больше
сценариев, чем можно жестко закодировать с помощью простого модульного или
функционального тестирования. При комбинировании действий создаются сценарии, которые
потенциально возможны при работе пользователей, при этом инженеру-тестировщику или
разработчику даже не приходится предугадывать все вероятные действия.
Одновременное выполнение нескольких действий. Помимо выполнения одной длительной
цепочки действий можно одновременно запускать и другие цепочки. Благодаря этой методике
можно создать такие конкурентные условия и экстремальные ситуации, которые могут никогда
не произойти в ходе фиксированных комплексных тестов.
Отслеживание катастрофических сбоев. Нагрузочное тестирование отличается такими жесткими
условиями, что те функциональные проблемы, которые в обычных случаях рассматривались бы
как ошибки, становятся менее критическими или даже ожидаемыми. При нагрузочном
тестировании следует сосредоточиться на поиске тех проблем приложения, которые,
несомненно, требуют устранения. При выполнении тестов необходимо задействовать механизм
отслеживания таких проблем.
Запись данных, облегчающих изучение сбоя. Обнаружение ошибок не имеет особого смысла,
если отсутствует средство для их устранения. При нагрузочном тестировании должны
записываться данные времени выполнения, на основе которых разработчик сможет вернуться к
точке сбоя, выяснить причину проблемы и исправить ее.
Отказ от использования неопределенных произвольных генераторов. Причина этого состоит в
том, что аварийный дамп/стек часто указывает на ошибку, но разработчику требуется контекст,
чтобы решить, следует ли создавать исправление. В идеале рекомендуется запустить
нагруженное приложение на компьютере разработчика и пронаблюдать за сбоем еще раз.
ПРОЕКТИРОВАНИЕ ТЕСТОВЫХ СЛУЧАЕВ
Чтобы проиллюстрировать вышеперечисленные принципы, опишите типы нагрузочных тестов, которые
можно спроектировать для тестирования примера приложения Southridge Realty. В этом приложении
WPF служит для демонстрации и обработки местных предложений недвижимости. Оно обладает
такими функциями, как связанное с данными отображение объектов недвижимости и доступных в них
удобств, возможность поиска по элементам списка, интерактивные критерии поиска и расширенное
содержимое, включая изображения для каждого свойства, как показано на следующем рисунке:
РИС. 6. ПРИМЕР ПРИЛОЖЕНИЯ SOUTHRIDGE REALTY
Нагрузочные тесты для этого приложения могут включать следующие действия:








изменение размера панели инструментов ленты;
добавление и удаление параметров в панели быстрого доступа;
выбор даты встречи и ее отправка;
выполнение фоновых изменений данных в источнике данных;
выполнение поискового запроса;
изменение параметров поиска;
просмотр фотографий объектов;
изменение темы.
Этот лист можно продолжить, охватив более обширный набор базовых действий для конкретного
приложения. Окружение теста будет создавать множество потоков, запрашивать и выполнять действия
независимо на каждом из этих потоков.
В некоторых приложениях удобно группировать несколько действий вместе, изолируя остальные.
Разработчики приложения Southridge Realty могут выполнить один набор действий с открытой вкладкой
Search Criteria («Условия поиска»), а другой набор действий — для вкладки Search Results («Результаты
поиска»). Чтобы выполнить эту задачу, окружение нагрузочного теста должно приостановить,
переключить вкладки и затем продолжить тестирование.
Этого легко достичь, используя блокировку чтения-записи на пуле действий. Перед выполнением
любого действия потоки тестирования блокируются на чтение (обеспечивая одновременную
блокировку множества других действий). Когда тест будет готов переключить контроль с одной вкладки
на другую, один поток блокируется на запись (гарантируя, что действия не выполняются). Затем поток
тестирования меняет вкладки и набор доступных для запуска действий. После разблокировки все
исходные потоки тестирования возобновляют работу и могут выполнять новые тесты на другой части
приложения.
При необходимости в периоды между этапами нагрузочного тестирования можно выполнять
функциональные тесты и тесты производительности. Благодаря этому проверку на основе таких тестов
можно выполнять после того, как приложение поработало в экстремальных условиях, не сталкиваясь со
сложностями проверки «движущейся цели».
Пока выполняются все эти тесты, инфраструктура нагрузочного тестирования отслеживает сбои,
зависания, ошибочные утверждения и утечки памяти, как описано в следующем разделе. При
обнаружении таких ситуаций сбоя запускаются средства отладки, благодаря которым разработчики
могут получить дамп памяти приложения SouthridgeRealty.exe либо провести интерактивный сеанс
отладки, чтобы выяснить причину сбоя.
РЕКОМЕНДАЦИИ ПО НАГРУЗОЧНОМУ ТЕСТИРОВАНИЮ
Помимо создания собственной архитектуры нагрузочного тестирования, основанной на
вышеперечисленных принципах, рекомендуется выполнять нижеследующие инструкции, чтобы
повысить эффективность тестов.






Оставайтесь в пределах исходного кода. Чем больше времени ЦП затрачивает на настройку,
выполнение и разбор тестов, тем меньше времени остается на выполнение кода приложения.
Оптимизируйте тесты таких образом, чтобы основную часть времени выполнялся сам код
приложения, а меньше всего — тестовый код.
Не маскируйте исключения кода приложения. Обработка исключений приложения должна
выполняться продуманно и умеренно. При выполнении внутрипроцессного нагрузочного
тестирования перехват исключений может скрыть проблемы, которые впоследствии проявятся у
пользователей.
Сократите запись в журнал и вывод текстовых результатов. Это особенно важно при выполнении
одновременных тестов, поскольку ведение журнала вызывает последовательную обработку
потоков, при которой невозможна борьба за ресурсы. Поскольку сведения о сбое могут
собирать отладчики, ведение журнала при нагрузочном тестировании не так важно, как при
функциональном. Настоятельно рекомендуется вообще отключить запись в журнал.
Добавьте показатели производительности. Большинство случаев понижения
производительности происходит только в условиях высокой нагрузки. Поэтому рекомендуется
включить в нагрузочные тесты и возможность тестирования производительности.
Не допускайте, чтобы тестовый код создавал необработанные исключения. Поскольку их можно
трактовать как сбои нагрузочного тестирования, рекомендуется уменьшить уровень шума,
перехватывая исключения от тестового кода, а не от основного приложения. Можно
воспользоваться этой возможностью и намеренно создавать исключения в тестовом коде, чтобы
вызвать сбой в результате нагрузки. При наличии индикаторов работоспособности системы,
которые необходимо отслеживать при нагрузке приложения, их можно измерить и создать
исключение, если данные индикаторы показывают те или иные типы понижения
работоспособности.
Не создавайте нагрузочные тесты для проверки функциональности. Нагрузочные тесты не
должны давать сбои в том случае, если обнаружится некорректное поведение, которое должно
вызвать сбой функционального теста. Такие сбои могут привести к накоплению большого числа
ошибок, которые вряд ли удастся исправить, и помешают нагрузочным тестам найти
соответствующие их профилю ошибки.
ПЕРЕХВАТ ОШИБОК И ОТЧЕТЫ ОБ ОШИБКАХ
Важный этап нагрузочного тестирования — это перехват сведений о сбоях. Проще всего
воспользоваться для этого параметрами JIT-отладчика .NET Framework. В реестре разверните раздел
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework и найдите два значения:
DbgManagedDebugger и DbgJITDebugLaunchSetting.
Для нагрузочного тестирования задайте значение DbgManagedDebugger равным командной строке,
загружающей отладчик. Задайте значение DbgJITDebugLaunchSetting равным 2. В этом случае
командная строка отладчика будет автоматически выполняться при наличии необработанного
управляемого исключения.
Дополнительные сведения о параметрах JIT-отладки см. в статье Включение отладки с JITприсоединением на веб-сайте MSDN.
ИССЛЕДОВАНИЕ СБОЕВ С ПОМОЩЬЮ ИНТЕРАКТИВНЫХ СЕАНСОВ
ОТЛАДЧИКА
Выбор используемой командной строки отладчика зависит от того, как планируется выполнять
нагрузочные тесты. Если нагрузочные тесты будут выполняться изредка всего на одном или нескольких
компьютерах, рекомендуется присоединить средство VSJitDebugger.exe к неисправному процессу и
исследовать его с помощью интерактивного удаленного сеанса. Для этого установите следующее
значение DbgManagedDebugger:
"%systemroot%\system32\vsjitdebugger.exe" PID %d APPDOM %d EXTEXT "%s" EVTHDL %d
ИССЛЕДОВАНИЕ СБОЕВ С ПОМОЩЬЮ ДАМПОВ ПАМЯТИ
Чтобы получить наиболее точные данные нагрузки, рекомендуется несколько раз выполнять тесты на
множестве компьютеров в течение продолжительного времени. Если нагрузочные тесты ежедневно
выполняются на большом количестве компьютеров, удобнее собирать аварийные дампы для изучения
в свободное время, а не занимать компьютеры, готовясь выполнить исследование. В этом случае
следует использовать отладчик, который может собирать дампы памяти и принимать команды
отладчика в виде аргументов командной строки. Один из вариантов — загрузить средства Debugging
Tools for Windows с веб-сайта WDK and Developer Tools. Чтобы присоединить отладчик к неисправному
процессу, автоматически собрать дамп памяти и выйти, установите следующее значение
DbgManagedDebugger:
"%program files%\debugging tools for windows\ntsd.exe" -p %ld -c &quot.dump /ma ;q"
Для упорядоченного хранения файлов дампа воспользуйтесь кодом, приведенным в следующем
примере. В этом случае файлы дампа будут храниться во временной папке пользователя с именами,
состоящими из даты и процесса. Кроме того, в результате этого будет открыт канал удаленной связи для
локальной или удаленной отладки сбоя. Если после сбора дампа требуется закрывать отладчик,
добавьте ;q к концу команды, передаваемой ntsd.exe.
public class JitDebuggerWrapper
{
private static string commandLine;
public static void Main(string[] args)
{
string debuggerPath = DebuggerSettings.Default.DebuggerPath ==
"Default" ?
Path.Combine(
Environment.ExpandEnvironmentVariables("%programfiles%"),
"Debugging Tools for Windows\\ntsd.exe") :
DebuggerSettings.Default.DebuggerPath;
string pipeName = DateTime.Now.ToString() + "-";
for (int i = 0;
{
commandLine
commandLine
pipeName +=
}
i < args.Length; i++)
+= " ";
+= args[i];
args[i];
commandLine = "-server npipe:pipe=" + pipeName;
Process.Start(debuggerPath, commandLine);
string dumpPath = Path.Combine(
Environment.ExpandEnvironmentVariables("%userprofile%"),
"appdata\\local\\temp\\");
dumpPath += "crashDump" + pipeName + ".dmp";
Process.Start(
debuggerPath,
"-remote npipe:server=" +
Environment.MachineName +
",pipe=" +
pipeName +
" -c \".dump /ma " + dumpPath + "\"");
}
}
ПЕРЕХВАТ ПОДТВЕРЖДЕНИЙ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
С помощью нагрузочных тестов можно обнаруживать не только сбои приложений. JIT-отладчик будет
собирать сведения сбоя от исключений тестового кода. А значит, можно вызывать сбои, намеренно
создавая исключения. Можно также добавить пользовательский прослушиватель трассировки, чтобы
превращать ошибочные утверждения в необработанные исключения. Корректно написанные
утверждения (те, которые не дают сбоев) позволяют перехватывать более широкий спектр проблем с
нагрузочными тестами, чем при мониторинге только сбоев приложения.
Следующий код описывает простой прослушиватель трассировки, который будет превращать
ошибочное утверждение в необработанное исключение. Дополнительные сведения о трассировщиках
см. в статье TraceListener — класс на веб-сайте MSDN.
/// <summary>
/// Trace listener to detect asserts and turn them into stress failures by
/// throwing unhandled exceptions
/// </summary>
public class AssertTraceListener : TraceListener
{
public override void Fail(string message)
{
throw new Exception("Assertion failed, message: " + message);
}
public override void Write(string message)
{
}
public override void WriteLine(string message)
{
}
}
Создав пользовательский прослушиватель трассировки, добавьте на него ссылку в файл machine.config.
Для этого потребуется полное имя библиотеки DLL. В следующем примере кода показан раздел файла
machine.config со ссылкой на пользовательский прослушиватель трассировки:
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="assertlistener" type="[Fully Qualified Type Name]" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
ОТЛАДКА СБОЕВ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
Отладку аварийных дампов можно выполнять с помощью любого из отладчиков Windows, таких
как WinDbg или NTSD. Использование этих средств отличается от применения отладчика
Visual Studio. Однако в среде CLR доступны полезные управляемые расширения отладки в
библиотеке SOS. В следующей таблице приводится несколько команд, с которых можно начать
работу.
Команда
Использование
.loadby sos
mscorwks
Загрузка библиотеки SOS.dll. При отладке дампа на компьютере, где этот дамп был
создан, библиотека SOS.dll загружается с помощью данной команды. При этом
предоставляется доступ ко всем управляемым расширениям отладки. При отладке
дампа на другом компьютере для прямой загрузки SOS используется следующая
команда:
.load <путь к библиотеке>
Библиотека SOS.dll находится в каталоге .NET Framework вашего компьютера
!Threads
Печать сводки всех активных потоков. Благодаря ей можно увидеть, в каком потоке
создано исключение и какое оно
!PrintException
или
!pe
Печать сведений о самом последнем исключении, созданном на текущем потоке
(исключение, которое, вероятно, является причиной сбоя одного из потоков)
!dso
Создание дампа объектов стека со сведениями об объектах, находящихся в стеке
!clrstack
Отображение управляемой трассировки стека для текущего потока
!eeheap
Отображение объема памяти управляемой кучи
!dumpheap
Отображение объектов управляемой кучи
~1s
Переключение на поток ID 1. Замените его на ID потока, на который необходимо
переключиться
~*
Отображение всех активных потоков
Дополнительные сведения об отладке SOS см. в статье Расширение отладки SOS (SOS.dll) на веб-сайте
MSDN.
ПОКАЗАТЕЛИ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ И КОНТРОЛЬ КАЧЕСТВА
Последнее, что следует сделать в отношении нагрузочного тестирования, — определить, насколько
критичны вызванные нагрузкой сбои. Удобно применять такой показатель нагрузочного тестирования,
как процент успешно пройденных нагрузочных тестов. Чтобы измерить процент успешного выполнения,
можно установить фиксированное время (например, 12 часов) и выполнять в течение этого времени
нагрузочные тесты на множестве компьютеров, а затем определить процент компьютеров, которые
завершили тестирование без сбоев. Для комплексных наборов нагрузочных тестов и статистически
значимого количества компьютеров процент успешного выполнения, равный 90 % или выше,
свидетельствует о надежном приложении.
ПОЛЬЗОВАТЕЛЬСКИЕ ЭЛЕМЕНТЫ УПРАВЛЕНИЯ И ТЕСТИРОВАНИЕ
РАСШИРЯЕМОСТИ
В данный раздел включены следующие темы:





Общие аспекты создания пользовательских элементов управления и расширяемости.
Рекомендации по созданию пользовательских элементов управления.
Процесс создания пользовательских элементов управления с помощью объектов
AutomationPeer.
Пример пользовательского элемента управления с поддержкой модели автоматизации
пользовательского интерфейса.
Тестирование пользовательских элементов управления WPF с помощью объектов
AutomationPeer.
В этом разделе также приводится пример кода для создания и тестирования пользовательских
элементов управления.
ОБЩИЕ АСПЕКТЫ СОЗДАНИЯ ПОЛЬЗОВАТЕЛЬСКИХ ЭЛЕМЕНТОВ
УПРАВЛЕНИЯ И РАСШИРЯЕМОСТИ
Обширные возможности платформы WPF позволяют легко настраивать элементы управления с
помощью шаблонов (элементов управления, данных и др.), стилей, тем и т. д. Поэтому новый или
пользовательский элемент управления приходится создавать сравнительно редко. Однако если все-таки
необходимо создать новый элемент управления с новым поведением, необходимо учитывать
приведенные в этом разделе аспекты их создания.
ВЫБОР КЛАССА ДЛЯ ПРОИЗВОДНОГО ЭЛЕМЕНТА УПРАВЛЕНИЯ
В WPF доступны три модели создания элемента управления, каждая из которых отличается своими
возможностями и уровнями гибкости. Перед написанием нового элемента управления настоятельно
рекомендуется подробно ознакомиться с этими моделями. В следующей таблице перечислены эти
модели и их свойства.
Модель
Свойства
Производный от UserControl
Достоинства. Поддержка форматированного содержимого, стилей и
триггеров.
Недостатки. Отсутствуют поддержка шаблонов и тем и возможность
настройки.
Случаи использования:


Производный от Control. Эта
модель используется в
большинстве встроенных
элементов управления WPF
Элемент управления состоит только из существующих
компонентов.
Поддержка расширенной настройки не требуется.
Достоинства. Призвана отделить операционную логику от
визуального представления с помощью шаблонов и тем, поэтому
предоставляет максимальную гибкость.
Недостатки. Более сложная по сравнению с созданием класса,
производного от UserControl.
Случаи использования:


Производный от
FrameworkElement
Требуется выполнять настройку внешнего вида элемента
управления с помощью класса ControlTemplate.
Элемент управления должен поддерживать различные темы.
Достоинства. Самый гибкий. Лучший выбор, если не требуется
механизм использования шаблонов.
Недостатки. Может быть более сложным, чем другие модели.
Случаи использования:

Для элемента управления шаблон не требуется: планируется
самостоятельно выполнять визуальное создание и

подключение дочерних элементов.
Требуется более тонкая настройка функциональности, чем
доступная при создании элементов управления, производных
от классов UserControl или Control (в основе которых
лежит компоновка существующих элементов).
Существует два стандартных метода создания такого элемента
управления: прямая визуализация и пользовательская компоновка
элементов. При прямой визуализации переопределяется метод
OnRender класса FrameworkElement и предоставляются операции
DrawingContext, которые явно определяют визуальные элементы.
При пользовательской компоновке элементов создаются экземпляры
объектов Visual, которые затем используются для создания внешнего
вида компонента.
ДРУГИЕ АСПЕКТЫ
Ниже рассматриваются прочие аспекты создания пользовательского элемента управления.














Как упаковать элемент управления?
Когда следует использовать объекты DependencyProperty вместо свойств CLR?
Когда следует использовать объекты RoutedEvent вместо событий CLR?
Когда следует использовать объекты Command?
Как создавать шаблоны для элементов управления и каковы издержки производительности? Как
можно их уменьшить?
Как создавать тематические стили и шаблоны для элементов управления?
Как упаковать тематические ресурсы?
Как сделать элемент управления доступным?
Как сделать элемент управления локализуемым?
Как добавить к элементу управления поддержку времени разработки?
Как создать опытное проектирование для элемента управления в Microsoft Expression Blend и
Microsoft Visual Studio?
Как реализовать поддержку ведения журнала для свойств элемента управления?
Как виртуализовать части пользовательского интерфейса в элементе управления (если
применимо)?
Как реализовать поддержку виртуализации данных для элемента управления?
РЕКОМЕНДАЦИИ ПО СОЗДАНИЮ ПОЛЬЗОВАТЕЛЬСКИХ ЭЛЕМЕНТОВ
УПРАВЛЕНИЯ
Ниже приводятся рекомендации по созданию пользовательского элемента управления.


Перед выбором модели для нового элемента управления настоятельно рекомендуется
подробно ознакомиться с тремя доступными моделями их создания.
Чтобы упростить повторное использование элемента управления, упакуйте его в отдельную
сборку.



Обычно рекомендуется подкреплять все свойства нового элемента управления объектом
DependencyProperty. Дополнительные сведения см. в статье Пользовательские свойства
зависимостей на веб-сайте MSDN.
Подобно тому, как свойства зависимостей расширяют функциональность свойств CLR, так и
перенаправленные события расширяют обычные события CLR. При создании нового элемента
управления WPF рекомендуется реализовать события в виде объектов RoutedEvent.
Дополнительные сведения см. в статьях Общие сведения о перенаправленных событиях и
Практическое руководство. Создание пользовательских перенаправленных событий на вебсайте MSDN.
Чтобы отделить пользовательский интерфейс элемента управления от его логики,
воспользуйтесь привязкой данных. Это особенно важно, если внешний вид элемента
управления определяется с помощью класса ControlTemplate.
Чтобы добавить поддержку пользовательских элементов управления WPF в средстве WPF Designer для
Visual Studio, выполните следующие инструкции:




Для объектов DependencyProperty реализуйте метод CLR get accessor для свойств только для
чтения.
Для объектов AttachedProperty выполните следующие действия:
o Создайте общий статический и доступный только для чтения экземпляр
DependencyProperty формы PropertyNameProperty, создаваемой с помощью метода
RegisterAttached.
o Реализуйте пару общих статических методов CLR с именем GetPropertyName (для всех
свойств) и SetPropertyName (для свойств чтения-записи). Эти методы должны направлять
непосредственно к методам GetValue и SetValue целевого объекта зависимости.
Используйте объект Command, который повышает гибкость обработки входных данных (событий
и др.) Дополнительные сведения о командах см. в статье Общие сведения о системе команд.
Создайте тематическую сборку со словарями ресурсов, переопределяющими стили по
умолчанию. Для этого создайте несколько файлов ResourceDictionary, используя соглашение об
именах Theme Name.Theme Color.xaml (например, Luna.NormalColor.xaml). Поместите файлы в
каталог с именем Themes. Не забудьте включить файл Generic.xaml в качестве источника
резервного стиля.
НЕКОТОРЫЕ АСПЕКТЫ БЕЗОПАСНОСТИ
Одноранговые элементы модели автоматизации должны работать в среде с частичным доверием.
Поскольку сборка UIAutomationClient не предназначена для запуска с частичным доверием, в коде
поставщика (коде пользовательского элемента управления) не должно быть ссылки на эту сборку. В
противном случае код может выполняться в среде с полным доверием, но давать сбои в среде с
частичным доверием. В частности, не следует использовать в сборке UIAutomationClient поля из классов,
такие как в объекте AutomationElement. Вместо этого эквивалентные поля из классов, такие как
AutomationElementIdentifiers, следует использовать в сборке UIAutomationTypes.
ДОПОЛНИТЕЛЬНЫЕ РЕСУРСЫ ПО СОЗДАНИЮ ПОЛЬЗОВАТЕЛЬСКИХ
ЭЛЕМЕНТОВ УПРАВЛЕНИЯ
Дополнительные сведения о создании пользовательских элементов управления см. в следующих
ресурсах на веб-сайте MSDN:



Общие сведения о разработке элементов управления.
Рекомендации по разработке элементов управления с возможностью использования стилей.
Настройка элементов управления WPF при помощи шаблонов, автор Чарльз Петцольд (Charles
Petzold).
СОЗДАНИЕ ПОЛЬЗОВАТЕЛЬСКИХ ЭЛЕМЕНТОВ УПРАВЛЕНИЯ С ПОМОЩЬЮ
ОДНОРАНГОВЫХ ЭЛЕМЕНТОВ МОДЕЛИ АВТОМАТИЗАЦИИ
Чтобы создать пользовательский элемент управления с поддержкой модели автоматизации, выполните
действия, приведенные в следующей таблице.
Функционал
ьность
Предоставлен
ие элемента
управления
модели
автоматизации
пользовательс
кого
интерфейса
Реализация
Переопределите метод OnCreateAutomationPeer для пользовательского элемента
управления, чтобы он возвращал объект поставщика, который должен быть
прямым или непрямым производным от AutomationPeer. Например, если
пользовательский элемент управления, производный от Button, именуется
MyButton, то объект, возвращаемый OnCreateAutomationPeer, должен
именоваться MyButtonAutomationPeer
Предоставлен
ие значений
свойств
Переопределите методы базового однорангового класса, получающие значения
свойств элемента управления (например, AutomationPeer.GetAcceleratorKey), и
любых дополнительных интерфейсов шаблонов элемента управления,
реализуемых пользовательским одноранговым классом (например,
IToggleProvider.ToggleState)
Обеспечение
взаимодействи
я клиента с
элементом
управления
Переопределите методы базового однорангового класса (например,
ToggleButtonAutomationPeer.IToggleProvider.Toggle) и любых дополнительных
интерфейсов шаблонов элемента управления, реализуемых пользовательским
одноранговым классом. В реализации поставщика GetPattern верните объект,
поддерживающий указанный шаблон элемента управления. Это может быть
одноранговый объект или объект элемента управления, представляемый
одноранговым объектом
Создание
событий
Вызовите методы RaiseAutomationEvent и RaisePropertyChangedEvent
пользовательского класса AutomationPeer, чтобы создать соответствующие
события шаблона. Например, в событии OnClick пользовательского элемента
управления (например, MyButton.OnClick) выполните следующий вызов:
myButtonPeer.RaiseAutomationEvent(AutomationEvents.InvokePatternO
nInvoked)
При создании пользовательского элемента управления с поддержкой модели автоматизации
разработчикам следует помнить следующее:




Если интерфейс пользовательского элемента управления включает коллекцию стандартных
элементов управления (например, Button и TextBox), то в классе AutomationPeer этого
пользовательского элемента переопределите методы GetChildrenCore или GetChildren базового
однорангового класса, чтобы возвращалась коллекция одноранговых объектов модели
автоматизации стандартных элементов управления. Если пользовательский элемент управления
является производным от класса UIElementAutomationPeer, то по умолчанию реализация метода
GetChildrenCore выполнит обход дочерних объектов в визуальном дереве и вернет список их
одноранговых элементов модели автоматизации. Если не требуется предоставлять все
визуальные элементы, можно переопределить метод GetChildrenCore и возвращать только
требуемые одноранговые элементы.
Если в пользовательском элементе управления содержится элемент управления Popup, не
полагайтесь на обход визуального дерева, поскольку содержимое Popup находится в отдельном
визуальном дереве. Например, метод ComboBoxAutomationPeer.GetChildrenCore должен
возвращать список одноранговых элементов модели автоматизации, соответствующих
элементам в визуальном дереве элемента управления Popup.
Если пользовательский элемент управления является производным класса Control, не
включающего сам объект AutomationPeer, то пользовательский одноранговый класс должен
быть производным FrameworkElementAutomationPeer.
В целях оптимизации производительности следует убедиться, что события модели
автоматизации создаются только при наличии прослушивателей на клиентах. Для этого
проверьте связанные события с помощью метода AutomationPeer.ListenerExists.
ПРИМЕР СОЗДАНИЯ И ТЕСТИРОВАНИЯ ПОЛЬЗОВАТЕЛЬСКОГО ЭЛЕМЕНТА
УПРАВЛЕНИЯ
Чтобы подробнее узнать о том, как создавать пользовательские элементы управления и тестировать их,
можно воспользоваться примером решения. Чтобы получить пример, загрузите сжатый файл,
содержащий пример из блога WPF Testing.
Пример решения включает следующие проекты:




Библиотеку пользовательских элементов управления с двумя элементами со встроенной
поддержкой модели автоматизации пользовательского интерфейса.
Приложение WPF с пользовательскими элементами управления.
Проект тестирования для активизации приложения WPF с помощью API модели автоматизации
пользовательского интерфейса.
Второй проект тестирования, демонстрирующий встраивание тестового кода в тестируемое
приложение.
Дополнительные примеры по созданию пользовательских элементов управления WPF см. в статье
Примеры настройки элементов управления на веб-сайте MSDN.
ТЕСТИРОВАНИЕ ПОЛЬЗОВАТЕЛЬСКИХ ЭЛЕМЕНТОВ УПРАВЛЕНИЯ WPF С
ПОМОЩЬЮ ОДНОРАНГОВЫХ ЭЛЕМЕНТОВ МОДЕЛИ АВТОМАТИЗАЦИИ
ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
При тестировании пользовательских элементов управления WPF с помощью одноранговых элементов
модели автоматизации пользовательского интерфейса выполните следующие инструкции:





Убедитесь, что пользовательский элемент управления поддерживает модель автоматизации
пользовательского интерфейса с AutomationPeer. Дополнительные сведения см. в разделе
«Пример создания и тестирования пользовательских элементов управления» этого документа.
Следуйте рекомендациям, описанным в разделе «Основные рекомендации по обеспечению
доступности пользовательского интерфейса», чтобы правильно пометить элементы управления.
Сведения о модульном тестировании пользовательского элемента управления содержатся в
примере, описанном в записи блога Unit Testing WPF controls with Automation Peers. В этом
примере показано, как тестировать стандартный элемент управления. Процедура тестирования
пользовательского элемента управления аналогична приведенной, за исключением того, что для
тестирования используется объект AutomationPeer пользовательского элемента.
Сведения о тестировании пользовательского элемента управления в рамках процесса
тестирования модели автоматизации пользовательского интерфейса приложения см. в примере
решения, описанном в разделе «Пример создания и тестирования пользовательских элементов
управления» этого документа.
Убедитесь, что элемент управления поддерживает различные темы.
ТЕСТИРОВАНИЕ ИНТЕГРАЦИИ И СЦЕНАРИЕВ
Тестирование интеграции и сценариев — это взаимосвязанные методологии, служащие для
тестирования нескольких модулей продукта, чтобы оценить их взаимодействие. В следующих разделах
приводится более подробное обсуждение этих двух подходов.
ТЕСТИРОВАНИЕ ИНТЕГРАЦИИ
Модульное тестирование предполагает тестирование одного модуля или компонента кода.
Тестирование интеграции основано на модульном тестировании и служит для проверки успешного
взаимодействия модулей друг с другом. Даже после расширенного модульного тестирования
программного компонента его ценность стремится к нулю, если его нельзя успешно интегрировать с
остальной системой.
Тестирование интеграции является критически важной составляющей успешного продукта. Во многих
случаях тестированием интеграции занимается отдельная команда инженеров-тестировщиков.
На этапе интеграции может обнаружиться много ошибок. Ниже приводятся некоторые причины того,
почему на этапе интеграции возникают проблемы:







компоненты, разработанные различными программистами или командами;
неполные или неточные спецификации или исходные положения;
ошибки в отдельных компонентах;
глобальные структуры данных, представляющие проблемы;
данные, потерянные в структуре интерфейса;
распределенные возможности;
отдельная допустимая погрешность, возросшая до неприемлемых уровней.
ЭТАПЫ ТЕСТИРОВАНИЯ ИНТЕГРАЦИИ
Ниже рассматриваются этапы тестирования интеграции.
1. Определение взаимодействий модулей. Определение и документирование взаимодействий
модуля с другими модулями.
2. Выверка полноты взаимодействий. Любые взаимодействия модулей друг с другом следует
проверять на предмет нарушения согласованности. Например, если модуль A отправляет
данные модулю B, то модуль B должен указать, что получены входные данные от модуля A.
3. Создание условий тестирования интеграции. Условия тестирования готовятся для интеграции
каждого модуля и документируются.
4. Оценка выполнения условий тестирования. В этом вам помогут следующие вопросы:
1. Все ли взаимодействия между модулями проверены таким образом, что выходные данные
одного записываются как входные данные другого?
2. Проверена ли перед тестированием интеграции обработка каждого модуля?
3. Все ли разработчики модулей согласны с тем, что условия тестирования интеграции
подходят для тестирования интерфейсов каждого модуля?
4. Все ли модули включены в тестирование интеграции?
СТРАТЕГИИ ИНТЕГРАЦИИ
Существует несколько подходов к тестированию интеграции. Эти подходы зависят от того, как
интегрируется приложение. Ниже приводятся некоторые из часто используемых технологий.
Одновременная интеграция. Очень маленькие системы часто интегрируются и тестируются в один этап.
Это позволяет эффективно использовать ресурсы тестирования, поскольку отсутствует дополнительная
нагрузка, связанная с созданием заглушек и драйверов для выполнения модульного тестирования или
частичной интеграции. Возьмем, к примеру, простое приложение калькулятора: обычно оно состоит из
пользовательского интерфейса и компонента арифметической логики. Поскольку приложение
маленькое, намного проще сосредоточить ресурсы на тестировании целого приложения, чем
тестировать отдельные компоненты и интегрировать их.
РИС. 7. ОДНОВРЕМЕННАЯ ИНТЕГРАЦИЯ
Для большинства реальных или больших систем одновременное тестирование нецелесообразно.
Система даст сбои в стольких местах сразу, что выполнить отладку и повторное тестирование будет
просто невозможно. Для больших систем может потребоваться множество этапов интеграции, начиная
со сборки модулей в низкоуровневые подсистемы, сборки подсистем в крупные подсистемы и
заканчивая сборкой подсистем высшего уровня в целую систему.
Нисходящая интеграция. Нисходящая стратегия начинается с высокоуровневых модулей и
тестирования их интеграции. Она позволяет заранее протестировать потоки данных высокоуровневых
компонентов. Однако в этом подходе часто приходится использовать заглушки для нереализованных
функций, и он не помогает тестировать ранние выпуски продуктов с ограниченными функциями.
Такой подход можно применить к приложению для работы с фотографиями. Можно начать с
проектирования пользовательского интерфейса, жестко закодировав все пути к изображениям на
компьютере. Следующим компонентом может стать компонент проверки подлинности для доступа к
интерактивному фотоальбому. В ходе тестирования интеграции можно проверить взаимодействие
пользовательского интерфейса с компонентом проверки подлинности. Следующим этапом разработки
может стать компонент получения и кэширования фотографий.
РИС. 8. НИСХОДЯЩАЯ ИНТЕГРАЦИЯ
Восходящая интеграция. Стратегия восходящей интеграции начинается с низкоуровневых модулей. Она
позволяет заранее протестировать эти взаимодействия и устраняет необходимость в заглушках. Обычно
при этом требуется, чтобы драйверы запускали данные модули. Такой подход не обеспечивает
достаточной поддержки ранних выпусков с ограниченной функциональностью.
РИС. 9. ВОСХОДЯЩАЯ ИНТЕГРАЦИЯ
Смешанная интеграция. В стратегии смешанной интеграции нисходящие тесты используются для
верхних уровней структуры программы, а восходящие — для более низких уровней.
Интеграция по уровню важности. При этом подходе сначала интегрируются самые важные
компоненты, а все остальное добавляется потом. Это гарантирует работоспособность наиболее важных
компонентов, однако может усложнить интеграцию системы для других компонентов.
ДОПОЛНИТЕЛЬНЫЕ РЕСУРСЫ



http://www.exforsys.com/tutorials/testing/integration-testing-whywhathow.html
http://www.softwaretestingstuff.com/2008/12/integration-testing-four-step-procedure.html
http://www.softwaretestingstuff.com/2008/12/how-to-do-integration-testing-writing.html
ТЕСТИРОВАНИЕ СЦЕНАРИЕВ
Тестирование сценариев позволяет оценить, сможет ли пользователь успешно выполнить в продукте ту
или иную задачу от начала до конца. Тестирование сценариев и интеграции — это взаимосвязанные
методологии, служащие для тестирования нескольких модулей продукта, чтобы оценить их
взаимодействие. Тестирование интеграции обычно проводится для проверки корректного
взаимодействия нескольких модулей, тогда как при тестировании сценариев проверяется корректность
комплексных сценариев работы пользователей. Оба вида тестирования отражают реальное
использование продукта.
Например, в практической лабораторной работе по приложению Southridge Realty предлагается
множество различных вариантов тестирования сценариев и интеграции. Тесты интеграции могут
включать несколько модулей: создание и обслуживание профилей, обработка условий поиска,
результаты поиска, отображение данных, контакты клиента и общая корректность пользовательского
интерфейса. В тесте сценария на основе нескольких модулей проверяется сценарий работы
пользователя от создания нового профиля со сложными условиями поиска до отображения результатов
на карте, их распечатки и отправки клиенту по электронной почте.
ПРЕИМУЩЕСТВА ТЕСТИРОВАНИЯ СЦЕНАРИЕВ
Тесты сценариев обеспечивают следующие важные преимущества:




являются средством экспериментального исследования и помогают инженерам-тестировщикам
ознакомиться с продуктом;
позволяют убедиться, что основные требования пользователей успешно выполняются;
могут использоваться для нагрузочных тестов, при тестировании надежности и
производительности;
выявляют проблемы и поднимают новые вопросы, связанные с проектированием.
ПОДХОД К ТЕСТИРОВАНИЮ СЦЕНАРИЕВ
При проектировании сценариев следует придерживаться следующих принципов:



Сценарий должен рассказывать о пользователе и его мотивах применения продукта.
Рассказ должен мотивировать, иллюстрируя одно или несколько основных требований, которым
должна удовлетворять программа.
Рассказ должен быть правдоподобным: описанная ситуация должна быть возможна в
реальности.


Рассказ должен демонстрировать сложный или экспертный уровень использования продуктов
для сложных программ либо интуитивно понятный — для простых.
Результаты тестирования должны оцениваться максимально просто. Это очень важно, учитывая
сложную структуру сценария. Инженеры-тестировщики могут запросто одобрить любое
приемлемое поведение: чтобы этого не случилось, результаты должны быть точными и легко
проверяемыми.
Полезны и негативные сценарии. Сценарии, демонстрирующие вредоносное злоупотребление
возможностями программы (например, попытки нарушить требования безопасности), должны давать
сбой и не предоставлять сведений, как создать успешный сценарий для такой операции. Сценарии,
показывающие случайное неправильное использования (например, использование неверной функции
для выполнения правомерной задачи), должны либо помогать пользователю найти нужную функцию,
либо предлагать пересмотр проектных решений, в результате которых стал возможен такой сценарий.
При создании сценариев следует учитывать различные аспекты. Сэм Канер (Cem Kaner) предлагает 12
способов создания сценариев:
1. Написать комплексные истории для объектов в системе.
2. Перечислить возможных пользователей, проанализировать их интересы и цели.
3. Учесть нежелательных пользователей: каковы варианты применения системы не по
назначению?
4. Перечислить ожидаемые события. Как система обрабатывает их?
5. Перечислить необычные события. Как система адаптируется к их возникновению?
6. Перечислить преимущества системы и создать комплексные задачи для их проверки.
7. Опросить пользователей о наиболее частых проблемах и сбоях старой системы.
8. Взаимодействовать с пользователями, чтобы узнать, как они работают и что делают.
9. Прочесть о подобных системах и принципах их работы.
10. Изучить жалобы на предшествующую систему или конкурирующие решения.
11. Сыграть роль реального пользователя системы.
12. Использовать данные/сценарии от конкурирующих или предшествующих приложений на
текущей системе.
Примечание. Событие — это любое действие, реагирование на которое заложено в проекте системы. В
приложении Southridge Realty это отмена пользователем параметра поиска.
Хотя тестирование сценариев — это важный этап в тестировании приложения, здесь нужно соблюдать
меру. Необходимо выбрать надлежащее число сценариев, чтобы оправдать вложения.
ДОПОЛНИТЕЛЬНЫЕ РЕСУРСЫ
Сэм Канер (Cem Kaner), An Introduction to Scenario Testing
Сандип Кончади (Sandeep Konchady), What to Expect from User Scenario Testing
ТЕСТИРОВАНИЕ ВРУЧНУЮ, ЗАПИСЬ И
ВОСПРОИЗВЕДЕНИЕ ТЕСТОВ
В этом разделе рассматривается создание ручных и записанных тестов, включая следующие темы:



Преимущества и недостатки автоматизации теста.
Принципы написания хорошего ручного теста.
Запись ручного теста.
ПРЕИМУЩЕСТВА И НЕДОСТАТКИ АВТОМАТИЗАЦИИ ТЕСТА
Тестирование ПО началось именно с ручных тестов: разработчики просто выполняли ряд действий по
списку. И до сих пор ручное тестирование остается важным компонентом тестирования ПО.
При правильном использовании автоматизированные тесты очень удобны, но их сложно составлять и
обслуживать, а типы обнаруживаемых ими дефектов ограничены. Для создания автоматических тестов
требуются значительные инвестиции, будь то запись каждого теста с последующим платным
обслуживанием или дорогостоящее и тщательное проектирование набора тестов или модели продукта.
Рекомендуется разработать стратегию и в соответствии с ней принимать решения о том, что следует
автоматизировать, что выполнять вручную, а от чего вообще отказаться. Иначе тестирование может
быстро превратиться в основную статью расходов программного проекта.
Перед тем как автоматизировать тестирование, следует ответить на несколько вопросов:




Насколько важна функциональность, охватываемая данным тестом?
Как часто могут происходить сбои в работе этой функциональности? Она относительно
стабильна или чувствительна к условиям использования?
Насколько быстро требуется узнавать о проблеме, обнаруживаемой в ходе тестирования?
Насколько сложно автоматизировать и обслуживать тест?
Если тест служит для проверки важной функциональности, если эта функциональность нестабильна,
если об ошибках требуется узнавать быстро и если тест легко автоматизировать, то его действительно
следует автоматизировать. Если функциональность относительно стабильна и при надлежащей
настройке не дает сбоев, если об ошибках не обязательно узнавать сразу, если поведение меняется
часто (и в допустимых пределах) или если тест сложно автоматизировать и выполнять без ошибок, то,
вероятно, лучше выбрать тестирование вручную.
Например, в Visual Studio автоматизируются тесты, определяющие, попадает ли отладчик в точку
останова и правильно ли добавляются обработчики событий для элементов управления. Эти типы
функциональности часто дают сбои во время разработки, ошибки такого рода являются критическими, а
для создания тестов не требуется значительных усилий. Некоторые тесты, которые обычно не
автоматизируются, относятся к проверке правильной работы функций поиска и замены либо
возможности окрашивания текста в редакторе. Эти тесты проверяют стабильную функциональность,
которая редко дает сбои, а обнаруживаемые ими ошибки не требуют срочного устранения. Кроме того,
уже рассмотренное тестирование окрашивания сложно автоматизировать надлежащим образом по
сравнению с другими тестами Visual Studio.
ПРИНЦИПЫ НАПИСАНИЯ ХОРОШЕГО РУЧНОГО ТЕСТА
Ручной тест, по сути, представляет собой список операций, которые необходимо выполнить и проверить
в продукте. У ручных тестов две важные цели. Первая — обеспечить всеобщее понимание теста, а
вторая — добиться, чтобы в ходе проведения теста выполнялись действия и проверялись результаты
так, как запланировано.
Ниже приводятся некоторые рекомендации по созданию ручных тестов.




Создайте глоссарий, объясняющий специальную терминологию продукта или возможности.
Создайте документ, где обсуждаются известные проблемы, описываются способы различения
ошибок и допустимых изменений, а также объясняются способы выполнения комплексных
проверок для возможности (если необходимо).
При описании точной процедуры не упускайте детали ее выполнения. Например, добавьте
следующий комментарий, описывающий используемые в тесте действия: Добавьте кнопку к
началу окна, дважды щелкнув ее в панели инструментов.
Если точная процедура не важна, не вдавайтесь в подробности ее выполнения. Например, тест
может включать комментарий: Переместите значение в низ документа вместо более
подробного: Выберите значение, нажмите Ctrl+X, затем Ctrl+End и Ctrl+V.
Реструктурируйте этапы. Записывайте общие этапы в одном месте и ссылайтесь на их название.
Например, можно создать в общем расположении процедуру с названием «Создание нового
веб-проекта», включающую следующие инструкции:
1.
2.
3.
4.
5.
Закройте все открытые решения.
Выберите «Файл» -> «Создать веб-сайт».
Выберите в качестве шаблона «Веб-сайт по умолчанию».
Нажмите кнопку «ОК».
(И т. п.)
После создания этого общего набора инструкций в любом тесте, где требуются эти этапы, можно просто
сослаться на процедуру «Создание нового веб-проекта».

Подробно описывайте, что требуется проверить и что ожидается на каждом этапе. В следующих
примерах показаны сведения, которые можно включить в тест, в порядке возрастания
полезности.
1. Отформатируйте документ. (Плохо.)
2. Отформатируйте документ. Проверьте форматирование сценария. (Лучше.)
3. Отформатируйте документ. Проверьте, изменились ли интервалы в
выражениях в соответствии с параметрами Tools.Options. (Лучше всего.)
Обращайте внимание даже на результаты, проверка которых явно не указана в тесте. Элементы,
определенные в тесте, — это необходимый минимум для тестирования и проверки.
o
o
Как правило, в рамках одного теста следует сосредоточиться на одной возможности.
Составляйте тест так, чтобы до и после него не приходилось выполнять никаких действий.
Используйте предварительно созданное содержимое или тестовые данные для запуска теста,
чтобы сразу начать тестирование. Например, можно включить в тест предварительно созданную
страницу или форму, в которой уже содержатся тестовые данные. Затем можно написать
инструкции, как показано ниже:
1. Откройте файл FormattingSample.xaml. (В этом предварительно созданном окне
находятся тестовые данные.)
2. Выберите... и отформатируйте. Проверьте... (Тест-инженер может
переходить непосредственно к тестовому случаю.)

Проектируйте тест так, чтобы его можно было эффективно выполнить вручную, как показано в
следующих тестовых инструкциях:
1. Введите следующие 100 строк. (Плохо — для ввода 100 строк потребуется много
времени.)
2. Вставьте следующие 100 строк. (Лучше — это намного эффективнее.)
ЗАПИСЬ РУЧНОГО ТЕСТА
Если вы создали полезный ручной тест и впоследствии решили, что его стоит автоматизировать, можно
записать этапы тестирования с помощью технологии записи. Это довольно дешевый способ
автоматизации существующих тестов, однако при этом следует помнить некоторые моменты. В
следующих разделах приводятся рекомендации по записи тестов.
СТРУКТУРИРУЙТЕ ЭТАПЫ
Как и в случае с ручными тестами, структурируйте общие действия и записывайте их этапы в одном
месте, чтобы на них можно было сослаться по названию. Например, конкретные этапы создания вебсайта в Visual Studio постоянно менялись на протяжении всей разработки, и если были бы записаны
тысячи тестов, в каждом из которых содержалась бы копия этих этапов, то пришлось бы выполнить
огромный объем работ по их обслуживанию.
В рамках структуризации обратите внимание на обобщенные инструкции к ручному тесту. Например,
если в тесте нужно вставить данные, но не оговорен способ вставки, можно структурировать реализации
с различными типами вставки и впоследствии разнообразить эти структурированные инструкции (с
помощью Ctrl+V, из главного меню, из контекстного меню). Если в тесте не было конкретных сведений о
данных (например, просто предлагается изменить размер прямоугольника), структурируйте данные и в
дальнейшем варьируйте их по мере необходимости. Таким образом, автоматизированный тест не будет
слишком единообразным по сравнению с ручным эквивалентом.
ПРИ ВОЗМОЖНОСТИ РАЗДЕЛЯЙТЕ ДАННЫЕ
Если тест включает одни и те же этапы с разными данными (например, введите hello, затем StRANge),
запишите эти этапы один раз, а затем структурируйте код, чтобы разделить данные. Таким образом вы
сможете добавлять другие значения, не усложняя обслуживание тестов, если этапы впоследствии
изменятся.
ДОБАВЬТЕ НУЖНУЮ ЛОГИКУ ПРОВЕРКИ
В запись теста включаются только сами действия, а не проверка. После записи этапов тестирования
необходимо самостоятельно добавить соответствующую проверку. Нередко эта часть автоматизации
оказывается самой дорогой, поскольку порой намного сложнее выяснить, как прочесть состояние
приложения, чем интерпретировать сами взаимодействия.
Поэтому рекомендуется создавать общий код для извлечения состояния из тех частей продукта,
которые подвергаются расширенному тестированию. Например, можно написать код, чтобы извлечь
текст из редактора в Visual Studio. Затем можно предоставить к этому коду тестирования состояния
общий доступ со стороны различных тестов. Логика для чтения состояния может потребовать частого
изменения, поэтому дублировать ее не рекомендуется.
Внимательно продумайте охват проверки: каков объем проверяемого состояния продукта? Люди
отлично справляются с проверкой, однако достичь такого же уровня проверки в автоматизированном
тесте с малыми затратами невозможно. Просмотрите найденные дефекты и сделайте так, чтобы они
обнаруживались и в ходе автоматической проверки. (Например, если после определенного этапа
тестирования команда вставки выключается, проверяется ли, что элементы меню становятся
доступными и недоступными, как запланировано?)
Также обдумайте подробность проверки. Если в ручном тесте требуется проверить, соответствует ли
форматирование текста параметрам, указанным в Tools.Options, то человек обычно смотрит не только
на одну изменившуюся строку. Должен ли тест проверять, что все остальное осталось без изменений?
Должен ли тест проверять, изменилось ли написание прописными буквами в словах? Если проверяется
каждая деталь документа после форматирования, будет ли изменяться форматирование по мере
разработки продукта, вынуждая обновлять тест?
ВЫБИРАЙТЕ НАДЕЖНЫЕ ДЕЙСТВИЯ
В некоторых случаях в исходном ручном тесте могут быть действия, которые сложно автоматизировать.
Попробуйте заменить их действиями, которые более удобны для автоматизации, либо ограничьте
количество выполнения этих действий в ходе тестирования. Если конкретный способ взаимодействия с
приложением не имеет значения для тестирования, выберите более надежную альтернативу: это
поможет сократить число сбоев теста, не связанных с проблемами продукта. Модель автоматизации
пользовательского интерфейса не является абсолютно надежной, и множество сложных действий часто
увеличивает объем обнаруживаемых ошибок.
Вот некоторые сложные действия:





перетаскивание;
ввод длинных строк символов;
действия по наведению мыши (пример: поиск подсказки);
прокрутка;
перемещение по меню (пример: перемещение мыши, ожидание, перемещение мыши и др.).
Для всех этих действий поток событий, создаваемых в Windows при выполнении этих жестов человеком,
оказывается довольно длинным (множество событий мыши или нажатий клавиш). И чем длиннее такой
поток действий, тем сложнее автоматизировать действия надлежащим образом. В длинном потоке
действий, где автоматизация работает быстрее человеческих движений, различия в поведении могут
появляться просто из-за разницы во времени выполнения этих действий.
Кроме того, многие действия могут быть трудными для пользователей (или просто выполняться
медленнее). Чтобы решить эту проблему, можно спроектировать продукт с более быстрыми
альтернативными возможностями, которые могут использоваться как обычными людьми, так и
автоматическими тестами. К этим альтернативам относятся сочетания клавиш для команд меню,
частичный ввод значений для перехода к интересующему элементу и др.
ДОБАВЬТЕ ПРОДУМАННУЮ ЛОГИКУ ОЖИДАНИЯ
Записанные тесты часто выполняют действия намного быстрее, чем человек при ручном тестировании.
Некоторые среды тестирования позволяют имитировать задержки, свойственные ручному
тестированию. Однако при этом тесты будут выполняться медленнее, и продукт может оказаться не
готов для каждого последующего этапа теста.
Как правило, задач, требующих ожидания, не так уж много, поэтому можно написать для них общий
код. (Типичные примеры: «Дождитесь создания проекта» или «Дождитесь окончания загрузки
редактора».) Важно структурировать этот код и хранить его в одном месте, поскольку он обычно
относится к той части автоматизированного теста, которая чаще всего изменяется. При хорошей
структурированности можно заменить изначально неверную стратегию (например, ожидать в течение
того же времени, что и человек) улучшенной, как только она будет разработана.
Самый простой тип ожидания, который доступен в платформах модели автоматизации
пользовательского интерфейса, — это ожидание появления элемента интерфейса. Например, если
щелкнуть «Правка» -> «Найти», чтобы затем ввести текст в поле «Найти», нужно лишь дождаться
появления диалогового окна «Найти».
Еще одна простая стратегия ожидания — дождаться, пока значение будет считано методами проверки.
Например, если в ходе теста в текстовое поле вводится длинное значение и нужно убедиться, что это
значение введено полностью, то проще всего проверить это, периодически считывая значение из
текстового поля, пока не обнаружится нужное значение или не истечет разумный промежуток времени.
Если для действия требуется логика ожидания, другим действиям также, вероятно, потребуется
аналогичная логика ожидания. В этом случае во всех тестах с таким действием должна использоваться
одна и та же логика ожидания. Рекомендуется структурировать саму логику ожидания и действие,
которому требуется ожидание, а также запрограммировать прямой вызов логики ожидания таким
действием. В этом случае во всех тестах, включающих это действие, будет использоваться логика
ожидания, отражающая наилучшую стратегию. А другие действия, которым нужна эта логика, могут
совместно использовать лучшую реализацию. Со временем реализации стратегий ожидания и
используемой стратегии, вероятно, будут меняться.
СРЕДСТВА
В этом разделе приводится предварительный список средств, доступных для создания, отладки,
профилирования и тестирования приложений WPF. В текущем выпуске документа описываются
средства для профилирования производительности. Другие средства будут рассмотрены в следующих
выпусках.
TESTAPI
TestApi — это библиотека API тестирования и служебных программ, с помощью которых разработчики и
инженеры-тестировщики могут создавать автоматизированные тесты для приложений WPF, Windows
Forms, .NET Framework и Win32. Разработка библиотеки спонсируется командой WPF в Microsoft.
Библиотека TestApi включает набор простых, документированных, разложенных на компоненты и
многоуровневых API тестирования, дополняющих это руководство и материалы, доступные в блоге WPF
Testing.
В пакет TestApi входят следующие элементы:




Двоичные файлы. Двоичные и символьные файлы предназначены для непосредственного
включения в проекты.
Документация, в том числе документы по API в стиле статей MSDN и концептуальные документы
общего характера, описывающие области и шаблоны тестирования.
Исходный код. Весь исходный код библиотеки выпускается по лицензии Ms-PL license.
Примеры кода. Примеры целых проектов с пошаговой документацией, демонстрирующие
использование библиотеки в популярных наборах тестов, таких как Visual Studio Team System,
NUnit и xUnit.
Библиотека доступна на странице http://www.codeplex.com/testapi. Сегодня библиотека TestApi
охватывает следующие области, что поможет вам сэкономить массу времени при создании тестов:






API внедрения входных данных;
API визуальной проверки;
API автоматического контроля приложений;
полнофункциональное средство синтаксического анализа командной строки;
модули поддержки диспетчера WPF;
модули поддержки модели автоматизации пользовательского интерфейса.
По мере развития библиотеки будут предоставляться API для других областей. Схема возможностей
доступна на странице http://codeplex.com/testapi.
В примере ниже показано использование TestApi в автоматизированных тестах.
ПРИМЕР TESTAPI 1. ВНЕДРЕНИЕ ВХОДНЫХ ДАННЫХ
Внедрение входных данных — это имитация ввода данных пользователем. В примере кода показано,
как использовать доступные в TestApi классы Mouse и Keyboard для имитации ввода данных
пользователем:
//
// EXAMPLE:
// Discover the location of a TextBox with a given name, then simulate a
mouse click
// and keyboard input on it
//
string textboxName = “ssnInputField”;
AutomationElement textBox = AutomationUtilities.FindElementsByName(
AutomationElement.RootElement,
textboxName)[0];
Point textboxLocation = textbox.GetClickablePoint();
//
// Move the mouse to the textbox, click, then type something
//
Mouse.MoveTo(textboxLocation);
Mouse.Click();
Keyboard.Type(“Hello world. ”);
Keyboard.Press(Key.Shift);
Keyboard.Type(“hello, capitalized world.”);
Keyboard.Release(Key.Shift);
Дополнительные сведения см. в документации по TestApi или в статье Introduction to TestApi – Part 1:
Input Injection APIs.
ПРИМЕР TESTAPI 2. СИНТАКСИЧЕСКИЙ АНАЛИЗ КОМАНДНОЙ СТРОКИ
В библиотеке TestApi содержится многоуровневый API синтаксического анализа командной строки,
основанный на использовании классов CommandLineDictionary и CommandLineParser. В
нижеприведенном коде показаны базовые возможности синтаксического анализа командной строки,
доступные в библиотеке:
//
// EXAMPLE: Parsing a command-line such as "RunTests.exe /verbose
/testId=123"
//
using System;
using Microsoft.Test;
public class Program
{
public static void Main(string[] args)
{
CommandLineDictionary d = new CommandLineDictionary(args);
bool verbose = d.ContainsKey("verbose");
int testId = Int32.Parse(d["testId"]);
// use the parsed command-line parameters
}
}
Также в библиотеке TestApi содержатся возможности для синтаксического анализа командной строки со
строгой типизацией, как показано в коде ниже:
//
// EXAMPLE:
// Sample for parsing the following command-line:
// Test.exe /verbose /runId=10
// This sample declares a class in which the strongly typed arguments are
populated
//
public class CommandLineArguments
{
bool? Verbose { get; set; }
int? RunId { get; set; }
}
CommandLineArguments a = new CommandLineArguments();
CommandLineParser.ParseArguments(a, args);
Дополнительные сведения см. в документации по TestApi или в статье Introduction to TestApi – Part 2:
Command-Line Parsing APIs.
ПРИМЕР TESTAPI 3. ВИЗУАЛЬНАЯ ПРОВЕРКА
Визуальная проверка служит для подтверждения того, что приложение или его компонент корректно
визуализируется на экране. В библиотеке TestApi доступен практически полный набор API визуальной
проверки. В следующем примере демонстрируется один из имеющихся подходов визуальной проверки,
основанный на использовании классов Snapshot и ShapshotToleranceMapVerifier:
//
// EXAMPLE: Verify the correct display of a window.
//
// Take a snapshot, compare to the master image and generate a diff
Snapshot actual = Snapshot.FromWindow(hwndOfYourWindow, );
Snapshot expected = Snapshot.FromFile("Expected.png"));
Snapshot difference = actual.CompareTo(expected);
// Load the tolerance map. Then use it to verify the difference snapshot
Snapshot toleranceMap = Snapshot.FromFile("ExpectedImageToleranceMap.png");
SnapshotVerifier v = new SnapshotToleranceMapVerifier(toleranceMap);
if (v.Verify(difference) == VerificationResult.Fail)
{
// Log failure, and save the actual and diff images for investigation
actual.ToFile("Actual.png", ImageFormat.Png);
difference.ToFile("Difference.png", ImageFormat.Png);
}
Дополнительные сведения см. в документации по TestApi или в статье Introduction to TestApi – Part 3:
Visual Verification APIs.
СРЕДСТВА АВТОМАТИЗАЦИИ ПОЛЬЗОВАТЕЛЬСКОГО ИНТЕРФЕЙСА
В следующем списке содержатся сведения о средствах автоматизации пользовательского интерфейса.




UI Spy (UISpy.exe) — это приложение с графическим интерфейсом пользователя, с помощью
которого можно собирать сведения модели автоматизации пользовательского интерфейса для
разработки и отладки со стороны поставщика и клиента. Средство UI Spy входит в пакет Windows
SDK.
UIAutoCmd — это программа командной строки с возможностями, аналогичными UI Spy.
Платформа автоматизации тестирования UIA Verify — платформа автоматизации тестирования,
включающая библиотеку UIA Test Library и средство с графическим интерфейсом пользователя
Visual UIA Verify.
UI Accessibility Checker (или AccChecker) — средство, с помощью которого инженерытестировщики без опыта работы со специальными возможностями могут легко обнаружить
потенциальные проблемы с MSAA и другие проблемы доступности в реализациях
пользовательского интерфейса.



MSAABridge — средство предоставляет сведения модели автоматизации пользовательского
интерфейса клиентам Active Accessibility. Основная цель установки взаимосвязи модели
автоматизации пользовательского интерфейса и Active Accessibility — предоставить
существующим клиентам Active Accessibility возможность взаимодействовать с любой
платформой, реализующей модель автоматизации пользовательского интерфейса.
NUnit совместно с платформой модели автоматизации пользовательского интерфейса служит
для выполнения модульного тестирования элементов управления WPF.
Платформа тестирования пользовательского интерфейса White — расширение с открытым
исходным кодом для платформы тестирования NUnit с открытым исходным кодом. Для доступа
к страницам и элементам пользовательского интерфейса в целях тестирования в средстве
используется пространство имен System.Windows.Automation. Оно поддерживает тестирование
приложений Win32, Win Form, WPF и SWT (java).
В следующем списке содержатся сведения о сторонних средствах автоматизации пользовательского
интерфейса, которые часто используются за пределами Microsoft:

TestComplete. Это средство поддерживает тестирование приложений XAML/WPF.
СРЕДСТВА ОТЛАДКИ
В следующем списке содержатся сведения о средствах отладки для WPF:




Snoop. Это средство отладки приложений WPF, упрощающее визуальную отладку приложений
WPF.
Mole for Visual Studio, авторы Карл Шиффлетт (Karl Shifflett), Джош Смит (Josh Smith) и Эндрю
Смит (Andrew Smith): визуализатор Visual Studio, с помощью которого пользователи могут
осуществлять анализ и редактирование объектов во время выполнения.
Crack.NET, автор Джош Смит (Josh Smith): визуализатор-отладчик, с помощью которого
пользователи могут просматривать и изменять объекты управляемой кучи во время
выполнения. Сочетает в себе возможности средств Snoop и Mole.
WinDBG с расширением SOS от Microsoft: низкоуровневое средство отладки с простым
графическим интерфейсом пользователя. Расширение SOS, поставляемое с .NET,
добавляет специальную поддержку управляемой отладки.
СРЕДСТВА ПРОФИЛИРОВАНИЯ ПРОИЗВОДИТЕЛЬНОСТИ
В следующем списке содержатся сведения о средствах профилирования производительности для WPF:






Средства профилирования производительности для WPF от Microsoft.
Event Trace. Используется для анализа событий и создания файлов журнала событий.
Perforator. Используется для анализа поведения визуализации.
ETW Trace Viewer. Используется для записи, отображения и просмотра файлов журнала
трассировки событий Windows (ETW) в формате пользовательского интерфейса WPF.
Visual Profiler. Используется для профилирования работы служб WPF по элементам в визуальном
дереве, таким как разметка и обработка событий.
Working Set Analyzer. Используется для анализа характеристик рабочего множества
приложения.


.NET Memory Profiler от SciTech Software: средство, позволяющее обнаружить утечку и улучшить
использование памяти благодаря ручной проверке, снимкам памяти, профилированию памяти и
автоматическому тестированию.
CLR Profiler от Microsoft: средство профилирования памяти, отображающее сведения об
управляемых выделениях; имеет ограниченную функциональность по сравнению со
средством .NET Memory Profiler, но доступно для бесплатной загрузки.
СРЕДСТВА РАЗРАБОТКИ И ПРОЕКТИРОВАНИЯ ПРИЛОЖЕНИЙ WPF
В следующей таблице содержатся сведения о нескольких средствах создания приложений WPF:
Expression Design, Expression Blend и Visual Studio 2008. В ней перечислены области WPF, которые
поддерживаются этими средствами.
Expression Design
Expression Blend
Visual Studio 2008
Динамическая
Разметка
Статическая,
абсолютное
расположение
Стили
Нет
Визуальный
редактор
Нет
Шаблоны
Нет
Визуальный
редактор
Нет
Ресурсы
Как параметр
экспорта
Визуальный
редактор
Нет
Поддержка кода
Нет
Базовый
редактор
Многофункциональный
IntelliSense
Круговой путь XAML
В одну сторону
Да
Да
Да
Экспорт XAML
Раннее ограничение
возможностей во
избежание потерь
Анимация
Нет
Динамическая
Да
Визуальный
редактор
Только редактор XAML
Дополнительные сведения о средствах разработки и проектирования для WPF см. на веб-сайте Windows
Client в техническом документе New Iteration, авторы Карстен Янушевский (Karsten Januszewski) и Хайме
Родригес (Jaime Rodriguez).
СРЕДСТВА РЕДАКТИРОВАНИЯ XAML И НАДСТРОЙКИ VISUAL STUDIO
В следующем списке содержатся сведения о дополнительных средствах создания приложений WPF:

XAML Power Toys. Надстройка для нескольких доменов приложения Visual Studio 2008 SP1,
которая расширяет функциональность редактора XAML и позволяет разработчикам выполнять



разметку форм бизнес-приложений и обслуживать их с помощью элементов управления
пользовательского интерфейса из WPF и Silverlight, включая набор WPF Toolkit.
XAMLPad. Базовый визуальный редактор XAML.
ZAM 3D от Electric Rain. С помощью этого средства разработчики и проектировщики могут быстро
и легко создавать трехмерные элементы интерфейса для приложений WPF. Также содержит
конвертеры 3D — XAML и dxf — XAML.
XamlCruncher, автор Чарльз Петцольд (Charles Petzold). Редактор XAML, аналогичный XamlPad и
визуализирующий объекты в реальном времени. Это решение с открытым исходным кодом
расширяет возможности XamlPad.
ДРУГИЕ ПОЛЕЗНЫЕ СРЕДСТВА ДЛЯ РАЗРАБОТЧИКОВ И ТЕСТЕРОВ
WPF
В следующем списке содержатся сведения о дополнительных средствах создания приложений WPF:




Reflector для .NET. Это средство просмотра, обзора и анализа классов, а также просмотра
документации для типов .NET Framework. С его помощью можно выполнять просмотр,
навигацию, поиск, декомпиляцию и анализ сборок .NET Framework, созданных на языках C# или
Visual Basic либо на MSIL.
Trace sources in WPF. В этой записи блога содержится руководство по добавлению различных
источников трассировки, доступных в WPF, чтобы получить сведения отладки о приложении.
ShowMeTheTemplate!. Средство для исследования шаблонов (данных, элементов управления,
панелей элементов и др.), которые поставляются со встроенными в WPF элементами
управления.
WPF Content Control Viewer. Средство для получения содержимого элемента управления.
РЕСУРСЫ
Будет рассмотрено в следующих выпусках.
БЛАГОДАРНОСТИ
Авторы хотели бы поблагодарить за помощь в работе над этим документом следующих специалистов
(имена указаны в алфавитном порядке).
Автор
Разделы
Алексис Руза (Alexis Roosa)
«Тестирование стабильности и нагрузочное тестирование», «Средства»,
рецензент
Алик Хавин (Alik Khavin)
«Тестирование глобализации и локализации»
Андре Нидэм (Andre
Needham)
«Тестирование безопасности»
Энн Гао (Anne Gao)
«Введение», «Введение в тестирование программного обеспечения»,
«Введение в программный комплекс WPF», «Методология,
планирование и стратегии тестирования», «Тестирование
пользовательского интерфейса», «Тестирование специальных
возможностей», «Пользовательские элементы управления и
тестирование расширяемости», «Средства», пример решения
Атанас Коральски (Atanas
Koralski)
«Пользовательские элементы управления и тестирование
расширяемости», рецензент
Иво Манолов (Ivo Manolov)
Идея и структура документа, «Введение», «Введение в программный
комплекс WPF», «Управляемое данными тестирование», рецензент
Лестер Лобо (Lester Lobo)
Пример обнаружения элементов пользовательского интерфейса,
пример проекта, «Тестирование интеграции и сценариев», рецензент
Натан Андерсон (Nathan
Anderson)
«Тестирование интеграции и сценариев»
Масахико Канеко (Masahiko
Kaneko)
«Тестирование специальных возможностей», рецензент
Майкл Хантер (Michael
Hunter)
«Введение в тестирование программного обеспечения», «Методология,
планирование и стратегии тестирования», рецензент
Мэтт Гэлбрейт (Matt
Galbraith)
Пример обнаружения элементов пользовательского интерфейса,
рецензент
Пу Ли (Pu Li)
«Тестирование мультимедиа»
Ранджеш Джаганатан
(Ranjesh Jaganathan)
«Тестирование интеграции и сценариев»
Стивен Гэлик (Steven Galic)
«Визуальная проверка мультимедиа», «Проверка анимации и других
переходов»
Тим Коули (Tim Cowley)
«Тестирование специальных возможностей»
Варша Махадеван (Varsha
Mahadevan)
«Пользовательские элементы управления и тестирование
расширяемости», рецензент
Рецензенты: Алан Пейдж (Alan Page), Engineering Excellence, Брайан Макмастер (Brian McMaster), Client
Development Tools, Кором Томпсон (Corom Thompson), Деннис Ченг (Dennis Cheng), Джон Госсман (John
Gossman), Джейсон Гривз (Jason Grieves), WEX PM, Лора Руби (Laura Ruby), TwC Solutions & Outreach,
Майкл Шим (Michael Shim), Патрик Данино (Patrick Danino), Пол Хэррингтон (Paul Harrington),
разработчик на платформе Visual Studio, Роб Релиа (Rob Relyea), Скотт Луво (Scott Louvau), команда Web
Development Tools, Шон Хейс (Sean Hayes), Accessible Technology, Шозуб Квиреши (Shozub Qureshi),
Стивен Кой (Stephen Coy), Зия Рахман Мохаммад (Zia Rahman Mohammad).
Редактор: Майк Поуп (Mike Pope), команда ASP.NET User Education, Дэвид Карлсон (David Carlson),
команда .NET Framework User Education.
ПРИЛОЖЕНИЯ
ПРИЛОЖЕНИЕ 1. СОЗДАНИЕ НАБОРА ДЛЯ ТЕСТИРОВАНИЯ
ПРИЛОЖЕНИЙ WPF С ПОМОЩЬЮ VISUAL STUDIO TEAM SYSTEM
VSTS (Visual Studio Team System), NUnit и xUnit — это окружения теста, на основе которых можно создать
комплексные наборы для тестирования приложений WPF. В этом разделе приводятся краткий обзор
этих платформ и инструкции по созданию и развертыванию набора тестирования WPF.
VSTS — это более многофункциональная платформа по сравнению с NUnit и xUnit, которая
предоставляет возможности управления версиями, трассировки рабочих элементов и ошибок, создания
отчетов и выполнения анализа, не доступных в средах NUnit и xUnit и потому не обсуждаемых здесь. В
платформе также доступны функции ручного тестирования.
В библиотеке TestApi (http://codeplex.com/TestApi) содержатся примеры тестов приложений WPF,
разработанных в средах MSTest/VSTS, NUnit и xUnit, а также большая часть содержимого, включенного в
этот документ.
КРАТКОЕ РУКОВОДСТВО ПО ПЛАТФОРМАМ MSTEST / VSTS
Visual Studio Team System (VSTS) — это комплексная платформа для создания и управления
автоматизированными и ручными тестами. В платформе VSTS доступны функции модульного
тестирования, как через интерфейс, интегрированный в саму программу Visual Studio (см. Пошаговое
руководство. Создание и запуск модульных тестов), так и в простой программе командной строки
MSTest.
Тестирование модулей в Visual Studio имеет несколько разных названий: VSTS, MSTest и VSUnit. В
данном документе эта возможность именуется MSTest.
Тесты MSTest обычно упаковываются в библиотеку DLL. Класс может предоставлять один или несколько
методов тестирования. Основные правила создания теста MSTest довольно просты:




Любой класс, содержащий методы теста, должен быть помечен атрибутом [TestClass].
Методы теста помечаются атрибутом [TestMethod].
Результаты тестирования проверяются с помощью методов класса Assert (например,
Assert.IsTrue).
Ожидаемые исключения помечаются атрибутом [ExpectedException], применяемым к методу,
где ожидается исключение.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class SampleTests
{
// The following test demonstrates the use of Assert methods to assert
an
// expected test result.
[TestMethod]
public void TestThatAlwaysPasses()
{
Assert.IsTrue(10 > 5, "10 is greater than 5 (still!)");
}
// The following test demonstrates the use of the [ExpectedException]
attribute
// to assert that an expected exception is thrown within the test
method.
[TestMethod]
[ExpectedException(typeof(ApplicationException))]
public void TestThatExpectsAnException()
{
SomeThrowingMethod();
}
private void SomeThrowingMethod()
{
throw new ApplicationException();
}
}
Тестовый проект должен включать пространство имен Microsoft.VisualStudio.TestTools.UnitTesting и
ссылаться на следующие библиотеки DLL:


Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.dll
КРАТКОЕ РУКОВОДСТВО ПО ПЛАТФОРМЕ NUNIT
NUnit — это, вероятно, самая популярная бесплатная среда для модульного тестирования приложений
.NET. Ее можно загрузить с веб-сайта http://nunit.org. Дополнительные сведения содержатся в разделе
NUnit Quick Start для текущего стабильного выпуска. Краткое руководство для выпуска 2.4.8 (последний
стабильный выпуск на момент написания этого документа) доступно по адресу
http://nunit.org/index.php?p=quickStart&r=2.4.8.
Тесты NUnit упаковываются в библиотеку DLL. Класс может предоставлять один или несколько методов
тестирования. Основные правила создания теста NUnit довольно просты:




Любой класс, содержащий методы теста, должен быть помечен атрибутом [TestFixture].
Методы теста помечаются атрибутом [Test].
Результаты тестирования проверяются с помощью методов класса Assert (например,
Assert.IsTrue).
Ожидаемые исключения помечаются атрибутом [ExpectedException], применяемым к методу,
где ожидается исключение.
using System;
using NUnit.Framework;
[TestFixture]
public class SampleTests
{
// The following test demonstrates the use of Assert methods to assert
an
// expected test result.
[Test]
public void TestThatAlwaysPasses()
{
Assert.IsTrue(10 > 5, "10 is greater than 5 (still!)");
}
// The following test demonstrates the use of the [ExpectedException]
attribute
// to assert that an expected exception is thrown within the test
method.
[Test]
[ExpectedException(ExceptionType=typeof(ApplicationException))]
public void TestThatExpectsAnException()
{
SomeThrowingMethod();
}
private void SomeThrowingMethod()
{
throw new ApplicationException();
}
}
Тестовый проект должен включать пространство имен NUnit.Framework и ссылаться на библиотеку
NUnit.Framework.dll.
КРАТКОЕ РУКОВОДСТВО ПО ПЛАТФОРМЕ xUNIT
xUnit — это бесплатная платформа для модульного тестирования, стимулом для создания которой стала
среда NUnit. xUnit доступна по адресу http://codeplex.com/xunit и имеет следующие преимущества:



упрощает разработку модульных тестов, не требуя использования лишних атрибутов;
обладает дополнительными возможностями, такими как управление состоянием и поддержка
транзакций, управляемое данными тестирование и тестирование на основе спецификаций, а
также функция трассировки;
использует новые возможности .NET Framework, такие как универсальные шаблоны, анонимные
делегаты и методы расширения.
Дополнительные сведения см. в статье Why did we build xUnit.net?. Краткое сравнительное
исследование см. в публикации How does xUnit.net compare to other .NET testing frameworks?
Тесты xUnit упаковываются в библиотеку DLL. Класс может предоставлять один или несколько методов
тестирования. Загрузчик xUnit проходит все классы в библиотеке DLL и выполняет те, которые содержат
методы теста.
Основные правила создания теста xUnit довольно просты:




Методы теста помечаются атрибутом [Fact].
Результаты тестирования проверяются с помощью методов класса Assert (например,
Assert.True).
Ожидаемые исключения помечаются методом Assert.Throws.
Методы управляемого данными теста помечаются атрибутом [Theory] (вместо [Fact]).
Специальные варианты предоставляются с атрибутом [InlineData(…)].
Следующий простой класс показывает тестовый код xUnit:
using System;
using Xunit;
using Xunit.Extensions;
public class VisualVerificationTests
{
// The following two tests demonstrate the use of Assert methods
// to assert an expected test result.
[Fact]
public void TestThatAlwaysPasses()
{
Assert.True(10 > 5, "10 is greater than 5 (still!)");
}
[Fact]
public void TestThatExpectsAnException()
{
Assert.Throws<ApplicationException>(
delegate
{
SomeThrowingMethod();
});
}
private void SomeThrowingMethod()
{
throw new ApplicationException();
}
// The following test demonstrates the use of the [Theory] attribute
// and the [InlineData] attribute to enable data-driven tests.
[Theory]
[InlineData("WA", 98103)]
[InlineData("WA", 98052)]
[InlineData("CA", 90010)]
public void TestWithVariations(string state, int zip)
{
Assert.InRange<int>(zip, 10000, 99999);
}
}
Тестовый проект должен включать пространство имен Xunit и ссылаться на библиотеку xunit.dll. Для
поддержки управляемых данными тестов тест должен также включать пространство имен
Xunit.Extensions и ссылаться на библиотеку xunit.extensions.dll.
РЕКОМЕНДАЦИИ ПО СОЗДАНИЮ НАБОРА ДЛЯ ТЕСТИРОВАНИЯ ПРИЛОЖЕНИЙ
WPF
В целом создание набора для тестирования приложений и компонентов WPF не отличается от создания
набора для тестирования любого приложения .NET Framework. Ниже приводится ряд важных факторов,
которые следует учитывать при создании набора для тестирования приложений WPF.
Внутрипроцессное и внепроцессное тестирование
Обычно набор для тестирования приложений WPF состоит из модульных тестов, внутри- и
внепроцессных функциональных тестов и тестов сценариев, а также различных «фундаментальных»
тестов (таких как тесты производительности и нагрузочные тесты). Внутри- и внепроцессные
функциональные тесты и тесты сценариев — это важная категория тестов со своими проблемами и
особенностями.
Обычно для надлежащего охвата тестированием приходится использовать комбинацию внутри- и
внепроцессных тестов. Внепроцессные тесты могут быть более реалистичными, но связаны с
дополнительной необходимостью синхронизации (мониторинг целевого приложения, реагирование на
события). Внутрипроцессные тесты легко интегрируются в приложение, но часто требуют создания
внутреннего фасада тестирования во избежание непреднамеренных зависимостей от внутренних
компонентов приложения, что может снизить удобство поддержки тестов.
В библиотеке TestApi (http://codeplex.com/TestApi) содержатся API тестирования, специально
предназначенные для вне- и внутрипроцессного управления приложением.
Управляемые данными тесты
Набор тестов должен использовать технологию управляемого данными тестирования. Обзор этой
важной технологии приводится выше в разделе «Управляемое данными тестирование» текущего
документа. Среды VSTS/MSTest и xUnit включают стандартную поддержку управляемого данными
тестирования, а для среды Nunit предусмотрены соответствующие расширения.
Тесты и окружения теста, интегрированные в среду построения
Рекомендуется всегда хранить и создавать тесты вместе с тестируемым кодом. В идеале все
метаданные тестирования должны храниться вместе с тестами, чтобы разработчик мог создавать и
выполнять тесты независимо от доступности сервера. Авторы тестов иногда стремятся хранить данные
тестирования и метаданные в базе данных, что на первый взгляд кажется удачным решением, однако
связано с серьезными проблемами определения версий и ветвлением исходного кода.
В идеале запуски тестов тоже должны выполняться в рамках процесса после построения, тем самым
изначально предотвращая появление дефектов в базе кода. К примеру, пакет xUnit содержит задачу
MSBuild, которая служит для достижения этой цели.
Управление состоянием
Некоторые тесты во время выполнения меняют состояние системы. Эти изменения могут включать
копирование файлов, установку, изменение системных параметров, таких как языковой стандарт, DPI,
тема и др. Рекомендуется создать общую стратегию управления состоянием (с записью и откатом
состояния) еще на ранних этапах разработки теста, чтобы в дальнейшем избежать высоких расходов на
обслуживание и реструктурирование.
ПРИЛОЖЕНИЕ 2. ПРИВЯЗКА ДАННЫХ И ОТЛАДКА В WPF
Во втором выпуске этого документа основное внимание уделено ресурсам. Существует множество
полезных ресурсов с информацией о привязке данных WPF и отладке. Сведения о привязке данных см.
в следующих статьях и записях блогов:



Статья Привязка данных в разделе WPF веб-сайта MSDN.
Список практических руководств по привязке данных WPF в разделе WPF веб-сайта MSDN.
Блог Беатриз Коста (Beatriz Costa) с множеством полезных советов по привязке данных.
Полезными ресурсами по отладке являются следующие записи блогов:


Запись How do I debug WPF Bindings? в блоге Беатриз Коста (Beatriz Costa).
Запись Trace Sources in WPF в блоге Майка Хильберга (Mike Hillberg).
ПРИЛОЖЕНИЕ 3. ВЗАИМОДЕЙСТВИЕ WPF
Сведения о взаимодействии WPF и Win32 можно найти в разделе WPF веб-сайта MSDN в следующих
статьях:







Общие сведения о взаимодействии WPF и Win32
Руководство по созданию содержимого WPF, размещенного в приложении Win32
Учебник: создание приложения WPF, размещающего содержимое Win32
Windows Forms и архитектура ввода взаимодействия WPF
Сопоставление свойств Windows Forms и WPF
Элементы управления Windows Forms и эквивалентные элементы управления WPF
Разделы руководства по миграции и взаимодействию
В документе WPF for those who know Windows Forms на веб-сайте блогов MSDN содержится очень
удобное сопоставление возможностей Windows Forms и WPF для тех, у кого уже есть опыт
взаимодействия с Windows Forms и желание научиться работать в WPF.
В следующих статьях и записях блогов можно найти дополнительные сведения по данной теме:



WPF Interoperability FAQs на веб-сайте WindowsClient.NET.
Запись WPF-Win32 Interop Part 1: Hosting WinForms Controls (DataGridView) in WPF Windows в
блоге Иво Манолова (Ivo Manolov).
Запись WPF-Win32 Interop Part 2: Hosting Win32 Controls (ListBox) in WPF Windows в блоге Иво
Манолова (Ivo Manolov).
ПРИЛОЖЕНИЕ 4. НЕКОТОРЫЕ АСПЕКТЫ WPF-ПРИЛОЖЕНИЙ
БРАУЗЕРА
Ниже приводится ряд общих аспектов приложений XBAP.
ОБЩИЕ ПОДХОДЫ К ТЕСТИРОВАНИЮ ПРИЛОЖЕНИЙ XBAP

Тестирование функциональности приложения изнутри. Это означает, что у приложения должны
быть специальные сведения о самотестировании, а во многих сценариях — и полное доверие,
чтобы самостоятельно управлять своей работой, например, закрывать самого себя.

Управление приложением для внешнего тестирования. Большинство способов автоматизации
XBAP работают именно таким образом. После запуска приложения оно и сам браузер
контролируются с помощью API WPF UIAutomation. Это также удобный способ проверить
доступность приложения и определить, какие специальные возможности будут предоставляться
пользователям. Не забудьте задать свойство Name (или x:Name) на всех элементах управления,
которые планируется контролировать извне.
НЕКОТОРЫЕ АСПЕКТЫ РАЗГРАНИЧЕНИЯ ДОСТУПА КОДА ДЛЯ ТЕСТИРОВАНИЯ
ПРИЛОЖЕНИЙ XBAP



Уровень доверия. Тестируйте приложение с тем же уровнем доверия, с которым оно будет
выполняться. Помните, что доверие приложения определяет запрошенный набор разрешений, а
не зона происхождения. Поэтому приложения из зоны Интернета, запускаемые с локального
компьютера, будут по-прежнему выполняться с разрешениями зоны Интернета, а приложениям
с полным доверием будет разрешено выполняться только с локального компьютера (кроме
случаев повышения прав для доверенных издателей).
Внешнее управление автоматизацией. Для некоторых видов навигации требуется запуск
процесса пользователем в режиме частичного доверия, и они блокируются во всех случаях,
кроме тех, когда внешнее приложение или пользователь начали цепочку ввода данных, которая
привела к выполнению действия (например, навигация за пределы приложения), а
самоуправляемое приложение не может выполнять ввод данных в самого себя.
Использование API UIAutomation для поиска и вызова (щелчка) приложения. В данном случае
альтернативой может быть использование сборки APTCA в глобальном кэше сборок для
поведения полного доверия. (Тщательно продумывайте повышение прав!) Недостаток этого
подхода — возможная маскировка сценариев, которые не работают в режиме частичного
доверия, с помощью данной сборки брокера в глобальном кэше сборок, которая может
отсутствовать на компьютере конечного пользователя.
НЕКОТОРЫЕ АСПЕКТЫ CLICKONCE ДЛЯ ТЕСТИРОВАНИЯ ПРИЛОЖЕНИЙ XBAP
Обычно перед началом тестирования требуется очистить сетевое хранилище приложений. Если этого не
сделать, то будут запускаться устаревшие версии тестируемого приложения.


Очистка сетевого хранилища (требуется пакет SDK): Mage.exe -cc
Очистка всего хранилища: Delete %USERPROFILE%\Local Settings\Apps\2.0
Некоторые аспекты узла источника
Часто приложения обращаются к файлам или службам на своем узле источника. Это может осложнить
процесс тестирования, если сервер тестирования не аналогичен реальному серверу.




Избегайте жестко закодированной зависимости от сервера развертывания. Это относится к
таким распространенным сценариям, как веб-службы и содержимое несвязанных файлов.
Для выявления этой проблемы тестируйте различные узлы источника — реальные или
смоделированные.
Проверьте код, измените имя сервера.
При обнаружении проблем воспользуйтесь свойством BrowserInteropHelper.Source, чтобы
заменить жестко закодированный URL-адрес на URL-адрес развертывания.
Действия при невозможности тестирования с реального сервера
Следующая команда позволяет запустить приложение и (в целях разграничения доступа кода)
обрабатывает аргумент, переданный свойству debugSecurityZoneUrl, как «узел источника».
PresentationHost.exe -debug <путь к приложению> -debugSecurityZoneUrl <реальный узел>
Однако приложению потребуются некоторые сведения об этой процедуре, поскольку при выполнении в
этом режиме свойство BrowserInteropHelper.Source не является надежным источником URI-адреса
развертывания.
НЕКОТОРЫЕ АСПЕКТЫ ТЕСТИРОВАНИЯ WPF-ПРИЛОЖЕНИЙ БРАУЗЕРА







Воспользуйтесь ReadyState! При тестировании в Internet Explorer можно заблокировать
автоматизацию на основе значения readyState. Дополнительные сведения см. в записи форума
XBAP loading UI.
Перед выполнением тестов переведите браузер в известное и согласованное состояние.
Отключите диалоги блокировки. Отключите пользовательский интерфейс первого запуска,
изменив параметры Internet Explorer, или с помощью монитора процессов определите, что
нужно поместить в REG-файл, чтобы отключить этот интерфейс.
Проверьте автоматизацию настройки браузера на всех поддерживаемых платформах.
SKU Windows Server: добавьте узлы тестирования в список доверенных узлов, отключите
конфигурацию усиленной безопасности сервера или запланируйте автоматизацию прохода
этого пользовательского интерфейса.
Внимательно продумайте обработку входных данных приложения в браузере. Существуют
определенные комбинации клавиш, которые нельзя переназначить, что может привести к
нежелательным последствиям.
Некоторые комбинации с клавишами Alt и Ctrl подлежат локализации и различаются в
зависимости от языкового стандарта ОС. Если в приложении браузера обрабатывается ввод
данных с помощью клавиш Alt, Ctrl и функциональных клавиш, то необходимо выяснить, не
назначены ли этим клавишам определенные действия в том или ином поддерживаемом языке.
Download