2013-12-04 6 views
20

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

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

Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled; 

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

Вызов

Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.UIThreadOnly; 

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

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

ответ

34

После небольшого количества экспериментов, я разработал то, что, как представляется, комбинация настроек, которые позволяют моим 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's 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; 
    } 
} 
+1

Спасибо, что ответили на свой пост. Это ускорило мои испытания. – user171197

+0

Это фиксировало почти все для меня. У меня все еще есть некоторые проблемы с синхронизацией с некоторыми операциями Async, которые продолжаются, но этого можно ожидать. Благодаря! – Rouse02

+0

Кто-нибудь когда-либо получал эту работу с запуском тестовых примеров на основе [AssemblyInitialization]. За то, что я делаю. Мне нужно запустить мой тест в [AssemblyInitialization]. Я специально говорю о Playback.PlaybackSettings. Если кто-то получил эту работу, быстрый ответ или пример были бы замечательными. Tahnks – skinnyWill

6

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

This Microsoft blog дает много объяснений, что происходит и как его исправить. Пример показывает в нем ускорение от 30 секунд до 8 секунд, изменив поисковую строку из

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

к

Name Contains “Sales order‬ (‎‪1‬ - ‎‪ceu‬)‎‪ - ‎‪‪‪Sales order‬: ‎‪SO” 
+1

Извините, это не ответ на заданный вопрос. OP указывает, что SmartSearch уже отключен. Если контроль не может быть найден достаточно эффективно, тест просто терпит неудачу. Более того, эксперимент подтвердил, что наблюдаемая проблема связана с машиной WaitForReady. –

Смежные вопросы