Selenium IDE как артефакт пикника на обочине

Обычные, адекватные люди (it crowd programmers) при необходимости создать ряд автоматизированных тестов в рамках OpenSource инструментов используют для записи и прогона автоматизированных тестов нечто вроде Selenium IDE + JAVA + Selenium RC + Eclipse.

Алгоритм:

  1. Запускаем Selenium IDE и кликаем по приложению.
  2. Полученный код конвертируем на язык программирования, которым владеем.
  3. Переносим этот код в среду разработки.
  4. Превращаем куски этого кода в отдельные методы и разруливаем ситуацию по своему усмотрению.
  5. Запускаем тест-сьюты и отстраненно наблюдаем за ходом работы Selenium RC.

Я использую только первые два хода, затем не совсем стандартно разруливаю ситуацию непосредственно в Selenium IDE:

  1. Запускаю Selenium IDE и кликаю по приложению.
  2. Полученный код подправляю, снабжая его комментариями и дополнительными проверками.
  3. Полученный итоговый код разбиваю на логические сущности, которые можно выносить в отдельные файлы (по-ситуации).
  4. Выносимые файлы располагаются в разных каталогах, собранных в упорядоченную логическую структуру. Во всех подобных файлах используются переменные. Все подобные файлы используются и в других тест-сьютах.
  5. Собираю отдельный тест-сьют для проверки отдельного сценария.
  6. Выношу содержимое нужных мне переменных в отдельный html файл, который содержит команды StoreExpression и StoreEval (по ситуации).
  7. Запускаю отельные тест-сьюты при необходимости, а не все сразу один за другим, как это обычно делается.

Причина нестандартного подхода простая: мне нужен Selenium как вспомогательный инструмент, которые в нужное время быстро делает какие-то дела, а не как отдельный робот, который самостоятельно шурует по всему процессу тестирования от и до, выдавая только логи проделанной работы.

Изначально именно это я и хотел сделать , но бизнес у меня это дело не заказывал. Заказ был на ручное, функциональное тестирование, которое я ускорил за счет применения Selenium IDE.

Поднимать и в дальнейшем поддерживать отдельный тестовый фреймворк, слава Баранцеву, можно. Но в моем случае – не нужно. У меня относительно малые тесты то и дело все еще падают от столкновений с особенностями Ajax, и ковыряться в большом спагетти-приложении мне совсем не хочется, да и не просят.

Нужен помощник, а не тиран.

Selenium IDE отлично работает в качестве помощника, но он снабжен одной странностью, которую я не могу объяснить.

Эта странность уже дала мне ощутимое конкурентное преимущество перед моим предыдущим уровнем тестирования, но побороть ее пока не представляется возможным.

Странность в том, что совершенно адекватное поведение тула проявляется только в связке Selenium IDE + Ubuntu, и совершенно не работает в связке Selenium IDE + Windows.

Факт 1) Разрозненные тест-кейсы можно собрать в тест-сьют.

Файлы тест-кейсов должны находиться в том же каталоге, в котором находится файл собравшего их тест-сьюта.

Пример тест-сьюта в Selenium IDE:

<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium">
<tbody>
<tr><td><b>Test Suite Create New User</b></td></tr>
<tr><td><a href="openRegistrationPage.html">openRegistrationPage</a></td></tr>
<tr><td><a href="registrationPage.html">registrationPage</a></td></tr>
<tr><td><a href="signOutPage.html">signOutPage</a></td></tr>
<tr><td><a href="userIsAlreadyRegistered.html">userIsAlreadyRegistered</a></td></tr>
</tbody></table>

При изменении сьюта поначалу забываешь выбирать File > Save Test Suite, но опыт потерь учит быстро.

Факт 2) В тест-кейсах можно объявлять и использовать переменные.

В файле openRegistrationPage.html когда-то было написано следующее:

<tr>
    <td>open</td>
    <td>http://ourapp.com/CustomerRegistration.aspx</td>
    <td></td>
</tr>
<tr>
    <td>assertTitle</td>
    <td>Registration Page</td>
    <td></td>
</tr>

Это дело у нас в тестах встречается не один раз, и файл приходилось множить по разным каталогам. Изменения адреса и/или заголовка страницы сопровождались многократным переписыванием ряда файлов, что раздражает.

Использование переменных упрощает ситуацию:

<tr>
    <td>storeExpression</td>
    <td>/CustomerRegistration.aspx</td>
    <td>registrationPage</td>
</tr>
<tr>
    <td>storeExpression</td>
    <td>Registration Page</td>
    <td>registrationPageTitle</td>
</tr>
<tr>
    <td>open</td>
    <td>${registrationPageUrl}</td>
    <td></td>
</tr>
<tr>
    <td>assertTitle</td>
    <td>${registrationPageTitle}</td>
    <td></td>
</tr>

Теперь Selenium знает, что надо открыть страницу /CustomerRegistration.aspx относительно URL, который указан в качестве Base URL, и может быть модифицирован по ходу дела в самом IDE.

И знает, что должен проверить заголовок, который также объявлен в качестве отдельной переменной.

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

Факт 3) При сборке тест-сьюта можно указать файлы, которые находятся в других каталогах.

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

В файлах этих надо указать только переменные.

А данные, которые эти переменные должны будут использовать, отныне надо будет объявлять в каждом отдельном тест-сьюте.

Обновленный тест-сьют выглядит так:

<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite Create New User</b></td></tr>
<!-- объявляем содержимое всех переменных, которые будут использоваться в этом сьюте -->
<tr><td>
<a href="storedExpressions.html">storedExpressions</a>
</td></tr>
<!-- подключаем файлы, которые будут использовать уже объявленные значения переменных -->
<tr><td>
<a href="../../../../testLibrary/pages/openRegistrationPage.html">openRegistrationPage</a
></td></tr>
<tr><td>
<a href="../../../../testLibrary/pages/registrationPage.html">registrationPage</a>
</td></tr>
<tr><td>
<a href="../../../../testLibrary/pages/signOutPage.html">signOutPage</a>
</td></tr>
<tr><td>
<a href="../../../../testLibrary/users/userIsAlreadyRegistered.html">userExisted</a>
</td></tr>
</tbody></table>

Теперь каталог, в котором находится тест-сьют, содержит всего два файла:

* storedExpressions.html
* (test_suite)_registerNewUser.html

ведь в них находятся данные, которы уникальны сугубо для этого тест-сьюта.

Указание относительного пути “../../../../” прописал сам Selenium IDE.

Факт 4) Эта прелесть работает только под Ubuntu.

В Windows такие конструкции не работают по причине бага.

Да, это просто баг.

Вот как описана эта странность в официальной документации Selenium IDE:

Test case files should not have to be co-located with the test suite file that invokes them. And on Mac OS and Linux systems, that is indeed the case. However, at the time of this writing, a bug prevents Windows users from being able to place the test cases elsewhere than with the test suite that invokes them.

Предположим, что речь идет о временной неадекватности, которая может быть излечена.

Тест-сьют в Selenium IDE отображается, как полагается, и относительные пути прописаны правильно, но при обращении к файлам тест-кейсов появляется сообщение о невозможности найти запрашиваемое содержимое.

Попытки указать обратные слэши не помогли.

Попытки записать такой сьют в виндовой среде работают, и при первом прогоне ситуация выглядит внятной. Но после первого же переоткрытия сьюта (или же при последующем запуске Selenium IDE) все повторяется.

Факт 5) При каждом сохранении тест-сьюта относительные пути в его файле портятся.

После каждого сохранения пути вида
<tr><td><a href=”../../../../testLibrary/pages/openRegistrationPage.html”>openRegistrationPage</a></td></tr>
<tr><td><a href=”../../../../testLibrary/pages/registrationPage.html”>registrationPage</a></td></tr>

рэндомно превращаются в
<tr><td><a href=”../../../../../../testLibrary/pages/openRegistrationPage.html”>openRegistrationPage</a></td></tr>
<tr><td><a href=”../../../../../../testLibrary/pages/registrationPage.html”>registrationPage</a></td></tr>

Рэндомно, потому что не всегда и не все пути так модифицируются.

Факт раздражительный, но если приноровиться, и править файлы тест-сьютов руками – все ок.

