Тестирование пользовательского интерфейса в кодировке WPF случайно завершается со странным ArgumentException

Я закодировал тесты пользовательского интерфейса в приложении WPF, и они иногда терпят неудачу со следующим исключением:

Сообщение: метод теста MyMethodNameGoesHere вызвала исключение: System.ArgumentException: параметр недействителен.

и StackTrace:

at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)
at Microsoft.VisualStudio.TestTools.UITesting.LoggerUtility.GetDesktopImage()
at Microsoft.VisualStudio.TestTools.UITesting.LoggerUtility.CaptureScreenShotAndDrawBounds(Int32 x, Int32 y, Int32 width, Int32 height, Int32 borderWidth, Boolean isActualControlBounds)
at Microsoft.VisualStudio.TestTools.UITest.Extension.LoggerUtilities.CaptureScreenShotAndDrawBounds(Rectangle bounds, Int32 borderWidth, Boolean isActualControlBounds)
at Microsoft.VisualStudio.TestTools.UITesting.Playback.CaptureScreenShot(UITestControl control)
at Microsoft.VisualStudio.TestTools.UITesting.Playback.GetUITestControlString(UITestControl control)
at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapControlNotFoundException(COMException ex, IPlaybackContext context)
at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapAndThrowComException(COMException innerException, IPlaybackContext context)
at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapAndThrowException(Exception exception, IPlaybackContext context)
at Microsoft.VisualStudio.TestTools.UITesting.Playback.MapAndThrowException(Exception exception, String queryId)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindFirstDescendant(String queryId, Int32 maxDepth, Int32& timeLeft)
at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.GetElement(Boolean useCache, ISearchArgument searchArg)
at Microsoft.VisualStudio.TestTools.UITesting.SearchHelper.Search(ISearchArgument searchArg)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FindInternal()
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.<Find>b__175_0()
at Microsoft.VisualStudio.TestTools.UITesting.CodedUITestMethodInvoker.InvokeMethod[T](Func`1 function, UITestControl control, Boolean firePlaybackErrorEvent, Boolean logAsAction)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.Find()
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.GetPropertyPrivate(String propertyName)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.GetPropertyOfType[T](String propertyName)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.get_Exists()
at MyProjectNamespace.UITests.TestButtonExists() in E:\...\UITests.cs:line 177

Любой код, который пытается получить доступ к свойствам UITestControl лайк Exists, Checked или же Selected бросает это. Например:

WpfButton button = UIControlBuilder<WpfButton>.Builder()
    .Parent(MainPane)
    .AutomationID(MyButtonId)
    .Build();

// ...    

Assert.IsTrue(button.Exists);

Интересно, что эта проблема происходит случайно, но с некоторой закономерностью. Если я запускаю тесты один за другим, то они работают хорошо. Если я запускаю много тестов в строке, то через некоторое время один тест не пройден, а затем все последующие тесты тоже не пройдены. Я думал, что это может быть связано с проблемой памяти (утечка или нехватка памяти), но у меня определенно есть много доступной памяти, и процессы, кажется, не потребляют большую ее часть.

Из моего исследования тестовый интерфейс пользовательского интерфейса ловит исключение в FindFirstDescendant и пытается сделать снимок экрана, чтобы сообщить об этом исключении, но также не может сделать это:

// decompiled UI test framework's UITestControl.cs code
internal UITestControl FindFirstDescendant(string queryId, int maxDepth, ref int timeLeft)
{
    // ...
    try
    {
        element = this.ScreenElement.FindScreenElement(queryId, maxDepth);
    }
    catch (Exception ex) // catches exception here
    {
        // but this method does also throw exception, because of a bug:
        Microsoft.VisualStudio.TestTools.UITesting.Playback.MapAndThrowException(ex, queryId); 
        throw;
    }
}

Еще более интересно, что это очень общая ошибка, которая происходит в конструкторе.NET Bitmap (неверный параметр ширины или высоты?).

Из-за этого Bitmap проблема Я не могу получить оригинальное исключение, поэтому я не могу понять, что происходит. Playback.CaptureScreenShot помечен атрибутом подавления предупреждений компилятора, который четко указывает, что этот метод не должен генерировать никаких исключений.
Это ошибка в структуре тестирования пользовательского интерфейса?

Еще одно интересное наблюдение. Он создает скриншоты в моей тестовой директории, но окно приложения неправильно выделяется на скриншотах. Вот как это выглядит. Красный - моя настройка дисплея, синий - то, где на самом деле находится главное окно, зеленый - то, как WPF выделяет на скриншоте результатов теста:

Расстояние между зеленой узкой линией и синей узкой линией для углов одинаково, поэтому мне кажется, что она принимает смещение окна приложения в пределах одного основного дисплея, но затем оно пытается сделать снимок экрана, применяя смещение ко всем дисплеям. Может ли это быть причиной ошибки (например, выход за пределы экрана) или это просто другая вещь?

0 ответов

Поскольку это выглядело как ошибка, я задал тот же вопрос в DeveloperCommunity.

Похоже, что многоэкранный режим просто не поддерживается:

Спасибо за расследование по этой проблеме. похоже, что вы запускаете закодированный тест пользовательского интерфейса с несколькими экранами. На самом деле это неподдерживаемый сценарий.

Также закодированный тест пользовательского интерфейса устарел. Проверьте https://docs.microsoft.com/en-us/visualstudio/test/use-ui-automation-to-test-your-code?view=vs-2017

Мы предлагаем перейти на Selenium или Appium с WinAppDriver, в зависимости от обстоятельств.

Другие вопросы по тегам