Re: Дизайн Selenium Web тестов для ASP.NET на C#
От: Marduk Великобритания  
Дата: 21.12.09 10:12
Оценка: 3 (1)
Здравствуйте, sLMoloch, Вы писали:

LM>Всем привет,


LM>Недавно в свободное время наклепал проектик, в котором консолидировал весь свой опыт накопленный в области тестирования через UI.


Вы уточняйте, что это опыт тестирования UI с использованием Selenium-а, с примерами конкретных реализаций на C#.
Но это так, мелочь. У меня есть опыт работы с Selenium-ом, но только на Java и Ruby. Тем не менее, есть ряд общих вещей, которые мало зависят от конкретного языка.

LM>Принципы, которыми руководствовался в процессе написания проекта:


LM>1) Тесты должны быть простыми в написании и поддержке

LM>2) Тесты должны быть легкочитаемы

Тут еще надо определиться с целевой аудиторией. У нас на одном из проектов тоже одной из целей дизайна была простота, легкость поддержки и чтения тестов. Для этих целей делалось расширение основного класса Selenium-клиента, когда в те же методы верификаций, типа isTextPresent, уже встявлялись assert-ы. И сами тестовые классы наследовались от этого расширенного клиента. То есть, разработчик тестов вполне мог использовать методы селениума, даже не догадываясь, откуда они вообще там доступны.

И еще один момент. Как показала практика, для мануальщиков ООП весьма трудно для понимания. Гараздо проще именно процедурное программирование. В результате тест представляет собой последовательность команд вида:

click( "some_locator" );
isTextPresent( "Some text" );
isElementPresent( "some_other_locator" );

И так далее.

Идея оконных объектов достаточно удобна, мы ее тоже использовали. С той разницей, что в Java нет properties. Соответственно, пришлось использовать методы, причем они созвучны с методами Selenium-а, выполняющими основной ввод. То есть, все методы, которые делали клик начинались, с click, например clickOnSubmitButton(). По аналогии в соответствующих методах использовалиьсь префиксы type, select. Если бы в Java были properties, то ввод текста, выбор значения из списка точно были бы реализованы так же, как и у вас.

Причем, если то или иное действие приводило к загрузке другой страницы, то данный методы возвращали объект страницы. Соответственно, навигаторы, которые использовали вы, в данной задаче не использовались.

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

LM>3) Сайт должен содержать AJAX и тесты должны справлятся с этим

LM>4) Решение проблем с постоянностью. Это значит что тесты к примеру добавили юзера с именем "User1" в базу, то при втором запуске они не должны свалится от того что такой юзер уже сужествует.

У вас приведен пример считывания данных из базы, получение информации о существующих данных, хотя то, что вы описываете, может иметь много других подвидов.

Для этого нужно реализовать ряд recovery-сценариев. Как правило, это сценарии нескольких типов:
1) Установка основных настроек — используется какое-то средство администрирования тестируемого приложения, в котором выставляются все необходимые настройки, так что ни один тест, который как-то с такими настройками играется, не повлияет на работу других тестов.
2) Установка настроек, специфических для некоторой группы тестов — как правило, к ним в комплект идут сценарии, которые восстанавливают настройки по умолчанию, особенно, если это конфигурация, которая не накрывается сценарием из пункта 1.
3) Импорт данных, если таковые отсутствуют. Зачастую импорт предусматривает перезапись уже существующих данных.

LM>5) При ошибках тесты должны выдавать правильные ошибки, четко указывающие в чем проблема


Это скорее по части соглашений по написанию текста ошибок. Чем более детален текст описания, тем легче понять, что же произошло. Самый простой пример: если есть расхождения между ожидаемыми и фактическими результатами, то указываются оба: и что ожидали и что получили.

Есть еще штуки, специфические для конкретных ЯП. Например, для Ruby есть тестовый движок Cucumber, который использует Requirement Driven Testing подход. Так его лог выводит результаты не просто с текстом ошибок, а еще и с шагами для воспроизведения. Но это за счет особенности дизайна тестов для данного движка.

LM>6) Генерация кода, чтобы уменьшить количество работы


О да. Генерация — это всегда круто. Но в примерах, на которые вы ссылаетесь по данному пункту, вы используете исключительно xpath. На практике подобные локаторы одни из самых вредных, так как и работают медленней, а также более чувствительны к изменениям UI, особенно если захватывается несколько элементов в DOM-структуре.

LM>7) Должна быть возможность написания тестов непрограммистами


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

LM>8) Уменьшение времени тестирования путем запуска тестов в параллельных потоках, и используя Selenium Grid


Кстати, есть еще и т.н. практика "чёртового колеса", когда тесты выполняются постоянно в бесконечном цикле. Средства автосборки подобное обеспечивают. Главное — создать 2 идентичные таски, каждая из которых запускает тесты и выдает нотификации. При этом как только заканчивается выполнение первой таски, то начинается вторая. А когда закончится вторая, то начинается первая.

В чем преимущество: тесты работают 24 часа в сутки 7 дней в неделю. Человек работает 8 часов 5 дней в неделю. Даже если учесть, что автотесты работают в том же темпе, что и выполняются вручную, то от такой разницы по времени мы получаем выигрыш ( 24 * 7 )/( 8 * 5 ) = 21/5 = 4.2

То есть, работа одной машины заменяет работу 4-х людей. Особенно хорошо это себя проявит, когда суммарное время выполнения тестов будет исчисляться неделями.

Помимо этого, использование подобной практики позволит вам оперативно выявить реальные ошибки ваших тестов, то есть, если тест из разряда "passed after re-run", то при таких запусках 2-3 прогона подобные тесты отсеют.

В целом, ваше решение достаточно хорошее. У нас тут скоро планируется использовать селениум как раз в связке с .NET. Я думаю, выложенный вами материал будет интересен для ознакомления тем ребятам, которые на этом проекте будут работать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.