julia_v_iluhina

Untitled

Jan 22nd, 2017
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 22.76 KB | None | 0 0
  1. 1 Есть какое-то нарушение в логике теста
  2. Given по идее должен полностью заменить add но этого не происходит.
  3. https://bitbucket.org/wuppert/todomvc/src/bd2c3ca12f558bd7d5c108daad9374b5a443d54e/TodoMVCTestBackup/src/test/java/SmokeE2ETest/?at=master
  4.  
  5. Element not found {#todo-list>li.filter(exact text '2')}
  6. Expected: visible
  7. Screenshot: file:/E:/Projects2Git/TodoMVCTestBackup/build/reports/tests/1485024883010.1.png
  8.  
  9.  
  10. @Test
  11.     public void testTaskFlow() {
  12.  
  13.         given("1");
  14.         assertTasksAre("1");
  15.         toggleAll(); // complete all
  16.         assertTasksAre("1");
  17.  
  18.         filterActive();
  19.         assertNoVisibleTasks();
  20.         given("2");
  21.         /*
  22.            given - это не аналог и не заменитель для метода  add
  23.                given - полностью заменяет таски в списке, и делает это через работу с данными
  24.                add - добавляет таски, к уже существующим, причем делает это через UI (User Interface)
  25.  
  26.            применяй given - для создания НАЧАЛЬНОЙ ситуации в тесте
  27.            чтобы обеспечить = что должно быть в списке тасок на начало выполнения тестов
  28.  
  29.            а вот если речь идет о тесте собственно добавления таски - используй метод add
  30.  
  31.            в начале этого метода - можно пойти 2-мя путями
  32.                1й путь
  33.                given("1"); - не считаем - что в е2е на all покрыли добавление таски
  34.                первая тестируемая операция
  35.                и т д
  36.  
  37.                2й путь
  38.                given(); - обеспечили на начало теста пустой список тасок
  39.                add("1"); - а это уже тестируемая операция, тестируем добавление таски на all фильтре
  40.  
  41.                оба пути возможны
  42.                выбор повлияет на то, что и где мы покроем
  43.                и что нужно будет допокрывать фиче-тестами для реализации full coverage
  44.         */
  45. .....
  46. *****************************************************
  47.  
  48.     @Test
  49.     public void testDelete() {
  50.         given("1", "2");
  51.         assertTasksAre("1", "2");
  52.         assertItemsLeft(2);
  53.         /*
  54.             в целом - структура метода верная
  55.             в начале тест-метода - задали тестовую ситуацию используя гивен-метод
  56.  
  57.             далее - тестируемая операция и проверки после нее
  58.             причем - сначала - проверили более важное - списо тасок
  59.             и затем - уточнили - проверили менее важное  assertItemsLeft
  60.  
  61.             единственное замечание - не нужно проверок после вызова гивен-метода
  62.             мне кажется, это мы уже обсуждали ранее, на этапе выполнения Smoke + F
  63.             повторю текст про это
  64.         */
  65.         delete("2");
  66.         assertTasksAre("1");
  67.         assertItemsLeft(1);
  68.     }
  69. /*
  70.  
  71.     Это к общему сведению)
  72.  
  73.     Есть разные способы выполнять предварительные действия
  74.     Мы сейчас делаем это через действия на UI (User Interface)
  75.     А есть еще методы - работать непосредственно с данными (далее вы такое тоже попробуете)
  76.     Так вот через действия на UI - предварительные действия не быстрые и часто не достаточно надежные
  77.     А через непосредственную работу с данными - предварительные действия быстрые и надежные
  78.  
  79.     Если предварительные действия медленные или не надежные
  80.     То проверка в конце предварительных действий нужна
  81.  
  82.     А если мы уверены - что после предварительных действий гарантировано все ОК,
  83.     то и проверок не надо после предварительных действий
  84.  
  85.     Но, поскольку наше приложение - простое
  86.     Разумно не делать проверку в конце предварительных действий
  87.     чтобы наши тесты были эффективнее
  88.  
  89.     Тестировали бы что-то типа соцсети и если бы предварительные действия были
  90.     реализованы через UI - да, после предварительных действий было бы разумно
  91.     выполнить проверку (проверка после предварительных действий нам позволяет отличить -
  92.     ошибка возникла на этапе выполнения тестируемого действия, или все же раньше)
  93.  
  94.  
  95. */
  96. ******************************************************************************
  97.  
  98. 2. Во второй версии не ясно   выполнение в методе given -     given(tasks);
  99. Подразумевалась перегрузка методов ?
  100. Два метода с одинаковым названием принимающих разные аргументы ?.
  101.  
  102. /*
  103.     да, именно это подразумевалось, все верно
  104. */
  105.  
  106.  
  107.     @Step
  108.     public void given(String... tasks) {
  109.     /*
  110.         во втором варианте реализации, что я тебе привела в качестве примера -
  111.         такой метод оперировал параметром Tasks... tasks
  112.         это важно
  113.         т к позволяет создать несколько тасок - в разном состоянии
  114.  
  115.         например - активную a, закомпличеную b
  116.         в некоторых тест-методах это будет важно
  117.  
  118.         такая реализация - самая универсальная
  119.         именно в самом универсальном варианте - и стоит реализовать сам алгоритм
  120.         а далее - уже реализуем вариант given(TaskType taskType, String... taskTexts)
  121.         который как раз будет использовать наш универсальный вариант -  given(Tasks... tasks)
  122.  
  123.         такой подход - когда реализуешь алгоритм в самом универсальном варианте
  124.         и затем реализуешь методы с другим набором параметров - для других нужных вариантов вызова метода -
  125.         и в этих вариантах - переиспользуй первый универсальный вариант
  126.         так получишь DRY реализацию
  127.         один раз - реализовали алгоритм
  128.         и далее - реализовали набор методов, которые удобно вызывать в разных случаях
  129.  
  130.         given(new Task(ACTIVE, "a"), new Task(COMPLETED, "b")) - вариант для создания тасок в разных статусах
  131.  
  132.         given(new Task(ACTIVE, "a"), new Task(ACTIVE, "b")) - а для такого варианта - слишком длинно
  133.         given(ACTIVE, "a", "b")) - так то же самое получится лаконичнее и нагляднее
  134.  
  135.     */
  136. ***********************************************************************************
  137.  
  138. 3. И еще не ясно на каком этапе мы указываем состояние таски
  139. Сюда мы передаем (“ACTIVE”, “name”)
  140. public void given(TaskType taskType, String... taskTexts) {
  141. далее создаем масив размером [taskTexts.length]
  142. далее для каждой таски в массиве мы создаем новый объект с атрибутами тип и имя
  143. а далее мы вызывем пердыдущую весию given метода который принимает только имя таски потом передает
  144. в  prepareGivenCommand которій в свою очередь склеивает строку
  145.  
  146. такое впечатление что во второй версии given мы еще используем первую версию (без статуса таски).
  147. Может оно и DRY но что-то мне никак не KISS
  148. Может у тебя есть более доступная для понимания версия там где
  149.  given принимает два аргумена given(TaskType taskType, String... taskTexts)
  150. далее их передает в prepareGivenCommand (TaskType taskType, String... taskTexts) который потом уже возвращает  строку
  151.  
  152. /*
  153.     в коде тест-методов - очень важно быть KISS
  154.  
  155.     а вот в реализации вспомогательных методов - уже важнее быть DRY )
  156.     тут важно не реализовывать один и тот же алгоритм в нескольких вариантах
  157.  
  158.     подумай - как это поддерживать
  159.     представь - реализовали 2-3 варианта одного алгоритма
  160.     и надо переделать что-то
  161.  
  162.     это что-то - придется переделать трижды
  163.     а это - уже источник проблем - в одном месте исправили, в другом - нет
  164.     ну или - в одном месте исправили правильно, в другом - не правильно
  165.  
  166.     так что советую - остаться именно в DRY реализации
  167.     это критично, и это я требую в задании
  168.  
  169.     по поводу примера - я такого примера не буду давать
  170.     думаю, примеров уже достаточно
  171.     тем более, что не нужно двух реализаций одного алгоритма в двух методах prepareGivenCommand
  172.     с разным набором параметров
  173.  
  174.     я напишу это - немного на будущее
  175.            лично для себя я держу такую грань
  176.             то что юзаю в тест-методах - должно быть более KISS
  177.             а вот сама реализация пейджей/виджетов/хелперов/кондишенов - тут уже просто правила разработки ПО применяю
  178.             DRY - тут уже важно )
  179.             т е - снаружи все эти  пейджи/виджеты/хелперы/кондишены = то что видно при использовании этого всего
  180.             должно конечно обеспечивать KISS
  181.             а вот внутри - там где мы алгоритмы реализуем, какую-то сравнительно серьезную логику - там уже значимость DRY - гораздо выше
  182.     если это пока не очень понятно - то скоро станет понятнее)
  183. */
  184. ************************
  185. 4. Не понял зачем нам два метода
  186. Если мы передаем состояние и имя то нам нужен 2й..а зачем 1й?
  187.  
  188.     @Step
  189.     public void givenAtActive(Task... tasks) {
  190.         given(tasks);
  191.         filterActive();
  192.     }
  193.  
  194.     @Step
  195.     public void givenAtActive(TaskType taskType, String... taskTexts) {
  196.         given(taskType, taskTexts);
  197.         filterActive();
  198.     }
  199. /*
  200.     я выше написала про это
  201.             given(new Task(ACTIVE, "a"), new Task(ACTIVE, "b")) - а для такого варианта - слишком длинно
  202.             given(ACTIVE, "a", "b")) - так то же самое получится лаконичнее и нагляднее
  203.  
  204.     для варианта, когда нужно создать несколько тасок в одном статусе - гораздо нагляднее будет вызов метода
  205.     givenAtActive(TaskType taskType, String... taskTexts)
  206.  
  207.     ну и - почему мы создаем для каждого фильтра гивены
  208.     чтоб в тест-методах - предварительные действия делались - одним вызовом нужного гивен-метода
  209.     чтоб не раздувать сами тест-методы
  210.     максимально KISS тест-методы реализовать
  211. */
  212. ************************************************************************************
  213.  
  214. 5. Не понял зачем нам этот класс?
  215.  
  216.   public class Task {
  217.         String taskText;
  218.         TaskType taskType;
  219.  
  220.         public Task(TaskType taskType, String taskText) {
  221.             this.taskText = taskText;
  222.             this.taskType = taskType;
  223.         }
  224.     }
  225. Чего мы тут добиваемся и почему нельзя просто создать две переменные
  226.         String taskText;
  227.         TaskType taskType;
  228. Т.е вроде понятно что класс делает-хотя он вроде ничего и не делает..но с какой целью?
  229. Тут если можно как для дебилов ибо все равно не понял
  230. /*
  231.     а как ты передашь в метод - несколько сущностей
  232.     у каждой из которых будет 2 свойства - и тип таски и текст таски
  233.  
  234.     я другого метода не знаю
  235.     найдешь - покажи)
  236.  
  237.     этот класс - нужен лишь для того - чтоб мы могли оперировать несколькими такими сущностями
  238.     для реализации метода - given(Task... tasks)
  239.  
  240.     чтоб можно было вот так работать
  241.     given(new Task(ACTIVE, "a"), new Task(COMPLETED, "b"))
  242.  
  243.     получим - список тасок
  244.     с несколькими тасками
  245.     причем - у разных тасок модет быть разный тип - активный или закомпличеный
  246. */
  247. ***************************************************************************
  248. Раньше мы делали метод, в него передавали 2 аргумента(считай свойства), далее их использовали в методе.
  249. А тут как-то все пошло не так..
  250. /*
  251.     боролись за новые возможности
  252.     мы их получили благодаря этому
  253.  
  254.     и это - нам нужно
  255.  
  256.     например
  257.     чтоб проверить переход с фильтра на фильтр
  258.     правильно - создать несколько тасок
  259.     в разных состояниях - одну активную, вторую - закомпличеную
  260.  
  261.     для того - чтоб фильтеринг был проверен максимально точно проверен
  262.     мы так одним махом проверим
  263.     как влияет переход на такой-то фильтр - и на активные таски, и на закомпличеные таски
  264. */
  265. *****************************************************************************************
  266.  
  267. 6
  268. по 3 вопросу
  269. надо тебе почитать на такую тему - java array initialization
  270. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
  271. http://javadevnotes.com/java-initialize-array-examples
  272. https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html#jls-10.6
  273. http://stackoverflow.com/questions/1938101/how-to-initialize-an-array-in-java
  274.  
  275. @Step
  276.     public void given(TaskType taskType, String... taskTexts) {
  277.         Task[] tasks = new Task[taskTexts.length];
  278.     Подскажи, зачем мы тут указываем length (откуда эта length вообще берется?
  279.     Это метод java доступный для любого текста?)а не просто
  280. Task[] tasks = new Task[taskTexts] –так было бы понятно
  281. Task[] tasks = new Task[taskTexts.length]; - так нет
  282. /*
  283.     при инициализации массива - нам нужно передать в качестве параметра - количество элементов этого массива
  284.     количество элементов должно быть = количеству переданных строк в качестве значения параметра - String... taskTexts
  285.  
  286.     http://www.java-tips.org/java-se-tips-100019/24-java-lang/481-using-the-varargs-language-feature.html
  287.     At compile time a vararg is converted to an array.
  288.  
  289.     что это значит - At compile time a vararg is converted to an array.
  290.     это значит - что с параметром taskTexts мы можем работать как с массивом
  291.     taskTexts.length = количество элементов массива
  292.  
  293.     почитай про массивы в Java
  294. */
  295. Я ссылки прочитал.. и там в целом как в javarush описывается как поместить значение в массив.
  296. Т.е. будь там число описывающее размер массива- не было бы вопросов..ни или набор текстов
  297. (int[] testArray = new int[10];
  298. Это понятно
  299.    int[] testArray1 = {1, 2, 3, 4, 5};
  300. и это понятно
  301. /*
  302.     мы как раз что-то аналогичное int[] testArray = new int[10] сделали
  303.     инициализировали массив такого-то размера
  304. */
  305. Если taskTexts.length это переменная ( а судя по всему так и есть)- то почему она нигде не определена?
  306. Т.е еще раз вопрос откуда берется именно length ?
  307. /*
  308.     гугли array java
  309.     вот например доходчиво описано
  310.     http://developer.alexanderklimov.ru/android/java/array.php
  311. */
  312. **********************************************************************************************************
  313. 7   Тут https://tasj.slack.com/files/julia.v.iluhina/F3RS60NR3/-.txt
  314. начиная с 38й строки это новая реализация в ней все нужно ничего лишнего?
  315. /*
  316.     да, это вариант окончательной реализации гивен-методов
  317.     точнее, почти окончательной)
  318.  
  319.     далее - еще одно в них встроим
  320.     но это позже
  321.  
  322.     можешь использовать в своем решении - такой вариант реализации
  323.     я далее напишу - что еще тут чуть поменяем
  324.     буквально - 1-3 строки в одном методе
  325.  
  326.     а так - да, тут уже все ок
  327.  
  328.     конечно, есть и другие варианты
  329.     но они сложнее в реализации
  330.     это = нормальный не сложный окончательный вариант гивен-методов
  331.  
  332.      можно чуть оптимизировать количество гивен-методов
  333.      это уже такая, оптимизационная работа
  334.      делать ее или нет - решать тебе
  335. */
  336. /*
  337.      Тут приведу тебе рекомендации Якова для другого студента - про набор методов given
  338.  
  339.         ***
  340.             но я вот подумал бы об этих методах givenAtAll дополнительных...
  341.  
  342.             я бы наверное оставил
  343.  
  344.             given(Tasks...)
  345.             given(String...)
  346.             given()                 // вот этот может стоит таки переименовать в givenAtAll
  347.                                     // потому как без префикса звучит не однозначно
  348.             givenAtActive(Tasks...)
  349.             givenAtActive(String...)
  350.             givenAtActive()
  351.             givenAtCompleted(Tasks...)
  352.  
  353.             это был бы самый экономный вариант по количеству методов...
  354.             и все еще достаточно гибкий и при этом понятный...
  355. */
  356. /*
  357.             Лично мне нравится набор вот такой
  358.  
  359.             given(Tasks...)
  360.             givenAtActive(Tasks...)
  361.             givenAtCompleted(Tasks...)
  362.  
  363.             givenAtAll(Status status, String... texts)
  364.             givenAtActive(Status status, String... texts)
  365.             givenAtCompleted(Status status, String... texts)
  366.  
  367.             мне кажется - так универсальнее, и однозначнее
  368.             для каждого фильтра - по 2 метода
  369.             параметры методов для каждого фильтра - одинаковы = меньше думать/помнить + больше вариантов
  370.  
  371.             вызвать в варианте given() - можно метод given(Tasks...)
  372.             так что - все описанные варианты покрываются
  373.  
  374.             а вариант Якова - позволит лаконичнее код писать
  375.  
  376.             выбери, какие идеи тебе ближе
  377.  
  378.   */
Advertisement
Add Comment
Please, Sign In to add comment