Монитор пользовательского режима
Монитор пользовательского режима позволяет тестам получать больше контекста о выполнении тестируемых процессов, чтобы получить больше контекста для исследования сбоев тестов или для обеспечения более эффективной проверки из существующих тестов. Текущая реализация монитора пользовательского режима предоставляет базовую реализацию с дополнительными настройками и конфигурацией, которые будут доступны в последующих выпусках.
Введение
Монитор пользовательского режима (UMM) использует низкоуровневые api Windows для уведомления обо всех событиях "отладчика", которые происходят из заданного процесса: запуск и остановка потока, загрузка модуля, сбои и обработанные исключения. После получения события отладчика код UMM может выполнить одно из нескольких действий, включая ведение журнала комментариев, ведение журнала ошибок (для того, чтобы не выполнить тест) или даже выполнить минидамп тестируемого процесса.
Включение монитора пользовательского режима
Чтобы включить UMM для конкретного тестового случая, необходимо предоставить два элемента конфигурации:
- Тест должен быть помечен значением метаданных ProcessUnderTest. Это позволяет UMM определить тестируемый процесс.
- Командная строка Te.exe должна включать "/userModeMonitor", чтобы включить функцию UMM.
При использовании кода UMM следует учитывать следующие моменты.
- Если запущено несколько экземпляров именованного тестового процесса, будет использоваться экземпляр, обнаруженный первым.
- Пользователь, выполняющий автоматизацию тестирования, должен иметь достаточные разрешения на получение событий отладчика из тестируемой обработки.
- Код UMM будет "присоединяться" к тестируемой процедуре после выполнения всех установочных приспособлений и "отсоединять" перед выполнением очисточных приспособлений. Это позволяет средствам настройки теста запустить тестируемый процесс и выполнить любую необходимую инициализацию для подготовки к тесту.
Поддерживаемый монитор "Действия" в пользовательском режиме
Монитор пользовательского режима имеет набор действий, которые он может выполнять при возникновении заданного события отладчика в отслеживаемом процессе. В текущей реализации данное событие вызывает только действие по умолчанию; в настоящее время не поддерживается конфигурация.
Действие | Описание |
---|---|
LogComment | Добавляет комментарий в журнал с контекстной информацией из события. |
LogError | Записывает ошибку в журнал, что приведет к сбою текущего теста. |
Минидампа | Записывает минидамп и сохраняет его в журнале. |
Игнорировать | Не выполняет никаких действий. |
Поддерживаемый монитор пользовательского режима "События"
Монитор пользовательского режима отображает "события", которые могут применять одно из перечисленных выше действий. В следующей таблице показан текущий список сообщаемых событий, а также действие по умолчанию, которое будет выполняться при получении события.
Событие | Действие по умолчанию (второе действие по умолчанию) |
---|---|
Создание потока | Игнорировать |
Выход из потока | Игнорировать |
Процесс создания | Игнорировать |
Процесс выхода | LogError |
Загрузка модуля | LogComment |
Выгрузка модуля | Игнорировать |
Системная ошибка | Игнорировать |
Начальная точка останова | LogError |
Начальная загрузка модуля | Игнорировать |
Выходные данные отладчика | LogComment |
Нарушение прав доступа | LogError (LogError) |
Сбой проверочного утверждения | LogError (LogError) |
Зависание приложения | LogError (LogError) |
Исключение инструкции break | LogError |
Продолжение исключения инструкции break | Игнорировать |
Исключение C++ EH | LogError (LogError) |
Исключение CLR | LogError (LogError) |
Исключение уведомления CLR | LogError (игнорировать) |
исключение Control-LogError | LogError |
Control-LogError продолжение исключения | Игнорировать |
Исключение Control-C | LogError |
Продолжение исключения Control-C | Игнорировать |
Неправильное сопоставление данных | LogError (LogError) |
Исключение команды отладчика | Игнорировать |
Нарушение страницы "Защита" | LogError (LogError) |
Недопустимая инструкция | LogError (LogError) |
Ошибка страничного ввода-вывода | LogError (LogError) |
Целочисленное деление на ноль | LogError (LogError) |
Переполнение целых чисел | LogError (LogError) |
Недопустимый дескриптор | LogError |
Недопустимое продолжение дескриптора | LogError |
Недопустимая последовательность блокировки | LogError (LogError) |
Недопустимый системный вызов | LogError (LogError) |
Порт отключен | LogError (LogError) |
Зависание службы | LogError (LogError) |
Одношаговая исключение | LogError |
Продолжение одношагового исключения | Игнорировать |
Stack buffer overflow; | LogError (LogError) |
Stack Overflow | LogError (LogError) |
Остановка проверяющего средства | LogError (LogError) |
Исключение Visual C++ | Игнорировать (игнорировать) |
Отладчик пробуждения | LogError (LogError) |
Точка останова WOW64 | LogError (игнорировать) |
Одношаговая исключение WOW64 | LogError (игнорировать) |
Другое исключение | LogError (LogError) |
Примере
Чтобы проиллюстрировать использование функций UMM, давайте рассмотрим (слегка придуманные) пример теста, который автоматизирует MSPaint:
namespace UserModeMonitorExample
{
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WEX.Logging.Interop;
using WEX.TestExecution;
[TestClass]
public class BasicExample
{
[TestInitialize]
public void TestInitialize()
{
Process[] runningPaintInstances = Process.GetProcessesByName("mspaint.exe");
Verify.IsTrue(runningPaintInstances.Length == 0, "There are no running instances of mspaint.exe");
this.mspaintUnderTest = Process.Start("mspaint.exe");
}
[TestCleanup]
public void TestCleanup()
{
// Close the 'mspaint under test' - if it's already gone, this will throw, but that's no big deal.
this.mspaintUnderTest.CloseMainWindow();
}
[TestMethod]
[TestProperty("ProcessUnderTest", "mspaint.exe")]
[TestProperty("Description", "Shows how a test can be failed if the UI is closed from underneath the test.")]
public void SimpleInteraction()
{
Log.Comment("If the 'user mode monitor' is enabled and mspaint.exe is closed,");
Log.Comment("then this test will be failed.");
Log.Comment("Sleeping for 5 seconds");
Thread.Sleep(TimeSpan.FromSeconds(5));
}
private Process mspaintUnderTest;
}
}
Ниже приведена краткая разбивка структуры теста.
- Тест SimpleInteraction представляет собой тест, взаимодействующий с приложением на основе пользовательского интерфейса. В данном случае это "MSPaint.exe". Обратите внимание, что метаданные ProcessUnderTest были применены для вызова того, что этот тест тест тестирует процесс "mspaint.exe".
- Тест содержит средство настройки, которое гарантирует отсутствие существующих экземпляров, и запускает один экземпляр для тестирования.
- Тест также содержит средство очистки, которое закрывает экземпляр, запущенный в программе установки.
"Тест" очень прямой, давайте рассмотрим возможные результаты:
- Тест выполняется без проблем. Это наилучший возможный результат.
- Без включения UMM пользователь закрывает экземпляр MSPaint во время выполнения. В этом случае тест будет пройден, но очистка завершится ошибкой с ошибкой InvalidOperationException.
- При включенной UMM пользователь закрывает экземпляр MSPaint во время выполнения. В этом случае код UMM зановит в журнал ошибку, показывающую, что процесс завершился сбоем теста. Очистка завершается ошибкой в случае (2).
Если UMM включена, поведение с ошибками немедленно сообщается и напрямую влияет на результат теста. Это гораздо лучший шаблон тестирования, так как ошибки отображаются как можно раньше, и предоставляется дополнительный контекст для отладки или понимания сбоев тестов.