julia_v_iluhina

Untitled

Dec 27th, 2016
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.23 KB | None | 0 0
  1. public class TodoMVCTest extends OpenPageAndClearDataBeforeEachTest {
  2.     TodoMVCPage tasks = new TodoMVCPage();
  3.     Preconditions given = new Preconditions();
  4. /*
  5.     класс Preconditions - ты используешь как пейдж, в общем-то
  6.     и его можно рассматривать пейдж - как объект-контейнер вспомогательных для тестов методов
  7.  
  8.     предлагаю класс Preconditions - переименовать в PreconditionsPage
  9.     и переместить в тот же пекедж, где пейдж
  10.  
  11.     или  - пусть это будет класс-хелпер
  12.     размести его так -  src / main / java / helpers
  13.  
  14.     но - точно - с предками тест-класса - ему не место
  15. */
  16. ********************************
  17. public class Preconditions {
  18.  
  19.     public void givenAllActive(String... taskTexts){
  20.  
  21.         String commandToRun = "";
  22.  
  23.         for (String element : taskTexts){
  24.         /*
  25.             element - не самое удачное имя для текста таски
  26.         */
  27.             ...
  28.             if (taskTexts.length > 1) {
  29.                 ...
  30.             }
  31.             /*
  32.                 тут мы запятую добавляем, если ....
  33.             */
  34.         }
  35.  
  36.         if (taskTexts.length > 1)
  37.         {
  38.             ....
  39.         }
  40.         /*
  41.             и тут мы все равно обрезаем, если ....
  42.  
  43.             раз мы тут обрезаем лишнюю запятую, то может - изменив условие тут - можно избежать if-а
  44.             внутри цикла?
  45.  
  46.             можно так улучшить
  47.  
  48.             а можно и вот так
  49.             Реализация красивее может стать за счет использования String.join(",", ...)
  50.  
  51.                 Есть об этов в прошлом ревью
  52.  
  53.                 если вместо StringBuilder jsContent
  54.                 создать List<String> jsContent
  55.                 и в цикле собирать в этот список строки {...}
  56.                 то внутри цикла - можно будет вообще не заботиться о добавлении запятой
  57.                 а уже когда строку собираешь - сможешь применить String.join(",", jsContent)
  58.                 такая операция даст строку, в которой все ее элементы будут идти через запятую
  59.                 так код станет еще лаконичнее
  60.  
  61.                 Настаивать на этих изменениях не буду, советую попробовать)
  62.                 https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
  63.                 http://joxi.ru/V2VBQLqf0ZW692 - фактически, вызываем второй из этих методов
  64.                 (переменную типа List<String> тут можно передать в качестве второго параметра)
  65.  
  66.                 https://habrahabr.ru/post/260767/
  67.                 http://javarevisited.blogspot.com/2016/06/10-examples-of-joining-string-in-java-8.html
  68.  
  69.         */
  70. ******************************************
  71.  
  72.     public void givenAllCompleted(String... taskTexts){
  73. /*
  74.     обрати внимание - этот метод в своей реализации - очень похож на предыдущий
  75.  
  76.     нету смысла реализовывать несколько методов, которые реализуют один и тот же алгоритм
  77.     это не DRY
  78.     в случае, когда мы говорим про реализацию какой-то уже не самой эелементарной логики (циклы, ветвления, ...)
  79.     то грамотнее - реализовать ОДИН метод
  80.     и его испоьзовать
  81.  
  82.     можно идти постепенно к цели
  83.     в зависимости от того, насколько сложна эта задача для тебя
  84.  
  85.     если сложно
  86.         первый шаг - реализовать метод given(boolean isCompleted, String... taskTexts)
  87.         который сможет делать то, что уже делают твои методы
  88.  
  89.         конечно, параметр boolean isCompleted - не очень наглядно
  90.         удобнее использовать метод с параметром типа enum - т к вызов метода - будет нагляднее
  91.         т е  - второй шаг - given(TaskType taskType, String... taskTexts)
  92.         где - TaskType - это enum с 2-мя значениями - ACTIVE, COMPLETED
  93.         (ниже - будет подробнее)
  94.  
  95.         следующий момент)
  96.             не всегда нам подходит вариант - когда мы работаем с тасками в одинаковом статусе
  97.             иногда нам будет нужно - чтобы таски в списке - были в разных статусах
  98.             т е - с одной стороны - нам нужно добавить несколько тасок
  99.             с другой стороны - для каждой таски нужно задать и текст, и статус
  100.             это можно сделать - реализовав класс Task - который будет описывать таску
  101.             и  - реализовываем следующий вариант - given(Task... tasks)
  102.             и вызов метода может быть таким
  103.                  given(new Task(COMPLETED, "a"), new Task(ACTIVE, "b"))
  104.                  чтобы получить вот такую картину
  105.                  закомпличеная таска a, и активная - b
  106.  
  107.                  полезные линки
  108.  
  109.                      классы
  110.                      http://www.tutorialspoint.com/java/java_object_classes.htm
  111.                      http://www.helloworld.ru/texts/comp/lang/java/java/07.htm
  112.  
  113.                      внутренние классы (нас интересуют member inner classes)
  114.                      http://www.tutorialspoint.com/java/java_innerclasses.htm
  115.                      http://www.quizful.net/post/inner-classes-java
  116.                      http://www.javatpoint.com/java-inner-class
  117.     если не сложно
  118.         то сразу реализуй given(Task... tasks)
  119. */
  120. ******************************
  121.    есть еще вопрос - какой тип использовать для типа таски (статуса таски)
  122.  
  123.     варианты на поверхности - boolean или String
  124.     оба варианта имеют недостатки
  125.  
  126.     boolean
  127.         new Task(true, "a") - это я какую таску создала?
  128.  
  129.     String
  130.         я могу вызвать метод, передав в качестве второго параметра любую строку
  131.         new Task("green", "a")
  132.  
  133.         эта ошибка проявится уже только в момент запуска тестов, а на этапе компиляции - мы не получим никаких сообщений -
  134.         что что-то не так с вызовом метода
  135.  
  136.     вот для таких случаев очень хорошо подойдет использование enum
  137.     если параметр taskStatus у нас будет типа enum TaskStatus,
  138.     то мы только значение этого enum и сможем передать в качестве параметра
  139.     по-другому - будут выданы сообщения об ошибке - еще на этапе разработки кода
  140.  
  141.     потому - лучший вариант для для типа таски (статуса таски) - использовать тип enum
  142.  
  143.     Кстати, для любого значения из enum -  можно получать соотвествующую ему строку
  144.  
  145.     у нас задача - для каждого значения enum вернуть свою строку
  146.     enum - это тоже класс
  147.     у которого может быть и конструктор, и поля
  148.     например
  149. */
  150.  
  151. public enum Day {
  152.         MONDAY("понедельник"),
  153.         TUESDAY("вторник"),
  154.         WEDNESDAY("среда"),
  155.         THURSDAY("четверг"),//<<----------------------для каждого значения enum - вызов конструктора, фактически значение = объект класса
  156.         FRIDAY("пятница"),
  157.         SATURDAY("суббота"),
  158.         SUNDAY("воскресенье");
  159.  
  160.         String description;//<<---------------------------поле для хранения описания дня недели
  161.  
  162.         public Day(String description) {
  163.                 this.description = description;//<<---------------------------логика конструктора - запомнить для объекта его описание
  164.         }
  165.  
  166.         @Override
  167.         public String toString() {
  168.             return description;//<<---------------------------логика - вывести для объекта - то что для него заполнили
  169.         }
  170. }
  171.  
  172. /*
  173.  
  174.     все классы - потомки класса Object (enum - это тоже класс)
  175.     у Object есть метод toString()
  176.     который выполняет преобразование объекта к строке
  177.     реализовав такой метод в рамках класса SomeClass -
  178.     используя выражения типа "day is "+ Day.MONDAY
  179.     получишь строку "day is понедельник"
  180.  
  181.     toString() - можно грамотно использовать в рамках всех вспомогательных классов и enum-ов
  182.     это позволит упростить код
  183.  
  184.     конструкторы в enum-ах как раз и могут помочь решению задачи
  185.     для каждого значения enum вернуть свою строку
  186.  
  187.     попробуй применить эти подходы
  188.  
  189.     вот хороший пример
  190.     http://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html
  191. */
  192. **********************************************
  193. /*
  194.     и далее - оставим реализованный алгоритм в самом универсально реализованном методе
  195.     фактически - все остальные методы - были нужны чтоб разобраться и реализовать
  196.     given(Task... tasks)
  197.  
  198.     а дальше - начнем реализовывать другие гивен-методы
  199.     которые внутри себя - будут вызывать наш given(Task... tasks)
  200.     и просто обеспечат - возможность наиболее наглядного и удобного вызова
  201. */
  202.  
  203.     мы реализуем полное покрытие
  204.     и нам надо уметь в предварительных действиях - реализовывать следующие вещи (мо минимуму, самое необходимое)
  205.     - на all
  206.         - добавить таски с разными статусами
  207.         - добавить таски с одним каким-то статусом
  208.     - на active
  209.         - добавить таски с разными статусами
  210.         - добавить таски с active статусом
  211.     - на completed
  212.         - добавить таски с разными статусами
  213.         - добавить таски с completed статусом
  214. */
  215. /*
  216.      Тут приведу тебе рекомендации Якова для другого студента - про набор методов given
  217.  
  218.         ***
  219.             но я вот подумал бы об этих методах givenAtAll дополнительных...
  220.  
  221.             я бы наверное оставил
  222.  
  223.             given(Tasks...)
  224.             given(String...)
  225.             given()                 // вот этот может стоит таки переименовать в givenAtAll
  226.                                     // потому как без префикса звучит не однозначно
  227.             givenAtActive(Tasks...)
  228.             givenAtActive(String...)
  229.             givenAtActive()
  230.             givenAtCompleted(Tasks...)
  231.  
  232.             это был бы самый экономный вариант по количеству методов... и все еще достаточно гибкий и при этом понятный...
  233. */
  234. /*
  235.             Лично мне нравится набор вот такой
  236.  
  237.             given(Tasks...)
  238.             givenAtActive(Tasks...)
  239.             givenAtCompleted(Tasks...)
  240.  
  241.             givenAtAll(Status status, String... texts)
  242.             givenAtActive(Status status, String... texts)
  243.             givenAtCompleted(Status status, String... texts)
  244.  
  245.             мне кажется - так универсальнее, и однозначнее
  246.             для каждого фильтра - по 2 метода
  247.             параметры методов для каждого фильтра - одинаковы = меньше думать/помнить + больше вариантов
  248.  
  249.             вызвать в варианте given() - можно метод given(Tasks...)
  250.             так что - все описанные варианты покрываются
  251.  
  252.             а вариант Якова - позволит лаконичнее код писать
  253.  
  254.             выбери, какие идеи тебе ближе
  255.  
  256.   */
  257. /*
  258.     как переиспользовать внутри метода given(TaskType taskType, String... taskTexts)
  259.     уже реализованный метод given(Task... tasks)
  260.  
  261.     задача - тебе внутри given(TaskType taskType, String... taskTexts)
  262.     надо сделать то же что ты делал в given(Task... tasks)
  263.     просто - не ясно
  264.     как из параметров (TaskType taskType, String... taskTexts)
  265.     получить (Task... tasks)
  266.      вот решим эту задачу - сможешь внутри
  267.     given....(TaskType taskType, String... taskTexts)
  268.  
  269.     написать код в одну строчку
  270.     given(xxx(taskType, taskTexts))
  271.  
  272.     в given(Task...tasks) в качестве параметра можно передавать массив Task[] tasks
  273.     погугли про varargs in java
  274.  
  275.     реализуй метод xxx
  276.     возвращающий Task[]
  277.     с параметрами (TaskType taskType, String... taskTexts)
  278.  
  279.     в котором
  280.     объяви переменную типа Task[] и инициализируй ее как массив Task[....такого-то размера....]
  281.     какого - посмотри на параметры нашего метода
  282.  
  283.     в цикле обойди taskTexts
  284.     и каждый элемент массива заполни с помощью метода aTask
  285.  
  286.     верни полученный массив
  287.  
  288.     а далее - используй этот метод
  289.     внутри given...(TaskType taskType, String... taskTexts)
  290.  
  291.         given(xxx(taskType, taskTexts))
  292.  
  293.     Если тяжело сразу  xxx реализовать -
  294.     то для начала просто внутри givenAt....
  295.     реализуй этот код - собери массив Task[] по переданным параметрам
  296.  
  297.     И тогда будет что-то типа такого
  298.           Task[] tasks = ....
  299.           ....
  300.           ....
  301.           ....
  302.           given(tasks)
  303. */
  304. ******************************************
  305. /*
  306.     дальше - дореализуй полное покрытие
  307.     смотри на свой тест-план
  308.     реализуй фиче-тесты
  309.  
  310.     если хочешь (это не обязательно)
  311.     оптимизируй его
  312.  
  313.     в чем оптимизация
  314.     - что покрыто в е2е - не покрываем фиче-тестами
  315.     - низкоприоритетное - покрываем единожды, на каком-то из контекстов (пример - delete by emptying text)
  316.     - низкоприоритетные варианты фичи, у которой есть покрытые варианты - не покрываем (пример - reopen all & add)
  317. */
  318. *************************
  319. //можно остановиться раньше - если будет сложно
Advertisement
Add Comment
Please, Sign In to add comment