Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Вот это задание
- https://docs.google.com/document/d/1yvUML7eXyEyDh5asUIL7M88RStlE1RZmgUOJZSXjMVo/edit?usp=sharing
- реши это задание, используя Selenide
- в видео - есть про то, как использовать Selenide
- https://www.youtube.com/watch?v=5c3z_iddWX0&feature=youtu.be
- Да, мы на курсе и с чистым селениумом будем работать, но начнем - именно с использования Selenide
- смотри план курса
- https://docs.google.com/spreadsheets/d/1avmeuOfyu_GC_rEAWxsUyv2O-VSJh7-KaZTAoCopP0E/edit?usp=sharing
- часть Web UI: The Art of Automation - используем Selenide
- часть Web UI: Software Development In Test - используем чистый Selenium
- Такой подход позволяет изолировать разые темы друг от друга
- Мы в более комфортном режиме - рассмотрим многие темы (часть 1)
- И лишь потом начнем разбираться с тонкостями селениума (часть 2)
- В итоге - процесс обучения будет поэффективнее
- ***********************************************
- public class ToDoTest {
- /*
- Имя тест-класса - лучше уточни
- приложение называется TodoMVC - от этого и оттолкнемся
- TodoMVCTest - будет ок
- в faq - есть раздел по naming, посмотри
- https://docs.google.com/document/d/10qSwWTQ6pGfVZSwOes-1QSmdflMiGD2U_y53VHq2m20/edit#heading=h.2zj10n877t2p
- */
- *******************************************
- @Test
- public void testTask() {
- /*
- у нас - е2е сценарий
- посмотри на советы - как в таких случаях лучше назвать тест-метод
- https://docs.google.com/document/d/10qSwWTQ6pGfVZSwOes-1QSmdflMiGD2U_y53VHq2m20/edit#bookmark=id.txqig9rkgybo
- */
- String[] taskNames = {"task1", "task2", "task3", "task4"};
- for (int i = 0; i < taskNames.length; i++)
- createTask(taskNames[i]);
- /*
- на добавление 4-х тасок - мы написали 3 строчки
- и к тому же использовали цикл
- а если бы просто писали
- createTask("task1");
- createTask("task2");
- createTask("task3");
- createTask("task4");
- то было бы всего на 1 строчку длиннее
- и значительно проще для восприятия
- в целом - надо избегать в тест-методах использовать сложную логику
- for - уже сложная логика)
- причем - во вспомогательных методах - for или if допустимы
- а вот тест-методы - должны оставаться "тупыми"
- погугли про KISS Principle
- в следующей работе - разберем как организовать вот такой метод
- createTasks("task1", "task2", "task3", "task4");
- пока остановись на четырех вызовах метода createTask
- что касается использования для тестовых данных переменных - ниже напишу
- тесты - это не только действия
- но и проверка результатов
- каждая операция - должна быть проверена сразу
- иначе - если возникнут ошибки - мы можем не разобраться в их причинах
- нам нужно убедиться что
- операции выполняются
- операции выполняются с ожидаемым нами результатом
- тут - поскольку действия однотипные - можно проверить уже после добавления четвертой таски
- */
- deleteTask("task2");
- /*
- удалили - и проверь состояние списка тасок
- */
- completeTask("task4");
- clearCompleted();
- /*
- и тут нужна проверка
- насчет проверки после completeTask...
- тут ситуация поинтереснее
- в принципе - проверку можно отложить на 1 шаг
- и проверить состояние списка тасок после clear completed
- так можно поступить - т к проверка текстов тасок после закомпличивания таски
- даст нам проверку логики = все таски на all фильтре отображаются независимо от своего статуса,
- но не даст проверку факта закомпличивания
- это мы как раз допроверим после clear completed
- проверка текстов после clear completed как раз этот факт и допроверит
- */
- driver.findElement(By.id("toggle-all")).click();
- clearCompleted();
- /*
- тут - также можно реализовать проверку
- уже после этих 2-ух действий
- далее на курсе чуть подробнее коснемся этой темы
- когда проверку можно отложить
- а вообще - правило такое
- каждое действие в тесте должно быть проверено сразу
- */
- }
- *********************************************************
- public void createTask(String taskName) {
- /*
- имя метода можно чуть упростить )
- все действия - выполняются над тасками
- да и параметр - немного поясняет
- можно без ущерба для точности
- вместо
- createTask(String taskName)
- использовать
- create(String taskName)
- аналогично - и для других вспомогательных методов-действий
- */
- driver.get("https://todomvc4tasj.herokuapp.com/");
- /*
- открыть нужный урл - нам достаточно лишь единожды
- я не буду вообще останавливаться на особенностях селенидовской или селениумской реализации
- раз ты осилила версию на чистом селениуме - думаю, с селениде вообще не будет вопросов)
- открытие урла - это не добавление таски
- это отдельное действие
- которое не стоит скрывать в методе добавления таски
- его вынеси в тест-метод - выше добавления тасок
- */
- waitElementById("new-todo", 20);
- driver.findElement(By.id("new-todo")).sendKeys(taskName);
- driver.findElement(By.id("new-todo")).sendKeys(Keys.ENTER);
- assertTrue(driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']")).isDisplayed());
- /*
- проверки - не прячь в методах-действиях
- т к тогда глядя на тест-метод - не всю тестовую логику понимаешь
- как уже писала - тест - это не только действия
- но и проверки
- лучше проверки - реализовывать отдельно от действий
- собственно по проверке
- грамотнее использовать ждущие проверки
- на видео будет про это
- т к на момент проверки список с тасками может быть еще не догрузился
- могут возникать ошибки - не потому - что приложение работает не верно
- а потому - что на момент проверки оно еще не догрузилось
- также - можно обойтись без xPath )
- ясно, что твоя цель была - найти элементы внутри элемента с id='todo-list'
- и таким-то текстом
- и ты так выкрутилась)
- нам не надо выкручиваться
- найди css selector для элементов списка http://joxi.ru/L210nzMu6YEO6m
- и уже для этой коллекции элементов - выполнишь ждущую проверку
- опять отсылаю тебя к видео - и как обратиться к коллекции элементов
- и как выполнить ждущую проверку
- и как проверить тексты элементво коллекции
- еще важная особенность проверки, которую ты в итоге получишь
- что она проверяет не состояние одной таски
- а - сразу всего списка тасок
- это тоже важное достоинство проверки
- т к в таком случае - проверка гораздо точнее
- ведь после добавления таски - могло добавиться например 2 такие таски
- и проверяя лишь наличие таски с нужным текстом - мы кучу всего еще упускаем
- резюме
- правильная проверка = ждущая + проверяющая состояние всего списка
- проверку не надо прятать внутри метода-действия
- */
- }
- *********************************************************
- public void deleteTask(String taskName) {
- waitElementByXpath("//*[@id='todo-list']//*[text()='" + taskName + "']", 20);
- driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']")).click();
- /*
- тут нам надо не кликнуть на таске
- а лишь навести на нее мышку
- у SelenideElement - есть метод hover
- раз ты уже такой опытный товарищ, что пишешь xpath-выражения
- не буду тебя мучать - и просить упрощать версию до работы с тасками -
- строя цсс селекторы для таски по ее индексу в списке
- выше уже расмотрели - как получить коллекцию элементов = таски списка
- у селенидовской коллекции элементов - есть метод findBy
- который позволяет найти элемент коллекции по условию
- нам нужно условие - совпадение текста = exactText
- метод findBy - вернет найденный элемент
- у которого уже сможешь вызвать метод hover
- */
- waitElementByXpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::button", 20);
- driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::button")).click();
- /*
- как найти таску в списке - уже описали
- теперь - раз мы умеем, оттолкнувшись от списка тасок
- получить таску по тексту - уточним далее
- у SelenideElement - есть метод find - который позволит найти кнопку удаления по ее селектору
- внутри этого родительского элемента
- такой метод - вернет внутренний SelenideElement = кнопку
- для которой и вызовешь метод click
- снова благополучно обойдемся без xpath )
- вообще - лучще избегать его применения
- понятно - что бывает такая необходимость
- но далеко не так часто )
- например, вот тут Яков про это писал
- http://automated-testing.info/t/pomogite-razobratsya-s-problemoj-czikla-v-selenide/10467/8
- */
- assertFalse(driver.findElement(By.xpath("//*[@id='todo-list']")).getText().contains(taskName));
- /*
- и тут тебе нужна проверка - ждущая + состоянив всего списка
- не - такая-то таска отсутствует
- а - присутствуют только такие-то таски
- так ты проверишь - и что таска удалилась
- и что с остальными все ок
- ну и вынеси проверку из метода-действия
- */
- }
- ************************************************************************
- public void completeTask(String taskName) {
- waitElementByXpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::*/../*[@type='checkbox']", 20);
- driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::*/../*[@type='checkbox']")).click();
- /*
- аналогично тому - как ты искала кнопку удаления таски - внутри таски
- так и тут - по тому же принципу можно найти наш чекбокс
- только поищи для него селектор понагляднее )
- кстати = если этот метод применить к уже закомпличеной таске
- она переоткроется
- потому - некорректно называть метод completeTask
- https://docs.google.com/document/d/10qSwWTQ6pGfVZSwOes-1QSmdflMiGD2U_y53VHq2m20/edit#bookmark=kix.x92tktmmfsz2
- */
- assertTrue(driver.findElement(By.xpath("//*[@id='todo-list']")).getText().contains(taskName));
- /*
- ну да, после закомпличивания таски - можно проверить факт
- что на all фильтре - таски отображаются в списке - вне зависимости от их статуса
- это да)
- только опять - вынеси проверку из метода-действия
- сделай ее ждущей + проверяющей состояние всего списка тасок
- кстати, ты предпочитаешь использование xpath даже для простых случаев- когда css селектора
- с головой хватило бы )
- это не правильно)
- для этого приложения - возможно без явного применения xpath обойтись
- да, внутри некоторых служебных методов - таки xpath внутри их реализации будет использоваться
- но нам, явно его не придется использовать)
- */
- }
- public void clearCompleted() {
- waitElementByXpath("//*[@id='clear-completed']", 20);
- driver.findElement(By.xpath("//*[@id='clear-completed']")).click();
- /*
- еще отличительной чертой Selenide есть то - что не придется отдельно заботиться об ожиданиях
- $(...).click() - уже обеспечивается ожидание - что єлемент будет готов к клику на нем
- это очень облегчает написание тестов
- */
- try {
- assertFalse(driver.findElement(By.xpath("//*[@id='clear-completed']")).isDisplayed());
- } catch (NoSuchElementException e) {
- System.out.println("List isn't displayed after clear is completed");
- }
- /*
- таки да, кнопка становится не видимой)
- и далее на курсе - мы даже рассмотрим - почему именно эту проверку допустимо оставить внутри метода
- clearCompleted )
- но)
- проверка в тест-методе = если проверка не выполнилась = тест должен упасть
- в так реализованном коде - мы лишь прочитаем про это сообщение
- ну и как обычно)
- проверка должна быть ждущей
- и после clearCompleted - нужна проверка не только состояния кнопки(это как раз менее важно)
- а и состояния списка тасок
- вот эту проверку - надо делать обязательно и ни в коем случае не прятать ее внутри этого метода
- */
- }
- public static void waitElementByXpath(String xpath, long seconds) {
- WebDriverWait wait = new WebDriverWait(driver, seconds);
- wait.until(ExpectedConditions.elementToBeClickable(By.xpath(xpath)));
- }
- public static void waitElementById(String elementId, long seconds) {
- WebDriverWait wait = new WebDriverWait(driver, seconds);
- wait.until(ExpectedConditions.elementToBeClickable(By.id(elementId)));
- }
- /*
- хитро выкрутилась с этими методами)
- нам они не пригодятся
- а во второй части курса - и об этом поговорим)
- */
- }
- /*
- ***************************
- /*
- хороша ли идея
- сделать список, положить туда значения тудушек,
- из него в цикле добавить таски
- на самом деле, тут 2 вопроса)
- использовать ли для тестовых данных переменные
- как можно реализовать добавление нескольких тасок, вызвав один метод
- начнем со второго вопроса)
- его можно пока отложить )
- но если хочется challenge )
- почитай про varargs parameters http://www.linkex.ru/java/varargs.php
- намекну - что можно реализовать добавление тасок - используя varargs parameters
- в результате чего - будешь вызывать метод - add("t1", "t2", "t3", "t4")
- если пока с этим сложно - отложи
- это будет разобрано в следующем видео
- пока - просто знай, что так реализовать добавление тасок - можно)
- технически можно, и это усложнение метода add оправдано - т к иногда в начале тест-метода
- действительно - будет требоваться создать несколько тасок сразу - в рамках подготовки тестовой ситуации
- теперь первый вопрос)
- он - не так прост, как кажется)
- вообще - надо с осторожностью подходить к решению,
- какие тестовые данные стоит выносить в переменные, а какие - нет
- С вынесением тестовых данных в переменные надо быть осторожным - далеко не всегда это полезно.
- Часто тестовые данные разумно оставлять в логике самих тестов -
- таким образом код тестов более очевидный = KISS.
- Тут - как раз тот случай)
- Используй в качестве текстов тасок что-то лаконичное
- (task1, task2 .../ t1,t2,..../ a,b,..../ 1,2,....)
- Тогда код будет по-прежнему наглядный и не загроможденный и при этом - простой для восприятия
- Важно - чтобы код теста был как можно более очевидным и простым - с первого взгляда на него.
- И потому тестовые данные - как правило - не стоит выносить в переменные -
- чтобы не приходилось при анализе кода отвлекаться на то, что это за переменные,
- где объявлены или чем инициализированы.
- Почитай про KISS principle
- Какие тестовые данные стоит выносить в переменные.
- То, что применяется в нескольких методах и является строго определенным (не произвольные данные,
- а какие-то конкретные). Пример - логин-пароль для аккаунта, или какие-то предопределенные данные -
- которые всегда есть на начало работы с приложением.
- У нас - другой случай. Просто тестовые данные, которые нужны в единственном тест-методе.
- Эти данные не какие-то строго определенные - они такие, какими мы их решили сделать = произвольные
- И у нас нет цели использовать значение - длинные строки, которые будут загромождать код.
- В таких случаях - лучшим решением будет просто указывать в коде значения текстов тасок,
- без использования дополнительных переменных.
- Ну и, конечно, разумно остановиться на лаконичном варианте - для текстов тасок -
- чтобы код не загромождать.
- Понимаю твое стремление разгрузить код тест-метода)
- Мы его разгрузим, но благодаря другому)
- Уже кое-что тебе в этом ревью показала,
- далее над этим будем работать
- */
Advertisement
Add Comment
Please, Sign In to add comment