julia_v_iluhina

Untitled

Oct 4th, 2016
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 25.41 KB | None | 0 0
  1.  
  2. Вот это задание
  3. https://docs.google.com/document/d/1yvUML7eXyEyDh5asUIL7M88RStlE1RZmgUOJZSXjMVo/edit?usp=sharing
  4.  
  5. реши это задание, используя Selenide
  6. в видео - есть про то, как использовать Selenide
  7. https://www.youtube.com/watch?v=5c3z_iddWX0&feature=youtu.be
  8.  
  9. Да, мы на курсе и с чистым селениумом будем работать, но начнем  - именно с использования Selenide
  10. смотри план курса
  11. https://docs.google.com/spreadsheets/d/1avmeuOfyu_GC_rEAWxsUyv2O-VSJh7-KaZTAoCopP0E/edit?usp=sharing
  12. часть Web UI: The Art of Automation - используем Selenide
  13. часть Web UI: Software Development In Test - используем чистый Selenium
  14.  
  15. Такой подход позволяет изолировать разые темы друг от друга
  16. Мы в более комфортном режиме - рассмотрим многие темы (часть 1)
  17. И лишь потом начнем разбираться с тонкостями селениума (часть 2)
  18. В итоге - процесс обучения будет поэффективнее
  19.  
  20. ***********************************************
  21.  
  22. public class ToDoTest {
  23. /*
  24.     Имя тест-класса - лучше уточни
  25.  
  26.     приложение называется TodoMVC - от этого и оттолкнемся
  27.     TodoMVCTest - будет ок
  28.  
  29.     в faq - есть раздел по naming, посмотри
  30.     https://docs.google.com/document/d/10qSwWTQ6pGfVZSwOes-1QSmdflMiGD2U_y53VHq2m20/edit#heading=h.2zj10n877t2p
  31. */
  32. *******************************************
  33.     @Test
  34.     public void testTask() {
  35.     /*
  36.         у нас - е2е сценарий
  37.         посмотри на советы - как в таких случаях лучше назвать тест-метод
  38.         https://docs.google.com/document/d/10qSwWTQ6pGfVZSwOes-1QSmdflMiGD2U_y53VHq2m20/edit#bookmark=id.txqig9rkgybo
  39.     */
  40.         String[] taskNames = {"task1", "task2", "task3", "task4"};
  41.         for (int i = 0; i < taskNames.length; i++)
  42.             createTask(taskNames[i]);
  43.         /*
  44.             на добавление 4-х тасок - мы написали 3 строчки
  45.             и к тому же использовали цикл
  46.  
  47.             а если бы просто писали
  48.                 createTask("task1");
  49.                 createTask("task2");
  50.                 createTask("task3");
  51.                 createTask("task4");
  52.  
  53.             то было бы всего на 1 строчку длиннее
  54.             и значительно проще для восприятия
  55.  
  56.             в целом - надо избегать в тест-методах использовать сложную логику
  57.             for - уже сложная логика)
  58.  
  59.             причем - во вспомогательных методах - for или  if допустимы
  60.             а вот тест-методы - должны оставаться "тупыми"
  61.             погугли про KISS Principle
  62.  
  63.             в следующей работе - разберем как организовать вот такой метод
  64.             createTasks("task1", "task2", "task3", "task4");
  65.             пока остановись на четырех вызовах метода createTask
  66.  
  67.             что касается использования для тестовых данных переменных - ниже напишу
  68.  
  69.             тесты - это не только действия
  70.             но и проверка результатов
  71.             каждая операция - должна быть проверена сразу
  72.                         иначе - если возникнут ошибки - мы можем не разобраться в их причинах
  73.  
  74.                         нам нужно убедиться что
  75.                             операции выполняются
  76.                             операции выполняются с ожидаемым нами результатом
  77.  
  78.             тут - поскольку действия однотипные - можно проверить уже после добавления четвертой таски
  79.         */
  80.         deleteTask("task2");
  81.         /*
  82.             удалили - и проверь состояние списка тасок
  83.         */
  84.         completeTask("task4");
  85.         clearCompleted();
  86.         /*
  87.             и тут нужна проверка
  88.  
  89.             насчет проверки после completeTask...
  90.             тут ситуация поинтереснее
  91.             в принципе - проверку можно отложить на 1 шаг
  92.             и проверить состояние списка тасок после clear completed
  93.                 так можно поступить - т к проверка текстов тасок после закомпличивания таски
  94.                 даст нам проверку логики = все таски на all фильтре отображаются независимо от своего статуса,
  95.                 но не даст проверку факта закомпличивания
  96.                 это мы как раз допроверим после clear completed
  97.                 проверка текстов после clear completed как раз этот факт и допроверит
  98.         */
  99.  
  100.         driver.findElement(By.id("toggle-all")).click();
  101.         clearCompleted();
  102.         /*
  103.             тут  - также можно реализовать проверку
  104.             уже после этих 2-ух действий
  105.  
  106.             далее на курсе чуть подробнее коснемся этой темы
  107.             когда проверку можно отложить
  108.  
  109.             а вообще - правило такое
  110.             каждое действие в тесте должно быть проверено сразу
  111.         */
  112.     }
  113. *********************************************************
  114.     public void createTask(String taskName) {
  115.     /*
  116.         имя метода можно чуть упростить )
  117.  
  118.         все действия - выполняются над тасками
  119.         да и параметр - немного поясняет
  120.         можно без ущерба для точности
  121.         вместо
  122.         createTask(String taskName)
  123.         использовать
  124.         create(String taskName)
  125.  
  126.         аналогично - и для других вспомогательных методов-действий
  127.     */
  128.         driver.get("https://todomvc4tasj.herokuapp.com/");
  129.         /*
  130.             открыть нужный урл - нам достаточно лишь единожды
  131.  
  132.             я не буду вообще останавливаться на особенностях селенидовской или селениумской реализации
  133.             раз ты осилила версию на чистом селениуме - думаю, с селениде вообще не будет вопросов)
  134.  
  135.             открытие урла - это не добавление таски
  136.             это отдельное действие
  137.             которое не стоит скрывать в методе добавления таски
  138.             его вынеси в тест-метод - выше добавления тасок
  139.         */
  140.         waitElementById("new-todo", 20);
  141.         driver.findElement(By.id("new-todo")).sendKeys(taskName);
  142.         driver.findElement(By.id("new-todo")).sendKeys(Keys.ENTER);
  143.         assertTrue(driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']")).isDisplayed());
  144.         /*
  145.             проверки - не прячь в методах-действиях
  146.             т к тогда глядя на тест-метод - не всю тестовую логику понимаешь
  147.  
  148.             как уже писала - тест - это не только действия
  149.             но и проверки
  150.  
  151.             лучше проверки - реализовывать отдельно от действий
  152.  
  153.             собственно по проверке
  154.             грамотнее использовать ждущие проверки
  155.             на видео будет про это
  156.             т к на момент проверки список с тасками может быть еще не догрузился
  157.             могут возникать ошибки - не потому - что приложение работает не верно
  158.             а потому - что на момент проверки оно еще не догрузилось
  159.  
  160.             также - можно обойтись без xPath )
  161.             ясно, что твоя цель была - найти элементы внутри элемента с id='todo-list'
  162.             и таким-то текстом
  163.             и ты так выкрутилась)
  164.             нам не надо выкручиваться
  165.             найди css selector для элементов списка http://joxi.ru/L210nzMu6YEO6m
  166.             и уже для этой коллекции элементов - выполнишь ждущую проверку
  167.             опять отсылаю тебя к видео - и как обратиться к коллекции элементов
  168.             и как выполнить ждущую проверку
  169.             и как проверить тексты элементво коллекции
  170.  
  171.             еще важная особенность проверки, которую ты в итоге получишь
  172.             что она проверяет не состояние одной таски
  173.             а - сразу всего списка тасок
  174.             это тоже важное достоинство проверки
  175.             т к в таком случае - проверка гораздо точнее
  176.             ведь после добавления таски - могло добавиться например 2 такие таски
  177.             и проверяя лишь наличие таски с нужным текстом - мы кучу всего еще упускаем
  178.  
  179.             резюме
  180.             правильная проверка = ждущая + проверяющая состояние всего списка
  181.             проверку не надо прятать внутри метода-действия
  182.  
  183.         */
  184.     }
  185. *********************************************************
  186.     public void deleteTask(String taskName) {
  187.         waitElementByXpath("//*[@id='todo-list']//*[text()='" + taskName + "']", 20);
  188.         driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']")).click();
  189.         /*
  190.             тут нам надо не кликнуть на таске
  191.             а лишь навести на нее мышку
  192.  
  193.             у SelenideElement - есть метод hover
  194.  
  195.             раз ты уже такой опытный товарищ, что пишешь xpath-выражения
  196.             не буду тебя мучать - и просить упрощать версию до работы с тасками -
  197.             строя цсс селекторы для таски по ее индексу в списке
  198.  
  199.             выше уже расмотрели - как получить коллекцию элементов = таски списка
  200.             у селенидовской коллекции элементов - есть метод findBy
  201.             который позволяет найти элемент коллекции по условию
  202.             нам нужно условие - совпадение текста  = exactText
  203.  
  204.             метод findBy - вернет найденный элемент
  205.             у которого уже сможешь вызвать метод hover
  206.         */
  207.         waitElementByXpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::button", 20);
  208.         driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::button")).click();
  209.         /*
  210.             как найти таску в списке - уже описали
  211.             теперь - раз мы умеем, оттолкнувшись от списка тасок
  212.             получить таску по тексту - уточним далее
  213.  
  214.             у SelenideElement - есть метод find  - который позволит найти кнопку удаления по ее селектору
  215.             внутри этого родительского элемента
  216.  
  217.             такой метод - вернет внутренний SelenideElement = кнопку
  218.             для которой и вызовешь метод click
  219.  
  220.             снова благополучно обойдемся без xpath )
  221.             вообще - лучще избегать его применения
  222.             понятно - что бывает такая необходимость
  223.             но далеко не так часто )
  224.             например, вот тут Яков про это писал
  225.             http://automated-testing.info/t/pomogite-razobratsya-s-problemoj-czikla-v-selenide/10467/8
  226.         */
  227.         assertFalse(driver.findElement(By.xpath("//*[@id='todo-list']")).getText().contains(taskName));
  228.         /*
  229.             и тут тебе нужна проверка - ждущая + состоянив всего списка
  230.  
  231.             не - такая-то таска отсутствует
  232.             а - присутствуют только такие-то таски
  233.  
  234.             так ты проверишь - и что таска удалилась
  235.             и что с остальными все ок
  236.  
  237.             ну и вынеси проверку из метода-действия
  238.         */
  239.     }
  240. ************************************************************************
  241.     public void completeTask(String taskName) {
  242.         waitElementByXpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::*/../*[@type='checkbox']", 20);
  243.         driver.findElement(By.xpath("//*[@id='todo-list']//*[text()='" + taskName + "']/following-sibling::*/../*[@type='checkbox']")).click();
  244.         /*
  245.             аналогично тому - как ты искала кнопку удаления таски  - внутри таски
  246.             так и тут - по тому же принципу можно найти наш чекбокс
  247.             только поищи для него селектор понагляднее )
  248.  
  249.             кстати = если этот метод применить к уже закомпличеной таске
  250.             она переоткроется
  251.             потому - некорректно называть метод completeTask
  252.             https://docs.google.com/document/d/10qSwWTQ6pGfVZSwOes-1QSmdflMiGD2U_y53VHq2m20/edit#bookmark=kix.x92tktmmfsz2
  253.            
  254.         */
  255.         assertTrue(driver.findElement(By.xpath("//*[@id='todo-list']")).getText().contains(taskName));
  256.         /*
  257.             ну да, после закомпличивания таски - можно проверить факт
  258.             что на all фильтре - таски отображаются в списке - вне зависимости от их статуса
  259.             это да)
  260.            
  261.             только опять - вынеси проверку из метода-действия
  262.             сделай ее ждущей + проверяющей состояние всего списка тасок
  263.            
  264.             кстати, ты предпочитаешь использование xpath даже для простых случаев- когда css селектора
  265.             с головой хватило бы )
  266.             это не правильно)
  267.             для этого приложения - возможно без явного применения xpath обойтись
  268.            
  269.             да, внутри некоторых служебных методов - таки xpath внутри их реализации будет использоваться
  270.             но нам, явно его не придется использовать)
  271.            
  272.         */
  273.     }
  274.  
  275.     public void clearCompleted() {
  276.         waitElementByXpath("//*[@id='clear-completed']", 20);
  277.         driver.findElement(By.xpath("//*[@id='clear-completed']")).click();
  278.         /*
  279.             еще отличительной чертой Selenide есть то - что не придется отдельно заботиться об ожиданиях
  280.             $(...).click() - уже обеспечивается ожидание - что єлемент будет готов к клику на нем
  281.             это очень облегчает написание тестов
  282.         */
  283.         try {
  284.             assertFalse(driver.findElement(By.xpath("//*[@id='clear-completed']")).isDisplayed());
  285.         } catch (NoSuchElementException e) {
  286.             System.out.println("List isn't displayed after clear is completed");
  287.         }
  288.         /*
  289.             таки да, кнопка становится не видимой)
  290.            
  291.             и далее на курсе - мы даже рассмотрим - почему именно эту проверку допустимо оставить внутри метода
  292.             clearCompleted )
  293.            
  294.             но)
  295.             проверка в тест-методе = если проверка не выполнилась = тест должен упасть
  296.             в так реализованном коде - мы лишь прочитаем про это сообщение
  297.            
  298.             ну и как обычно)
  299.             проверка должна быть ждущей
  300.            
  301.             и после clearCompleted - нужна проверка не только состояния кнопки(это как раз менее важно)
  302.             а и состояния списка тасок
  303.             вот эту проверку - надо делать обязательно и ни в коем случае не прятать ее внутри этого метода
  304.         */
  305.     }
  306.  
  307.     public static void waitElementByXpath(String xpath, long seconds) {
  308.         WebDriverWait wait = new WebDriverWait(driver, seconds);
  309.         wait.until(ExpectedConditions.elementToBeClickable(By.xpath(xpath)));
  310.     }
  311.  
  312.     public static void waitElementById(String elementId, long seconds) {
  313.         WebDriverWait wait = new WebDriverWait(driver, seconds);
  314.         wait.until(ExpectedConditions.elementToBeClickable(By.id(elementId)));
  315.     }
  316.    
  317.     /*
  318.         хитро выкрутилась с этими методами)
  319.         нам они не пригодятся
  320.        
  321.         а во второй части курса - и об этом поговорим)
  322.     */
  323. }
  324. /*
  325.     ***************************
  326.     /*
  327.       хороша ли идея
  328.       сделать список, положить туда значения тудушек,
  329.       из него в цикле добавить таски
  330.  
  331.        на самом деле, тут 2 вопроса)
  332.             использовать ли для тестовых данных переменные
  333.             как можно реализовать добавление нескольких тасок, вызвав один метод
  334.  
  335.        начнем со второго вопроса)
  336.             его можно пока отложить )
  337.             но если хочется challenge )
  338.                 почитай про varargs parameters http://www.linkex.ru/java/varargs.php
  339.                 намекну - что можно реализовать добавление тасок - используя varargs parameters
  340.                 в результате чего - будешь вызывать метод - add("t1", "t2", "t3", "t4")
  341.                 если пока с этим сложно - отложи
  342.                     это будет разобрано в следующем видео
  343.                     пока - просто знай, что так реализовать  добавление тасок - можно)
  344.                     технически можно, и это усложнение метода add оправдано - т к иногда в начале тест-метода
  345.                     действительно - будет требоваться создать несколько тасок сразу - в рамках подготовки тестовой ситуации
  346.  
  347.        теперь первый вопрос)
  348.             он - не так прост, как кажется)
  349.             вообще - надо с осторожностью подходить к решению,
  350.             какие тестовые данные стоит выносить в переменные, а какие - нет
  351.  
  352.                     С вынесением тестовых данных в переменные надо быть осторожным - далеко не всегда это полезно.
  353.                     Часто тестовые данные разумно оставлять в логике самих тестов -
  354.                     таким образом код тестов более очевидный = KISS.
  355.                     Тут - как раз тот случай)
  356.  
  357.                     Используй в качестве текстов тасок что-то лаконичное
  358.                     (task1, task2 .../ t1,t2,..../ a,b,..../ 1,2,....)
  359.                     Тогда код будет по-прежнему наглядный и не загроможденный и при этом - простой для восприятия
  360.                     Важно - чтобы код теста был как можно более очевидным и простым - с первого взгляда на него.
  361.  
  362.                     И потому тестовые данные - как правило - не стоит выносить в переменные -
  363.                     чтобы не приходилось при анализе кода отвлекаться на то, что это за переменные,
  364.                     где объявлены или чем инициализированы.
  365.                     Почитай про KISS principle
  366.  
  367.                     Какие тестовые данные стоит выносить в переменные.
  368.                     То, что применяется в нескольких методах и является строго определенным (не произвольные данные,
  369.                     а какие-то конкретные). Пример - логин-пароль для аккаунта, или какие-то предопределенные данные -
  370.                     которые всегда есть на начало работы с приложением.
  371.  
  372.                     У нас - другой случай. Просто тестовые данные, которые нужны в единственном тест-методе.
  373.                     Эти данные не какие-то строго определенные - они такие, какими мы их решили сделать = произвольные
  374.                     И у нас нет цели использовать значение - длинные строки, которые будут загромождать код.
  375.                     В таких случаях - лучшим решением будет просто указывать в коде значения текстов тасок,
  376.                     без использования дополнительных переменных.
  377.                     Ну и, конечно, разумно остановиться на лаконичном варианте - для текстов тасок -
  378.                     чтобы код не загромождать.
  379.  
  380.                     Понимаю твое стремление разгрузить код тест-метода)
  381.                     Мы его разгрузим, но благодаря другому)
  382.                     Уже кое-что тебе в этом ревью показала,
  383.                     далее над этим будем работать
  384.  
  385.     */
Advertisement
Add Comment
Please, Sign In to add comment