Advertisement
julia_v_iluhina

Untitled

Jan 4th, 2017
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 36.14 KB | None | 0 0
  1. по коду
  2. https://github.com/AleksanderPopov/automician_course/blob/master/src/test/java/com/alexautomician/todomvc/tests/TodoMVCTest.java
  3.  
  4. public class TodoMVCTest extends BaseTest {
  5. ...
  6.     @Test
  7.     public void tasksBasicFlow() {
  8.     @Test
  9.     public void smokeTasksFlow() {
  10. /*
  11.     не стоило объединять в одном тест-классе эти тест-методы
  12.     на самом деле - в реальном проекте - не было бы смысла держать в одном проекте оба таких е2е теста
  13.     второй вариант - более разумно оставить - т к он оптимальнее
  14.  
  15.     в нашем случае - это просто разные задания
  16.     разные задания = структурная информация
  17.     а структурную информацию грамотнее фиксировать а уровне пекеджей
  18.     в каждом из которых - свой тест-класс  со своим набором методов
  19.     и в таком случае - именовать тест-классы можно исходя из правил
  20.     https://docs.google.com/document/d/13dNyFGbI7mV22UUhH8E0LJ7SzabAmX7Bw7VCHScYfiU/edit#heading=h.xbzelgj7l3up
  21.  
  22.     т е - пока - для обеих работ - имя класса - TodoMVCTest - будет корректным
  23.     java позволяет в одном проекте держать классы с одним именем - в разных пекеджах
  24.  
  25.     да и ты вроде бы - предыдущие задания - прячешь в history/
  26.     tasksBasicFlow() - уже история)
  27.  
  28.     тогда и не будет проблемы с неймингом тест-методов
  29.     smoke - важная информация, да
  30.     но - это НЕ информация о тест-методе (в общем случае)
  31.     это - информация о покрытии (оно может быть реализовано и несколькими тест-методами нескольких тест-классов)
  32.     Это еще мы промоделируем, но чуть позже)
  33.  
  34.     пока
  35.      1 - разбей на пекеджи
  36.          каждое задание = свой пекедж
  37.      2 - у метода  smokeTasksFlow() -  smoke - лишнее в имени
  38.        tasksFlow, commonTasksFlow - будет OK
  39. */
  40.  
  41.     @Test
  42.     public void addEditDeleteCompleted() {
  43.     @Test
  44.     public void editDeleteCompleteClearActive() {
  45.     @Test
  46.     public void editActivateClearDeleteAll() {
  47. /*
  48.     методы - явно не фиче-тесты получились
  49.     это - тоже е2е-ы
  50.     разберем отдельно
  51.     и сначала на тест-плане
  52. */
  53. **********************************
  54.  
  55.     @Test
  56.     public void smokeTasksFlow() {
  57.  
  58.         page.add("1")
  59.                 .toggle("1");
  60. /*
  61.     тут - нужна проверка текстов тасок
  62.     проверим, что на all таски отображаются вне зависимости от статуса
  63.     а проверка после перехода на Active - лишь допроверит факт закомпличивания
  64.     и хорошо проверит - фильтеринг
  65. */
  66.         page.goActive()
  67.                 .shouldBeEmpty()
  68. *************************************
  69.  
  70. private SelenideElement editingTask = $(".editing .edit");
  71. /*
  72.     не, это - не editingTask )
  73.     это поле для ввода нового текста таски
  74.     да и вообще эта переменная - не нужна
  75.  
  76.     полезно придерживаться вот такой схемы
  77.     есть у нас переменная для коллекции тасок - tasks
  78.  
  79.     и если нужно доступиться к чему-то из этой структуры - то отталкиваться нужно от этой переменной
  80.     а не использовать новый независимый селектор
  81.  
  82.     что это нам дает
  83.         наглядность кода
  84.              сравни
  85.              $(".editing .edit")
  86.              и
  87.              tasks.findBy(...).find(...)
  88.              во втором случае - суть длиннее
  89.              но - нагляднее и понятнее - с чем мы работаем
  90.  
  91.              по сути - что нам нужно получить
  92.              нам нужно получить
  93.              таску с классом editing
  94.              а в ней - внутренний элемент с классом edit
  95.              это и будет описано во втором варианте
  96.         помимо наглядности, так ты получишь код, в котором будет меньше независимых селекторов
  97.              что в долгосрочном периоде - помогает проще поддерживать код
  98.              вот поменялось приложение
  99.              и чем меньше независимых селекторов - тем меньше придется адаптировать код
  100.         еще приятный бонус в Selenide - при использовании вот такого варианта tasks.findBy(...).find(...)
  101.              (по сравнению с независимым селектором)
  102.              код ошибки будет более точным
  103.              будет жадоба на какую-то конкретную часть этого выражения
  104.              что тоже удобно
  105.  
  106.      в общем  - очень рекомендую - отталкиваться от сущности, для которой уже объявлена переменная
  107.      и продвигаться от общего к частному
  108.  
  109. */
  110. ****************************
  111.   public TaskPage editEnter(String fromTaskName, String toTaskName) {
  112.         tasks.findBy(exactText(fromTaskName))
  113.                 .doubleClick();
  114.         editingTask
  115.                 .setValue(toTaskName)
  116.                 .pressEnter();
  117.         return this;
  118.     }
  119.  
  120.     public TaskPage editCancel(String taskName) {
  121.         tasks.findBy(exactText(taskName))
  122.                 .doubleClick();
  123.         editingTask
  124.                 .setValue(taskName)
  125.                 .pressEscape();
  126.         return this;
  127.     }
  128. /*
  129.     посмотри - как похожи методы
  130.  
  131.     вместо того, чтоб заводить переменную editingTask
  132.     лучше реализовать метод
  133.         SelenideElement startEdit(String fromTaskName, String toTaskName)
  134.         в котором будет происходить все вплоть до ввода нового значения
  135.         и метод будет возвращать SelenideElement = элемент в котором новое значение было введено
  136.  
  137.     чтоб потом вызывать такой метод
  138.         startEdit(fromTaskName, toTaskName).pressEnter();
  139.  
  140.     по поводу реализации и набора параметров   editCancel(String taskName)
  141.         тут вся соль отмены редактирования в том - что мы УЖЕ ввели новое значение
  142.          и нажав ескейп - вернули старое значение = отменили
  143.         не надо убирать второй параметр toTaskName - это искажает смыслы
  144.  
  145.     имена методов
  146.         editEnter - я бы в данном случае - не уточнялась до энтера - т к это стандартная реализация редактирования
  147.         как доберемся до автоматизации additional edit operations - там уже будем уточняться
  148.  
  149.         editCancel - тоже с недостатками
  150.         что мы делаем = отменяем редактирование = cancelEdit
  151.         а если хочется подчеркнуть последовательность действий - startEditThenCancel
  152.         что-то такое
  153.         я приверженец первого варианта
  154.         вот сюда взгляни
  155.         https://docs.google.com/document/d/13dNyFGbI7mV22UUhH8E0LJ7SzabAmX7Bw7VCHScYfiU/edit#heading=h.o7vsh4r93b55
  156. */
  157. ******************************************
  158.     public TaskPage toggleAll() {
  159.         $("#toggle-all").click();
  160.         return this;
  161.     }
  162.     public TaskPage completeAll() {
  163.         $("#toggle-all").click();
  164.         return this;
  165.     }
  166.  
  167.     public TaskPage toggle(String taskName) {
  168.         tasks.findBy(exactText(taskName)).$(".toggle").click();
  169.         return this;
  170.     }
  171.  
  172.     public TaskPage activate(String taskName) {
  173.         return toggle(taskName);
  174.     }
  175. /*
  176.     посмотри на реализацию методов
  177.     toggleAll и completeAll
  178.     и
  179.     toggle и activate
  180.  
  181.     в каждой паре - оба метода делают одно и то же
  182.     но те же самые действия - называют по-разному
  183.     в паре toggle и activate - ты выкрутился более DRY
  184.  
  185.     но все равно - так нельзя
  186.     вызови activate для активной таски
  187.     что произойдет?
  188.  
  189.     а completeAll() для ситуации, когда все таски и так закомпличены?
  190.  
  191.     будут выполнены противоположные действия
  192.     а имя метода - должно точно отражать что он делает
  193.     вне зависимости от контекста его вызова
  194.     иначе - это будет путать
  195.  
  196.     посмотри перевод toggle = переключить
  197.     и этот термин - корректный и для случая с закомпличиванием, и для случая с активацией
  198.  
  199.     тут есть варианты вот какие
  200.  
  201.     простой, лаконичный
  202.         оставить в пейдже - только методы toggle & toggleAll
  203.         и применять их и для закомпличивания, и для переоткрытия
  204.         и в коде, при вызове - кратко комментировать - что это
  205.  
  206.     второй, более сложный в реализации, более тормознутый в использовании
  207.         но с более красивым набором методов
  208.  
  209.         реализовать не toggle & toggleAll
  210.         а
  211.         complete
  212.         activate
  213.  
  214.         completeAll
  215.         activateAll
  216.  
  217.         чтоб методы отвечали своим именам - нужно встроить в них перед выполнением действия -
  218.         проверки
  219.         чтоб действие просто не могло выполниться - если таски в не верном состоянии на начало операции
  220.         тут проверка будет работать - не как проверка тестовой логики
  221.         а как инструмент, который обеспечивает только правильную работу метода - метод будет корректно работать
  222.         только в правильном контексте
  223.  
  224.     в этом простом приложении - я бы пошла первым путем
  225.     в более сложных вариантах - предпочла бы второй
  226.     цель - меньше всего держать в голове на этапе написания самого теста
  227. */
  228. *******************************
  229.     public TaskPage shouldHaveCompleted(String taskName) {
  230.         tasks.findBy(text(taskName)).find(".toggle").shouldBe(selected);
  231.         return this;
  232.     }
  233. /*
  234.     я бы не выносила это как отдельную проверку, если честно
  235.     кстати - вот тебе - хорошая идея для проверки
  236.     которую можно встроить в activate (в complete - будет что-то похожее )
  237.  
  238.     и я бы везде - где получала таску по ее тексту - использовала один и тот же кондишен - exactText
  239.     и точно, и одинаково
  240.     чтоб потом не маяться
  241.         не ловить странные ошибки
  242.             (например выполняешь проверку для "ask", а она выполняется в реальности - для "task1", которая идет раньше по списку)
  243.         не думать - почему тут так получаем таску, а тут эдак. Однозначный код - всегда лучше. Если делаем так-то - то делаем так-то
  244.         тут разнообразие - наш враг
  245. */
  246. *********************************************************
  247.     public TaskPage shouldHaveCompleted(String... taskNames) {
  248.         for (String taskName : taskNames) {
  249.             shouldHaveCompleted(taskName);
  250.         }
  251.         return this;
  252.     }
  253. /*
  254.     сравни
  255.     этот цикл
  256.     и такой вариант
  257.     tasks.filterBy(...).shouldHave(exactTexts(taskNames));
  258.  
  259.     в любом случае - второй вариант - лучше - т к эффективнее (1 ждущая проверка вместо нескольких) и проще
  260.     если можно обойтись без циклов - надо обходиться
  261.  
  262.     тут - тоже
  263.     такая проверка - не нужна
  264.     но какие-то тут описанные идеи - можно применить для реализации
  265.     completeAll и activateAll
  266. */
  267. ************************************
  268. public TaskPage shouldBeItemsLeft(int i) {
  269. /*
  270.     избегай однобуквенных имен переменных
  271.     только для итераторов цикла это ок
  272.     https://google.github.io/styleguide/javaguide.html#s5.2.6-parameter-names
  273.  
  274.     сравни
  275.     shouldBeItemsLeft
  276.     shouldItemsLeft
  277.     мне кажется - второй вариант - попонятнее
  278.     ?
  279. */
  280. *****************************************
  281.     public TaskPage goAll() {
  282.         $("#filters>li:nth-of-type(1)>a").click();
  283.         tasks = $$("#todo-list>li");
  284.         return this;
  285.     }
  286.  
  287.     public TaskPage goActive() {
  288.         $("#filters>li:nth-of-type(2)>a").click();
  289.         tasks = $$("#todo-list>li.active");
  290.         return this;
  291.     }
  292.  
  293.     public TaskPage goCompleted() {
  294.         $("#filters>li:nth-of-type(3)>a").click();
  295.         tasks = $$("#todo-list>li.completed");
  296.         return this;
  297.     }
  298. /*
  299.     по первым строчкам методов
  300.     т к приложение простенькое - можно вполне обойтись вариантом
  301.     $(By.linkText(...))
  302.     для приложения посложнее я бы применяла
  303.     $$("#filters>li").findBy(exactText("..."))
  304.     а т к $$("#filters>li") - повторялся бы трижды
  305.     то вынесла бы $$("#filters>li") - в переменную пейджа
  306.  
  307.     по второй строчке
  308.     это зло)
  309.     ты добавил магии, и сильно
  310.     да и проверки не обеспечил точные
  311.     ведь - проверяя коллекцию - $$("#todo-list>li.active")
  312.     мы не гарантируем - что других тасок, которые в эту коллекцию не попадают - не видно в списке
  313.     тут нужно было - оперировать $$("#todo-list>li").filter(visible)
  314.     еще раз посмотри - что я писала насчет проверок
  315.         может пригодиться вот это
  316.         http://joxi.ru/l2ZNaR0F83gJv2
  317.         Посмотри видео Якова про это - https://drive.google.com/file/d/0B8hgIBw8-V-AdGxxU1R3enl1RzQ/view?ts=567ab8d7
  318.  
  319.         чуть больше пояснений
  320.             мы можем быть максимально точными и держать 4 проверки
  321.                 2 -
  322.                     в списке = такси с такими-то текстами
  323.                     в списке = пусто
  324.                 и еще 2 -
  325.                     в отфильтрованном по visible списке = таски с такими-то текстами
  326.                     в отфильтрованном по visible списке = пусто
  327.                 И за точность будем платить  тем - что надо думать - когда какую проверку вызвать правильнее
  328.                 и если это делать бездумно - то при небольших изменениях сценариев - могут тесты падать на проверках,
  329.                 или второй вариант - не будем нормально пользоваться полученной точностью...
  330.  
  331.                 мы можем исходить из того, что ошибку, когда невидимые таски копятся в списке - мы тестим на более низком уровне,
  332.                 и на UI уровне - нам не нужно до этого уточняться. Поэтому - мы будем держать всего 2 проверки
  333.                       в отфильтрованном по visible списке = таски с такими-то текстами
  334.                       в отфильтрованном по visible списке = пусто
  335.                 В таком случае - каждый раз понятно - какую проверку вызывать - получаем более KISS картину
  336.                 правда, платим за это точностью) Но - возможно - если мы уже отдельно это в тестах покрыли -
  337.                 что у нас не копятся невидимые таски - так мы и не платим ) И - тогда - все проще в написании тестов,
  338.                 и в их сопровождении.
  339.                 Тогда - поскольку обе проверки реализованы одинаково и других нету - можно из имен проверок скрыть этот нюанс
  340.                 и назвать их assertTasks и assertNoTasks (хотя в них работаем с отфильтрованным по visible списком тасок)
  341.  
  342.  
  343.     почитай
  344.     http://enterprisecraftsmanship.com/2016/09/29/law-of-demeter-and-immutability/
  345.     http://enterprisecraftsmanship.com/2016/05/12/immutable-architecture/
  346.     а чтоб уберечь себя от мутабельности свойств объекта - можно их как final объявлять
  347.     даже более - так технически грамотнее делать)
  348.     просто обычно - на уровне тестов - уже многие считают это задротством
  349.     я попробовала на более серьезных проектах
  350.     мне идея с final - понравилась)
  351.  
  352. */
  353. ************************************************
  354. по тест-плану
  355.  
  356. https://docs.google.com/spreadsheets/d/1eAw67UrF58vyCf0Fk7f9hzoFFICgkeYVhhrph4XSb5g/edit#gid=0
  357.  
  358. /*
  359.     мы - по-прежнему - планируем smoke
  360.     это значит покрываем только высокоприоритетное и ТОЛЬКО на одном контексте
  361.  
  362.     и еще - один фиче-тест - проверяет одну фичу
  363.     лишь одну
  364.  
  365.     фактически - разгрузив наш е2е (что ты успешно сделал)
  366.     надо было допокрыть фиче-тестами
  367.     http://joxi.ru/Rmzqpx8H00kn1r
  368.     3 штуки - для каждого действия
  369.     и в рамках проверок в фиче-тестах - второй проверкой - покрой проверку items left
  370.     просто потому что по пути и это почти ничег не стоит
  371.  
  372.     у тебя реализованы - не фиче-тесты
  373.     а небольшие е2е тесты
  374.     учти по оформлению фиче-тестов
  375.     http://pastebin.com/4TiQi6jR, строки 51-70
  376.     и
  377.     это
  378.          имя фиче-теста - что тестим и на каком фильтре
  379.  
  380.             структура фиче-теста
  381.               предварительные действия
  382.               тестируемое действие
  383.               проверки
  384.  
  385.             предварительные действия начнем с комментария //given - ...
  386.             чтоб было понятно - что это предварительные действия и что за ситуацию мы в результате их получим
  387.             внутри и в конце блока предварительных действий - проверок не делаем
  388.             (мы это тут не тестируем, а используем для создания тестовой ситуации, ниже будет подробнее)
  389.  
  390.             после предварительных действий - пропустим строку
  391.             чтоб выделить - вот подготовка, вот - тестируемое действие
  392.  
  393.             проверки
  394.             сначала - более важные
  395.             затем - менее важные
  396.             (собственно - так ты и реализовал)
  397.             такой порядок - чтобы даже если тест упадет на менее важной проверке - был фидбек о важной проверке
  398.  
  399.             еще - в фиче-тестах мы можем себе позволить более интересные тестовые ситуации
  400.             например - редактирование второй таски в списке
  401.  
  402.             Это к общему сведению)
  403.  
  404.                 Есть разные способы выполнять предварительные действия
  405.                 Мы сейчас делаем это через действия на UI (User Interface)
  406.                 А есть еще методы - работать непосредственно с данными (далее вы такое тоже попробуете)
  407.                 Так вот через действия на UI - предварительные действия не быстрые и часто не достаточно надежные
  408.                 А через непосредственную работу с данными - предварительные действия быстрые и надежные
  409.  
  410.                 Если предварительные действия медленные или не надежные
  411.                 То проверка в конце предварительных действий нужна
  412.  
  413.                 А если мы уверены - что после предварительных действий гарантировано все ОК,
  414.                 то и проверок не надо после предварительных действий
  415.  
  416.                 Но, поскольку наше приложение - простое
  417.                 Разумно не делать проверку в конце предварительных действий
  418.                 чтобы наши тесты были эффективнее
  419.  
  420.                 Тестировали бы что-то типа соцсети и если бы предварительные действия были
  421.                 реализованы через UI - да, после предварительных действий было бы разумно
  422.                 выполнить проверку (проверка после предварительных действий нам позволяет отличить -
  423.                 ошибка возникла на этапе выполнения тестируемого действия, или все же раньше)
  424.  
  425. */
  426. **********************************************************************************************
  427. =========================================================================================
  428. 1. "оба варианта, которые ты привел - одинаково ненадежны)
  429.  
  430.    $$(tasks) - лишь рассказ про то - как искать коллекцию
  431.  
  432.    $$(tasks) - мы начинаем ее обход, и получим коллекцию, которая есть на этот момент
  433.    ты знаешь универсальный способ определить - что коллекция догрузилась?
  434.    любая коллекция, сферическая в вакууме )"
  435.  
  436.         >>>>>>>> ух, тяжеловато было это понять)) посмотрел вебинары по sdet, вроде
  437.                 понятнее стало. типа если мы хотим чего то подождать от списка конкретного,
  438.                 то будем писать $$().shouldHave(size(7)) - ждать пока элементов 7, и
  439.                 только потом работать? и метод get(index) Должен по идее тоже ждать
  440.                 размера листа...правильно я понимаю теперь?
  441. /*
  442.     да, если ты планируешь работать со списком - через обход коллекции - таки да - нужна проверка перед этим
  443.     уже писала - мне ни разу пока не пригодилось не в отладочных целях - делать такой обход)
  444.  
  445.     а вот варианты $$(...).get(...) $$(...).find(....) - тут уже предварять это проверками не нужно
  446.     т к при начале работы с таким элементом - Selenide будет ждать его видимости и так
  447. */
  448. =========================================================================================
  449. 2. "public TaskPage completedShouldHaveTexts(String... texts) {
  450.       public TaskPage completedListShouldBeEmpty() {
  451.       /*
  452.           Методы реализованы пристойно
  453.  
  454.           но - они все равно не нужны)
  455.           про это Яков говорил в видео
  456.           https://drive.google.com/file/d/0B8hgIBw8-V-AUDhxWDg1YmYxM3c/view?usp=sharing
  457.           примерно с 58-ой минуты, минут 5-7 посмотри"
  458.  
  459.                >>>>>>>> типа мы сейчас пишем функциональные тесты, поэтому нет
  460.                        смысла проверять что к задачке добавился класс, а лучше
  461.                        проверить функционал toggle -> filter, clearCompleted ?
  462.    /*
  463.        мы и сейчас, и далее везде на курсе - пишем функциональные тесты)
  464.        и да, верно, закомпличивание можно проверить тобой описанными способами
  465.        этого касалась и в ревью на твой сценарий
  466.        думаю, уже вопросы должны были отпасть
  467.    */"
  468.  
  469.        >>>>>>>> у меня сейчас есть метод
  470.  
  471.                    public TaskPage shouldBeEmpty() {
  472.                        tasks.shouldBe(empty);
  473.                        return this;
  474.                    }
  475.  
  476.                разве его нужно удалять? если я бегаю по фильтрам, и мне нужно
  477.                проверить что фильтр поменялся (например с Active на Completed)
  478.                и нет ни одной закомпличеннной таски, как мне это сделать,
  479.                если не смотреть размер тасок?
  480. /*
  481.    а я и не предлагаю удалить метод shouldBeEmpty()
  482.  
  483.    мне не нравятся методы - где ты фильтруешь список тасок по классу active / completed
  484.    это - как раз бессмысленно - т к не обеспечивает проверки = мы видим такие-то таски на таком-то фильтре
  485.    на active и completed фильтрах - разумно проверять $$("#todo-list>li").filter(visible)
  486.    на каждом из фильтров - мы видим лишь часть из всех тасок
  487.    это и нужно проверить
  488.    а какой класс у тасок - active / completed - это уже больше UI детали
  489.    конечно - если надумаешь реализовывать методы
  490.        complete & activate
  491.        completeAll & activateAll
  492.    вот в них - внутри этих методов - таки разумно использовать проверки основанные на работе с  классами active / completed
  493.    там это - будет уместно
  494. */
  495. =========================================================================================
  496. 3. ""не понимаю ценности BaseTest поясни, что из реализованного в BaseTest - ценно"
  497.  
  498.             >>>>>>>> ну как минимум он нужен для 'Configuration.browser = "firefox";'
  499.     /*
  500.         по умолчанию - так оно и есть)
  501.         потому - ничего и не нужно делать
  502.     */"
  503.  
  504.            >>>>>>>> я знаю что по умолчанию так и есть, но явные указывания таких
  505.                    глобальных переменных в конфиге необходимо, как по мне) чтобы мне
  506.                    не надо было вспоминать в каком там классе эти настройки хранятся
  507.                    в селениде, а чтоб у меня это было все в моем проекте)
  508.  
  509.                    про дефолт - в pom Тоже можно ставить last version, но это чревато
  510.                    нехорошими последствиями)
  511.  
  512.                    не хочу чтоб обновление либы могло повлиять на мои тест конфигурации
  513. /*
  514.    ну, аналогия не совсем удачная, по моему мнению
  515.    я бы в поме тоже про ласт версию ничего не писала)
  516.  
  517.    но ок
  518.    я принимаю доводы)
  519.    как весомые)
  520. */
  521. =========================================================================================
  522. 4. "Я бегло тебе ответила
  523.     http://joxi.ru/BA0p30gsJJbq7A (edited)
  524.     1 - начни  тут фразу с page .
  525.     будет нагляднее
  526.  
  527.     2 и далее - не хватает проверок"
  528.  
  529.        >>>>>>>> 1 - провтыкал, исправил. 2 и далее - 2 не стал трогать, т.к. не понимаю
  530.                что именно тут проверить. мы проверяем что таска закомпличена переходя
  531.                в active и проверяя что там пусто. то что далее исправил)
  532. /*
  533.    это описала выше
  534.    
  535.    тут повторюсь
  536.    такая проверка даст
  537.        проверим = на олле - таски видны с любым статусом
  538.        четче зафиксируем было-стало - какой список был до перехода на фильтр и после
  539.        
  540.        да, закомпличивание допроверится аж проверкой после перехода на фильтр, но предыдущие моменты - ценны
  541.        потомы стоит проверку сделать
  542. */                
  543. =========================================================================================
  544. 5. посмотрел видео Якова https://drive.google.com/file/d/0B8hgIBw8-V-AdGxxU1R3enl1RzQ/view?ts=567ab8d7
  545.    по поводу assertTasks and assertVisibleTasks, мой подход разве не лучше его альтернативы?
  546.    метод все еще один, и он ищет таски в зависимости от текущего фильтра свои
  547.  
  548.        public TaskPage goAll() {
  549.            $("#filters>li:nth-of-type(1)>a").click();
  550.            tasks = $$("#todo-list>li"); // все таски
  551.            return this;
  552.        }
  553.  
  554.        public TaskPage goActive() {
  555.            $("#filters>li:nth-of-type(2)>a").click();
  556.            tasks = $$("#todo-list>li.active"); // только активные
  557.            return this;
  558.        }
  559.  
  560.        public TaskPage goCompleted() {
  561.            $("#filters>li:nth-of-type(3)>a").click();
  562.            tasks = $$("#todo-list>li.completed"); // только закомпличенные
  563.            return this;
  564.        }
  565. /*
  566.    не, твой подход не лучше
  567.    выше писала почему
  568.    
  569.    пример
  570.    верно проставляются классы таскам, но при переходах на любой из фильтров - они видны
  571.    твои проверки - пройдут )
  572.    
  573.    ну и про то, почему не стоит делать свойства объекта мутабельными - почитай
  574.    это и правда стоит учитывать при проектировании
  575.    хорошая практика, сильно облегчающая жизнь
  576.    код проще, предсказуемее
  577.    его легче писать, легче менять, легче сопровождать
  578. */
  579. =========================================================================================
  580. 6. еще вопрос, можно ли это как то нормально сделать (тот метод что переменное число аргументов
  581.    принимает) ?
  582.  
  583.        public TaskPage shouldHaveCompleted(String taskName) {
  584.            tasks.findBy(text(taskName)).find(".toggle").shouldBe(selected);
  585.            return this;
  586.        }
  587.  
  588.        public TaskPage shouldHaveCompleted(String... taskNames) {
  589.            for (String taskName : taskNames) {
  590.                shouldHaveCompleted(taskName);
  591.            }
  592.            return this;
  593.        }
  594.        
  595. /*
  596.    Писала выше и про метод
  597.    и про то - где такая проверка была бы уместной
  598. */        
  599. =========================================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement