понедельник, 6 февраля 2012 г.

Грешки Автоматизатора. Часть 3. Xpath головного мозга

На этот раз пишу с привязкой к инструменту. И инструмент этот (СЮРПРИЗ!!!) - Selenium-WebDriver (дальше просто Selenium или Se).

Так вот, в selenium есть одна большая и неутихающая головная боль - локаторы элементов. Головная боль, если задуматься, довольно древняя и растет из того, что текущие (да и прошлые, чего греха таить) биндинги никак не располагают к тому, чтобы:

  • Задать много идентификаторов для одного элемента
  • Использовать все возможные идентификаторы тегов (title, например)
  • Обращаться напрямую к индексу элемента
  • Различать элементы по типам (привет findElement!)
Одной невозможности обращаться к элементу по его имени (title) и по индексу уже достаточно чтобы плакать кровавыми слезами.

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

Я долго думал почему же css-локаторы лучше чем xpath, но в итоге не придумал ни одного железобетонного аргумента.

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

Я мог бы сказать, что CSS читабельней чем xpath. Но это вкусовщина. Если человек привык писать //div[@id='eid'], то div#eid для него может показаться ущербным.

Я мог бы сказать, что CSS это практически jQuerry, но автоматизатору со средней полосы до jQuerry как правило нет никакого дела.

Но больше всего раздражает в xpath-локаторах то, что люди пытаются делать вот такие вещи:

html/body/div[2]/div[2]/div/div/ul/li[2]/div/img
//div[@id='ui-datepicker-div']/div/div/select[2]
Только xpath тут совсем ни при чем. Огромная, зловонная куча таких вырвиглазных примеров локаторов на xpath скорее всего существует только потому, что CSS-локаторы штука относительно новая и применяя их не успели еще создать столько мусора. Это просто гипотеза, но справедливости ради стоит заметить, что вырвиглазные примеры css-локаторов я тоже вижу, но в разы реже.

Не пишите глупых локаторов просто потому, что иначе нельзя. Борьба за testability (это, кстати, атрибут качества, если кто забыл) как правило в интересах автоматизатора, так как от ее отсутствия он страдает чаще и больше тех, кто занимается тестированием ручками. Тестирующие ручками, на самом деле, тоже страдают очень сильно, но им, как правило, сложнее увидеть корень проблемы. Попытайтесь найти выход.

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

Или предложите вашему разработчику написать тесты самому - он первый побежит проставлять идентификаторы.

Или проставьте их сами.

Только не рисуйте бессмысленных и беспощадных локаторов. Это зло, которое вам потом придется переписывать. И если у вас нет никакой возможности это зло побороть - переписывать, скорее всего, придется много и часто. И если смену имени/id элемента еще можно быстренько поправить (хотя в частой их смене тоже нет ничего хорошего), то переписывать развесистые локаторы, где упоминается добрая половина элементов DOM-дерева, сильно дольше. А уж читать эти развесистые локаторы после вас...

6 комментариев:

  1. Чем XPath хуже? А как же старый добрый "IE нумерует с нуля, а все остальные с единицы" (сейчас может и нет, давно я не трогал IE)?

    Вообще, я в свое время очень удивился когда узнал что "CSS" локаторы в Selenium RC на самом деле Sizzle (привет jQuery) и в WebDriver нельзя делать :contains('text'), :nth(3). И вместо XPath начал использовать Watir-WebDriver - куда удобнее ;D

    ОтветитьУдалить
  2. XPath в основном в IE и отстоен. В остальных +/- один фиг что и CSS.

    Но в целом согласен - Watir-WebDriver куда удобнее, хотя бы потому, что все четыре болезни Selenium локаторов там отсутствуют и не надо их заменять двумя костылями "CSS" и "XPath".

    ОтветитьУдалить
  3. Поддерживаю Вас, Сергей. Мы даже проводили отдельный воркшоп на тему, как писать правильные CSS и Xpath локаторы. Порекомендуйте читателям ресурсы или основные приемы по оптимизации уже существующих выражений.

    ОтветитьУдалить
  4. По CSS/XPath я там линку на тесты производительности от Santiago Suarez'а привел, по ним в принципе видно, что быстрее работает. Прямое обращение в CSS локаторе по ID и по имени в IE работает на пару порядков быстрее практически чего угодно. Т.е. если полста CSS локаторов обращающихся к элементу по ID в IE будут работать, например, секунду, то в XPath (или CSS/XPath локатор по относительному контенту) там легко может случиться пара минут.

    ОтветитьУдалить
  5. Надо заметить, что внутри Watir-Webdriver таки строится монстрообразный XPath, чтобы выполнять реальный поиск элементов -- https://github.com/watir/watir-webdriver/blob/master/lib/watir-webdriver/locators/element_locator.rb#L267

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

    Можно также загрузить jQuery или Sizzle на страничку и сделать механизм локации, который будет использовать их.

    Мир так разнообразен, и это так здорово, что каждая задача имеет много решений!

    Но с главным тезисом про "долой вырвиглазность" я, конечно, тоже не могу не согласиться :)

    ОтветитьУдалить
    Ответы
    1. Главное что этот монструозный XPath в watir-webdriver мы не видим. Так что в итоге единственное чем он нам может аукнуться это скоростью выполнения, которая, как я написал, не для всех критична (да и оптимизация локаторов это не единственный способ ускориться).

      Кстати, тут коллега высказал гипотезу, что обилие кошмарного XPath вызвано последствиями тесной связи с Se IDE

      Удалить