21 thoughts on “Selenium IDE как артефакт пикника на обочине

  1. Пользуясь случаем, хочу спросить – а можно использовать переменные в Selenium Core? В IDE ваш способ попробовал – работает. Перенес все в Core – запускаю сьют – и не работает 😦 Такое впечатление, что ${…} в Core не воспринимаются как переменные

    1. Это синтаксис переменных сугубо для Sel IDE.

      В коре вам нужно создать переменные по законам тамошнего шариата: String userName = hzhzhz, или как там вам будет удобнее.

  2. Спасибо за столь скорый ответ 🙂 В результате экспериментов пока установил, что при использовании Core переменные вида ${…} использовать получается, только если эти переменные инициализировать в том же тест-кейсе. Т.е. в одном кейсе сделать storeExpression – то переменная работает только в этом кейсе. А если все переменные вынести в отдельный файл и запустить его первым в тест-сьюте – то не работает.

  3. Вы не подскажете….реально ли с Селениум IDE работать напрямую из терминала Убунту?

    1. Реально, но бессмысленно.

      Ему же требуется браузер. Это штукая для работы с браузером в первую и последнюю очередь, а не htmlUnit или что-то подобное.

  4. Алексей подскажите пожалуйста, существует ли решение для Selenium IDE с объявлением переменных через user-extensions.js? Описанный Вами вариант с файлом типа storedExpressions.html достаточно удобен, но требует добавлять объявление переменных в _каждый_ тестсьют по отдельности, а хочется реализовать более общий вариант решения этого вопроса :).

      1. Подсказали:

        В файле-расширении нужные переменные следует задать в таком формате:
        storedVars[“variableName”] = “your text”;

        Проблемы и достижения нашлись быстро:

        – Можно объявлять неограниченное количество переменных. Главное суметь их грамотно организовать.

        – Подход срабатывает только при запуске Selenium IDE. Если в ходе работы потребуется изменить хотя бы один символ что в названии, что в содержимом объявленных таким способом переменных, придется

        — или перезапускать весь Selenium IDE.
        — или добираться до кнопки Options > Options > Selenium Core extensions > Reload > OK

        – Можно вписать такие переменные в отдельный файл-расширение, а можно и в существующий, уже подключенный – работает однозначно.

        – Если будет необходим текст с русскими али какими еще бусурманскими ятями – надо будет внимательно следить за кодировкой файла-расширения. Бо текст в поле ввода будет передан в исходной кодировке – кракозябликами, если не уследить.

        – Если в тест-кейсах не будет предупреждения о том, где находится содержимое переменных, то беременные женщины и будущие пользователи ваших скриптов будут очень недовольны, бо ничего не подсказывает об этом изумительно подлом способе объявления переменных.

        – В контексте работы в сьюте можно менять содержимое переменных, никаких ограничений нет.

  5. Спасибо за помощь, Алексей!
    Все гениальное по-прежнему просто 🙂 – находил данное решение на просторах инета и пытался им воспользоваться, но в том случае автор по каким-то (вероятно, языко-специфическим) соображениям, опустил кавычки. А самому по неопытности догадаться не удалось, соответственно “кривой” *.js селениум не “ел”.
    Хорошо, что есть вселенский разум, и на поиски решения не пришлось угрохать остаток жизни).

    Поскольку я еще очень сильно начинающий селеноид, кроме IDE на ближайший (небольшой) проект ни о чем не мечтаю. Ну а когда (и если) дорасту до драйвера и RC – будем посмотреть.

    Если в ходе работы потребуется изменить хотя бы один символ что в названии, что в содержимом объявленных таким способом переменных{…}

    Думаю, подобные случаи будут нерегулярными, соответственно

    В контексте работы в сьюте можно менять содержимое переменных, никаких ограничений нет.

    в противном случае уже нужно создавать дополнительную переменную (хоть в экстеншене заранее, хоть прямо в кейсе через store) и переопределять значение параметра в нужном месте сьюта. Согласен, не айс, но вполне решаемо.

    Кракозяблик уже тоже поймал), ага, тут нужно будет контролировать кодировку.

    А для беременных последователей оказывается уже существует FF-аддон Stored Variables Viewer (Selenium IDE), добавляющий всего одну кнопочку в панельку IDE для просмотра этих самых переменных. Конечно же, это никоим образом не избавляет от необходимости документирования собственной деятельности, но, как мне кажется, является более изящным решением чем колонка echo в начале каждого сьюта)).

  6. Добрый день!
    Не уверена, что вопрос по этой теме, но все же…
    Суть в следующем: есть тест-кейс с циклом while. Внутри цикла осуществляется вход на сайт, некоторые действия на нем и выход. Вход на сайт по паре email\пароль и входить должен каждый раз новый пользователь. Пароли у всех одинаковые, это не проблема, а вот как поменять email не знаю. Выглядит он примерно так user1@mail.ru, отличаются друг от друга цифрой. Вопрос такой: как мне заставить Selenium IDE менять эту цифру в нужных пределах (например, от 5 до 45) при каждом заходе на новый круг цикла? Или может быть есть возможность читать email из файла и передавать в нужную команду посредством переменной?
    Заранее спасибо за ответ!

      1. Спасибо, но эту Вашу статью я уже изучила и цикл делать научилась. Тут в другом сложность: мне надо при каждом новом заходе в цикл указывать новое значение email. То есть менять цифру внутри самого email: user1@mail.ru, user2@mail.ru, user3@mail.ru и так далее. Можно ли как-то это реализовать?

        1. Иногда задачи решаются проще, если их переформулировать или найти другой подход.

          Ну или сложнее, хз. Зависит от обстоятельств и умения/понимания программировать.

          Можете сделать, готовить данные заранее, отдельным методом, что ли, а потом новое значение использовать в каждом завихрении. Вот тупое, но простейшее решение:

          storeEval | ${userEmailNumber}+1 | userEmailNumber
          storeExpression | user${userEmailNumber}@mail.ru | userEmail
          echo | ${userEmail}

          Если повторять это последовательно, то циферка в userEmailNumber будет увеличиваться на единицу после каждого прогона.

          1. Спасибо большое, не думала, что можно так вставить переменную внутрь email. Попробую реализовать это на практике.

  7. Здравствуйте, Алексей!
    Огромное спасибо за презентацию (как раз пришлось начать работать с Selenium IDE), очень помогло.
    На данный момент возник вопрос как мне избежать редактирования тестов во время их прогона, поскольку одна ссылка меня перекидывает на окно в котором прописана другая ссылка, включающая название энвайромента? Т.е. я находилась например на sit-e, а внутри теста открывается ещё окно с uat ссылкой. (а мне то надо продолжать на sit-e).
    Надеюсь, что смогла нормально обьяснить и надеюсь на помощь.

    1. Нет, почему проблема.

      Я же не знаю, как вы организовали свои тесты и какие там шаги и почему такая привязка к sit, и почему там открывается окно на uat.

  8. Да, немного не подробно обьяснила.
    Тесты записываю на UAT, берём его за истинно правильный вариат. Но во время записи тестов есть такие моменты, где внутри теста будет открываться окно с адресом в котором присутствует этот uat. А когда я запущу эти тесты на sit-е то в тех тестах выскочит uat окошко ибо так было изначально записано.
    У меня же задумано, что можно легко один сьют прогнать на нескольких энвах.

    1. Переменные с адресом нужных страниц используете?

      Вроде
      storeExpression | http://notUAT.com/ | siteUnderTesting

      потом open | ${siteUnderTesting}/login.html | для работы на тестовом окружении.

      Если надо будет перейти на UAT, то переменная одна и та же, окружение меняется буквально редактированием одной строки:
      storeExpression | http://UAT.com/ | siteUnderTesting – и поехали в том же режиме дальше.

      Проблемно будет, если внутри сайта на тестовом окружении есть ссылки, которые почему-то жестко ведут на UAT. Надо смотреть и соображать непосредственно над приложением и особенностями его реализации, гадать тут незачем.

  9. С переменными пытаюсь дружить, но как-то иначе у меня была решена эта проблема с переключением энвов и всё ок.
    Проблему с окошками решила с помощью команды open но не всей ссылки, а например: open |tpadmin/tpmon/messages/config/externalResources.do#|
    шаги, шаги, шаги…
    И для возвращения на нужную страницу просто –
    open |tpadmin/tpmon/messages/summary.do#| |

    Не пришлось использовать всю ссылку в которой имеется UAT/SIT.
    Как-то так. Я молодой/зелёный и решения приходят иногда сами и неожиданно.
    Но работает и это радует:)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s