julia_v_iluhina

Untitled

Nov 23rd, 2016
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 16.10 KB | None | 0 0
  1. http://joxi.ru/Vrwqg81HKB4ZN2
  2.  
  3. /*
  4.     это по пути
  5.  
  6.     пока пекеджи не особенно четко говорят - где какая работа
  7.  
  8.     эта работа - это уже не вторая версия feature тестов
  9.     а новая - full coverage
  10.  
  11.     ну и ниже - по пекеджаи и имени тест-класса сложно понять что это за работа
  12.  
  13.     пройдет еще немного времени - и тебе будет сяжело сориентироваться
  14.  
  15.  
  16.     разложи решения разных добашек по пекеджам так, чтоб на одном уровне вложенности были пекеджи = значения одной категории
  17.     типа такого
  18.     homeworks
  19.         hw1
  20.             v1
  21.             v2
  22.         hw2
  23.             v1
  24.             v2
  25.             ...
  26.         ...
  27. */
  28. ****************************
  29.     @Before
  30.     public void openPage() {
  31.         if (!($("#new-todo").is(visible))) {
  32.             open("https://todomvc4tasj.herokuapp.com/");
  33.         } else {
  34.             refresh();
  35.         }
  36.     }
  37.  
  38.     дуже довго чекає запуску сторінки (більше хвилини)
  39. /*
  40.     Я такое смогла увидеть на твоем коде - когда опрерировала версией Selenide 3.6
  41.  
  42.     ФФ использую - 47,0,1
  43.  
  44.     Я вот после перехода на Selenide 3.11 - таких проблем не стало
  45.  
  46.  
  47.     мы в самом начале - еще до открытия страницы в первый раз - обращаемся к элементу на странице - когда, фактически еще вебдрайвер не открыт
  48.     и браузер не запущен. Я так понимаю - происходили какие-то тормоза на стыке версий вебдрайвера и Selenide
  49.  
  50.     мне ближе вариант проверки урла
  51.     если урл не равен ....
  52.     то тогда открыть
  53.     такой способ дает секунд 15 выигрыша - на таких тест-методах и моей машинке)
  54.  
  55.     url() - возвращает урл текущей открытой страницы
  56.  
  57.     refresh(); - нам тут еще рано делать
  58.     он нужен только после работы с локалсториджем
  59.     кстати, скорее всего, проблема уйдет вот эта = тести з методом add не проходять, лишається назва таски в полі #new-todo
  60.     про это отдельно напишу
  61.     но уже после таких исправлений в файрфоксе может перестать проявляться эта ошибка
  62.  
  63.     и еще - если вызывать гивен-метод в каждом из тест-методов
  64.     то нам не нужен @Before -метод
  65.     можно этот if - перенести внутрь гивена
  66.  
  67.     а раз мы на начало любого тест-матода - зададим состояние локалсториджа
  68.     так нам его и чистить не нужно
  69.     так уйдет и @After-метод
  70.     и один из предков тест-класса)
  71.  
  72.     заодно и иерархию упростим
  73. */
  74. *********************
  75. тести з методом add не проходять, лишається назва таски в полі #new-todo
  76. /*
  77.     тут "ноги растут" из проблем самого приложения нашего
  78.  
  79.     элементы страницы загружаются (при открытии или рефреше)
  80.     и становятся доступными для работы с ними
  81.  
  82.     но - есть момент - когда элементы уже доступны, а джаваскрипты некоторых элементов еще не догрузились
  83.     в результате - если мы успеваем выполнить ввод значения + энтер для создания новой таски - в этот маленький период
  84.     то как раз и можно было наблюдать такую ошибку
  85.  
  86.     в хроме - который чуть побыстрее - такая ошибка проявляется чаще)
  87.  
  88.     теперь про что делать)
  89.  
  90.     начнем с того - что если в твоей текущей версии все ок(уже с изменениями, описанными выше)
  91.     то и ок)
  92.  
  93.     проверку, что Яков рекомендовал -  $("#new-todo").shouldBe(enabled)
  94.     ты как раз встроила
  95.  
  96.     но для нашего приложения, увы, и этого может быть недостаточно
  97.  
  98.     хотя - в такой версии, что ты реализовала - должно быть достаточно)
  99.     если убрать лишний рефреш)
  100.  
  101.     если все же недостаточно)
  102.     то в конце гивен-метода - я бы встроила проверку - размер списка тасок соответствует количеству переданных в гивен тасок
  103.     на сегодня это помогало железно)))
  104.  
  105.     на реальном проекте - правильее было бы попросить девелоперов - дать на что опереться
  106.     например - чтоб поля не были доступны раньше времени
  107.  
  108.     иначе - придется встраивать вот такие костыли - обеспечивать на уровне гивена - вот этого ожидания - что страница уже ок работает
  109.     у нас есть только косвенные способы в данном случае
  110.  
  111. */
  112. **********************************
  113. 2. @Test
  114.     public void testCompleteOnAll() {
  115.  
  116.         given("1");
  117.  
  118.         //complete
  119.         toggle("1");
  120.         assertTasksAre("1");
  121.         assertItemsLeft(0);
  122.     }
  123.  
  124.     чи можна це вважати достньою перевіркою?
  125. /*
  126.     когда будут тесты и лля переходов с фильтра на фильтр
  127.  
  128.     в варианте
  129.     дано = активные и закоимличеные таски на таком-то фильтре
  130.  
  131.     делаем = переход на такой-то фильтр
  132.  
  133.     проверяем список тасок и итемс лефт
  134.  
  135.     то да - достаточно
  136.     т к если в комплексе на все тесты смотреть - то достаточно
  137.  
  138. */
  139. ******************************
  140.  given(aTask("1", State.COMPLETED), aTask("2", State.COMPLETED));
  141.  filterCompleted();
  142. /*
  143.     насчет COMPLETED вместо State.COMPLETED
  144.     то просто используй import static для State.COMPLETED и State.ACTIVE
  145.     и все)
  146.  
  147.     думаю, на третий вопрос твой я тоже ответила
  148.  
  149.     поскольку тестов много
  150.     то лучше на уровне тест-методов чуть полаконичнее быть
  151.  
  152.     не
  153.     given(aTask("1", State.COMPLETED), aTask("2", State.COMPLETED));
  154.     filterCompleted();
  155.     а
  156.     givenAtCompleted(aTask("1", State.COMPLETED), aTask("2", State.COMPLETED));
  157.  
  158.     т е - добавить реализаций гивен-методов - для работы с разными фильтрами
  159.     фактически - в них - будет
  160.         вызов гивен-метода, в котором алгоритм реализован
  161.         и далее - переход на нужный фильтр
  162. */
  163. ***********************************
  164. private void given(Task... tasks) {
  165. private void given(String... taskTexts) {
  166. /*
  167.     реализовывать 2 очень похожих алгорима - очень вредно)
  168.  
  169.     это не DRY
  170.  
  171.     и это в поддержке - всегда ведет к проблемам и потерям - соответственно
  172.  
  173.     пример - в одном алгоритме что-то подправили
  174.     а в другом  - нет
  175.  
  176.     самый универсальный у нас - given(Task... tasks)
  177.     вот пусть в нум и будет алгоритм
  178.  
  179.     а удобный given(String... taskTexts) - реализовать, переиспользовав внутри него given(Task... tasks)
  180.     я бы даже реализовывала вот так given(State state, String... taskTexts) - чтобы уж совсем разные варианты были
  181.  
  182.     чтоб так делать - надо уметь из State state, String... taskTexts
  183.     получить Task... tasks
  184.  
  185.     привожу кусок, написанный другому студенту - термины от твоих отличаются
  186.  
  187.      задача - тебе внутри given(TaskType taskType, String... taskTexts)
  188.         надо сделать то же что ты делал в given(Task... tasks)
  189.         просто - не ясно
  190.         как из параметров (TaskType taskType, String... taskTexts)
  191.         получить (Task... tasks)
  192.          вот решим эту задачу - сможешь внутри
  193.         given....(TaskType taskType, String... taskTexts)
  194.  
  195.         написать код в одну строчку
  196.         given(xxx(taskType, taskTexts))
  197.  
  198.         в given(Task...tasks) в качестве параметра можно передавать массив Task[] tasks
  199.         погугли про varargs in java
  200.  
  201.         реализуй метод xxx
  202.         возвращающий Task[]
  203.         с параметрами (TaskType taskType, String... taskTexts)
  204.  
  205.         в котором
  206.         объяви переменную типа Task[] и инициализируй ее как массив Task[....такого-то размера....]
  207.         какого - посмотри на параметры нашего метода
  208.  
  209.         в цикле обойди taskTexts
  210.         и каждый элемент массива заполни с помощью метода aTask
  211.  
  212.         верни полученный массив
  213.  
  214.         а далее - используй этот метод
  215.         внутри given...(TaskType taskType, String... taskTexts)
  216.  
  217.             given(xxx(taskType, taskTexts))
  218.  
  219.         Если тяжело сразу  xxx реализовать -
  220.         то для начала просто внутри givenAt....
  221.         реализуй этот код - собери массив Task[] по переданным параметрам
  222.  
  223.         И тогда будет что-то типа такого
  224.               Task[] tasks = ....
  225.               ....
  226.               ....
  227.               ....
  228.               given(tasks)
  229.  
  230. */
  231. ****************************
  232.  
  233. http://joxi.ru/EA4k7zEUDdvKE2
  234.  
  235. /*
  236.     код внутри гивен-метода - можно упростить
  237.  
  238.     давай посмотрим на собираемую строку
  239.     http://joxi.ru/Q2KpJYOs9zy0zA
  240.     вот эти кусочки - {....}
  241.     это как раз описание таски
  242.     и логично это делать единожды
  243.     я бы даже это поручила самому классу Task )
  244.  
  245.     если реализовать toString() в классе Task
  246.     то "some text" + task = даст нам строку "some text" - продолженную тем, что возвращает toString() класса Task)
  247.     все классы  - это потомки Object, у которого реализован toString()
  248.     этот метод отвечает за преобразование объекта к строке, и это часто можно использовать очень эффективно
  249.  
  250.     на этом не настаиваю - но однозачно - собирать подстроку про одну таску - надо лишь единожды
  251.  
  252.     так логика упростится
  253.  
  254.     насчет запятой между {....}
  255.  
  256.     можно не добавлять последнюю
  257.     можно отрезать последнюю
  258.     есть и другие методы)
  259.  
  260.     мне нравится - с использованием String.join(...)
  261.  
  262.     Given - String.join()
  263.     Нравится реализация метода)
  264.  
  265.         Красивее может стать только за счет использования String.join(",", ...)
  266.  
  267.         Есть об этов в прошлом ревью
  268.  
  269.         если вместо StringBuilder jsContent
  270.         создать List<String> jsContent
  271.         и в цикле собирать в этот список тесты объектов task
  272.         то внутри цикла - можно будет вообще не заботиться о добавлении запятой
  273.         а уже когда строку собираешь - сможешь применить String.join(",", jsContent)
  274.         такая операция даст строку, в которой все ее элементы будут идти через запятую
  275.         так код станет еще лаконичнее
  276.  
  277.         Настаивать на этих изменениях не буду, советую попробовать)
  278.         https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
  279.         http://joxi.ru/V2VBQLqf0ZW692 - фактически, вызываем второй из этих методов
  280.         (переменную типа List<String> тут можно передать в качестве второго параметра)
  281.  
  282.         https://habrahabr.ru/post/260767/
  283.         http://javarevisited.blogspot.com/2016/06/10-examples-of-joining-string-in-java-8.html
  284.  
  285.      важно - гивен-метод должен ок работать и при вызове given()
  286.      в результате такого вызова - должен быть пустой список тасок
  287. */
  288. *****************************************
  289. /*
  290.     В этом задании - оставь и е2е тест
  291.     и дополни его фиче-тестами
  292.  
  293.     оптимизировать покрытие не обязательно
  294.     но можно
  295.  
  296.     Optimized full coverage
  297.     в чем оптимизация
  298.         - что покрыто в е2е - не покрываем фиче-тестами
  299.         - низкоприоритетное - покрываем единожды, на каком-то из контекстов (пример - delete by emptying text)
  300.         - низкоприоритетные варианты фичи, у которой есть покрытые варианты - не покрываем (пример - reopen all & add)
  301.  
  302.     В следующий раз - приведи и тест-план и код
  303.  
  304.     Чтоб я могла понять твои идеи - что покрыто, что нет
  305.     Если оптимизировать не будешь - то можешь тест-план и не приводить
  306.  
  307.     Еще разнообразь тестовые ситуации для тестов похожего/одной и той же фичи, например
  308.         работаем с единственной таской
  309.         работаем с второй таской
  310.         работаем с единственной видимой таской
  311.  
  312.  
  313. */
  314. ****************************
  315. private enum State
  316. /*
  317.     Я бы это enum назвала TaskState все же
  318. */
Advertisement
Add Comment
Please, Sign In to add comment