Подтвердить что ты не робот

Кодированный тест пользовательского интерфейса медленно ожидает поток пользовательского интерфейса

Я добавил тесты кодированного пользовательского интерфейса в мое решение ASP.NET MVC в Visual Studio 2013. Я был встревожен тем, как медленно проходят тесты; каждая страница просто сидит там на минуту или больше, прежде чем тестовое оборудование просыпается и начинает заполнять поля формы.

После некоторых экспериментов (включая выключение SmartMatch), я обнаружил, что просто вызывая

Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;

решает проблему. Но, как и ожидалось, тест часто терпит неудачу, поскольку поток пользовательского интерфейса не готов к взаимодействию тестового оборудования с элементами управления в форме.

Вызов

Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.UIThreadOnly;

делает тестовый запуск надежным, если медленно.

Любые мысли или предложения? Любая надежда, что кто-то может иметь некоторое представление о магии, запеченной в машинах WaitForReady? Есть ли другие настройки, связанные с WaitForReady, с которыми я могу играть, кроме WaitForReadyLevel?

4b9b3361

Ответ 1

После нескольких экспериментов я разработал то, что представляется комбинацией настроек, которые позволяют моим Coded UI Tests надежно запускаться на полной скорости - быстрее, чем я мог бы взаимодействовать с сайтом вручную.

Примечание. Соответствующую "документацию" (если вы называете "документацию" в блоге) можно найти здесь:

Трюк требует нескольких модификаций настроек воспроизведения по умолчанию:

  • Настройка WaitForReadyLevel = WaitForReadyLevel.Disabled позволяет запустить тест на полной скорости. Но он также отключает магию (медленную!), Которая ждет, пока не будет безопасно взаимодействовать с элементами управления на странице.

  • Установка MaximumRetryCount и прикрепление обработчика ошибок обрабатывает большинство ошибок, возникающих в результате отключения магии "ждать готовности". Поскольку я запекал 1 секунду Sleep в логике повтора, это значение фактически представляет собой количество секунд, которые я готов дождаться загрузки страницы и стать отзывчивым.

  • По-видимому, неспособность найти проверяемый элемент управления не является одной из ошибок, которые обрабатывает механизм обработчика ошибок/повторов. Если для загрузки новой страницы требуется больше нескольких секунд, и тест ищет элемент управления, который не существует до тех пор, пока новая страница не загрузится, тест не сможет найти элемент управления, и тест завершится с ошибкой. Настройка ShouldSearchFailFast = false решает эту проблему, предоставляя вам полный тайм-аут для загрузки вашей страницы.

  • Настройка DelayBetweenActions = 500, похоже, устраняет проблему, которую я иногда вижу, когда пользовательский интерфейс пропускает нажатие кнопки, которое происходит сразу после загрузки страницы. Кажется, что тестовое оборудование думает, что нажата кнопка, но веб-страница не отвечает на него.

  • В "документации" говорится, что тайм-аут поиска по умолчанию составляет 3 минуты, но на самом деле это нечто большее 10 минут, поэтому я явно устанавливаю SearchTimeout на 1 секунду (1000 мс).

Чтобы сохранить весь код в одном месте, я создал класс, содержащий код, используемый всеми тестами. MyCodedUITests.StartTest() вызывается методом [TestInitialize] в каждом из моих тестовых классов.

Этот код действительно должен выполняться только один раз для всех тестов (а не один раз для каждого теста), но я не мог понять, как заставить вызовы Playback.PlaybackSettings работать в [AssemblyInitialization] или [ClassInitialization] подпрограммы.

/// <summary> A class containing Coded UI Tests. </summary>
[CodedUITest]
public class UI_Tests
{
    /// <summary> Common initialization for all of the tests in this class. </summary>
    [TestInitialize]
    public void TestInit()
    {
        // Call a common routine to set up the test
        MyCodedUITests.StartTest();
    }

    /// <summary> Some test. </summary>
    [TestMethod]
    public void SomeTest()
    {
        this.UIMap.Assert_HomePageElements();
        this.UIMap.Recorded_DoSomething();
        this.UIMap.Assert_FinalPageElements();
    }
}


/// <summary> Coded UI Test support routines. </summary>
class MyCodedUITests
{
    /// <summary> Test startup. </summary>
    public static void StartTest()
    {
        // Configure the playback engine
        Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;
        Playback.PlaybackSettings.MaximumRetryCount = 10;
        Playback.PlaybackSettings.ShouldSearchFailFast = false;
        Playback.PlaybackSettings.DelayBetweenActions = 500;
        Playback.PlaybackSettings.SearchTimeout = 1000;

        // Add the error handler
        Playback.PlaybackError -= Playback_PlaybackError; // Remove the handler if it already added
        Playback.PlaybackError += Playback_PlaybackError; // Ta dah...
    }

    /// <summary> PlaybackError event handler. </summary>
    private static void Playback_PlaybackError(object sender, PlaybackErrorEventArgs e)
    {
        // Wait a second
        System.Threading.Thread.Sleep(1000);

        // Retry the failed test operation
        e.Result = PlaybackErrorOptions.Retry;
    }
}

Ответ 2

Кодированный пользовательский интерфейс выполняет поиск элементов управления на экране, и поиск выполняется довольно быстро, если это необходимо. Однако, если поиск не выполняется, тогда в кодированном пользовательском интерфейсе есть другая попытка использовать метод "умного соответствия", и это может быть медленным. Основной способ избежать кодированного пользовательского интерфейса, возвращающегося к использованию интеллектуального сопоставления, заключается в удалении или упрощении элементов поиска, которые могут меняться от запуска до запуска.

Этот блог Microsoft дает много объяснений о том, что происходит и как его исправить. В этом примере показано ускорение с 30 секунд до 8 секунд путем изменения строки поиска из

Name EqualsTo "Sales order‬ (‎‪1‬ - ‎‪ceu‬)‎‪ - ‎‪‪‪Sales order‬: ‎‪SO-101375‬‬, ‎‪‪Forest Wholesales"

к

Name Contains "Sales order‬ (‎‪1‬ - ‎‪ceu‬)‎‪ - ‎‪‪‪Sales order‬: ‎‪SO"