Doing it wrong:
Тест-кейсы:
- В тестах присутствуют локаторы. Если это так, то не стоит продолжать написание новых тестов, даже если вы не используете PageObject pattern. Когда количество тестов приблизится к 100+ то поддерживать всю эту кашу из локаторов будет, мягко говоря, не просто. И большая часть времени работы над проектом будет заключаться в использовании Find&Replace+FireBug(IEDevTool)
- В тестах присутствуют операторы ветвления/циклов/try{}catch etc. Тесты должны быть атомарными (по-крайней мере с виду), а все остальное "непотребство" должно быть спрятано в недрах PageObject'a.
- В тестах присутствуют Assert'ы, Sleep'ы, Wait'ы, создание объектов не являющимися PageObject'ами и прочее. См п.2
Если вы добьётесь выполнения этих трех пунктов, пол-дела сделано.
Пример теста:
public void test() {
Manager m = new Manager(driver);
SelectColumnsDialog d = m.clickSelectColumns();
d.includedColumns.verifyContains("Title");
d.includedColumns.verifyItemPosition("Title", 1);
d.includedColumns.selectItem("Title");
d.includedColumns.verifyItemSelected("Title");
d.moveDown.click();
d.includedColumns.verifyItemPosition("Title", 2);
}
Локаторы:
- [Не читабельные]/[Сгенерированные] локаторы. Залог стабильных, легко поддерживаемых тестов - хорошее знание Xpath/CSS language. Поэтому если вы видите в своём проекте что-либо похожее на //div/table[2]/div[4]/td/a, бросайте все и беритесь за изучение Xpath [CSS опционально]. Многие искренне удивляются, когда узнают что Xpath - это в своем роде язык, и что он не ограничивается простым //sometag[@id='id']
- Локаторы основаны исключительно на id, class, name и прочих эфемерностях. Да-да, тут в меня полетят камни, но товарищи - мы ж не white-box testing'ом занимаемся. Over 9000 вопросов можно найти в selenium google groups про динамические/не уникальные id и прочее, т.к. в умах прочно сидит, что "если есть id - больше ничего не надо". Почему мы можем искать UI элементы основываясь на той информации, которая скрыта от "живых" пользователей? Если п.1 успешно пройдет, то для вас не будет проблемой построить локатор, так, как-бы его искал пользователь на странице - а именно основываясь на визуальной информации. Да - в некоторых случаях придется пренебрегать этим пунктом, но этого следует избегать.
PageObject:
Разработчики подарили пользователям WebDriver'а этот замечательный паттерн, но не довели его до логического завершения и... убили его потенциал введя аннотации аля @FindBy перемешав у большинства пользователей понятия PageObject и PageFactory
- У PageObject есть филды с аннотацией @FindBy. Да - в начале автоматизации все будет чудесно и просто. Потом вы станете замечать, что все чаще и чаще обращаетесь к driver.findElement(s). Потом увидите, что почти все аннотации похожи как две капли воды и зачастую отличаются один словом. Потом столкнетесь с ограничениями в различных ожиданиях/кондишенах. Так что, если вы начинаете работать над более-менее серьезным проектом - можете сразу исключить использование @FindBy, сократив время на последующий рефакторинг. Как альтернатива - используйте филды типа By, другой подход будет описан ниже.
- Sleep'ы. Ну тут всем понятно, чем их меньше - тем лучше. И что точно лучше не пытаться делать - это решить проблему StaleElementException через слипы.
- Wait'ы реализованные через операторы циклов, аля int i=0;while(i<10){sleep(1);i++}. Используйте WebDriverWait - не нужно изобретать велосипед.
- PageObject'ы слишком громоздки. Устаете скролить класс, что бы добраться до нужного метода? Много повторяющегося кода в разных PageObject'ах? Несмотря на то, что в оффициальных туториалах отмечается что PageObject не обязательно должен представлять целую страницу - это вполне может быть блок/секция/фрейм, большинство пытаются сделать из PageObject - GodObject забывая про наследование и про то, что у PageObject'а вполне может быть PageObject-филд.
Но... Даже если ваш проект будет удовлетворять всем этим условиям - все-равно будет ощущение что чего-то не хватает...