Advertisement
julia_v_iluhina

Untitled

Jan 7th, 2017
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.54 KB | None | 0 0
  1. /*
  2.     тут - объединим несколько заданий в одно
  3.     нет смысла в твоем случае делать их последовательно
  4. */
  5.  
  6. Reporting
  7.  
  8. как встроить алюр-репорт -
  9. https://drive.google.com/file/d/0B8hgIBw8-V-AVnVCNlpUd1hZaXM/view?usp=sharing
  10.  
  11. в faq - есть раздер по репортингу
  12. https://docs.google.com/document/d/13dNyFGbI7mV22UUhH8E0LJ7SzabAmX7Bw7VCHScYfiU/edit?usp=sharing
  13.  
  14. первая цель - встроить в проект - формирование алюр-репорта
  15. причем - такого, в котором форминуются скриншоты для каждого тест-метода
  16. это - сделай и продолжай двигаться дальше
  17.  
  18. это - делать не надо
  19. но - полюбопытствовать можешь )
  20. https://www.youtube.com/watch?v=w_rPX9TwDkA
  21. http://spirogov.github.io/video-recorder-intieghratsiia-s-jenkins-i-allure-rieportami/
  22. ************************************************
  23.  
  24. OOP: Intro
  25. https://docs.google.com/document/d/1QudwvJewDg9qwg59Yso5aQ4w3CdcPqlsa8Az11B8Y5M/edit
  26. Reusing Tests Setup
  27. https://drive.google.com/file/d/0B8hgIBw8-V-AMVNGRVh1ZTlyaG8/view?usp=sharing
  28.  
  29. cмотри эти видео
  30. возможно, какие-то мелочи и/или тонкости подметишь для себя
  31. в целом - думаю - ничего нового для тебя не будет
  32.  
  33. вторая цель - реализовать 2 предка для тест-класса
  34.     в первом - наиболее универсальном - возимся со скриншотами
  35.     в следующем - возимся с открытием урла и очисткой данных после теста
  36. это - сделай и продолжай двигаться дальше
  37.  
  38. сразу читани вот это
  39. https://docs.google.com/document/d/13dNyFGbI7mV22UUhH8E0LJ7SzabAmX7Bw7VCHScYfiU/edit#heading=h.tz2xue7whvu
  40. весь раздел
  41. там есть интересные нюансы
  42. полезно их понимать
  43. ************************************************
  44. Full Coverage with Feature Tests
  45. https://drive.google.com/file/d/0B8hgIBw8-V-AVExIeW1iQ0pXUTg/view
  46. https://drive.google.com/file/d/0B8hgIBw8-V-AUDdxNnpVdXYwbXM/view?usp=sharing
  47.  
  48. в faq - тоже глянь - есть немного полезного на тему работы с локалсториджем
  49.  
  50. третья цель - реализовать full coverage
  51.  
  52. текст задания (та часть, которая касается тебя)
  53.     provide full coverage according your test plan by switching more to feature style tests.
  54.     Move some "coverage" from E2E to FT in order to make E2E smaller,
  55.     more readable and easier to support.
  56.     Leave E2E only for "general" filtering and some basic operations in tasks Life Cycle.
  57.  
  58.     Make tests fast via implementing correspondent precondition helpers.
  59.  
  60. в принципе - оптимизировать покрытие по заданию - не обязательно
  61. но в общем - стоит - чтоб понимать - как это делается
  62.     потому - оптимизируй и приводи тест-план - с показанным покрытием
  63. ****************
  64. в чем оптимизация
  65.     - что покрыто в е2е - не покрываем фиче-тестами
  66.     - низкоприоритетное - покрываем единожды, на каком-то из контекстов (пример - delete by emptying text)
  67.     - низкоприоритетные варианты фичи, у которой есть покрытые варианты - не покрываем (пример - reopen all & add)
  68. ****************
  69. как реализовывать набор гивен-методов - изложено в видео
  70. это так сказать минимально нужное)
  71.  
  72. а можно и потренироваться в использовании Builder pattern)
  73.  
  74. чтоб получить что-то типа такого
  75.     given().activeTasks("a").completedTasks("b").atCompletedFilter().prepare();
  76.     вместо
  77.     given(new Task(ACTIVE, "a"), new Task(COMPLETED, "b"))
  78. а таком варианте - не настаиваю
  79. будет вариант given(new Task(ACTIVE, "a"), new Task(COMPLETED, "b")) - тоже ок будет
  80. это лишь в рамках тренировки Builder pattern полезно
  81.  
  82. дальше - про Builder pattern подробнее
  83. *********************************************************************
  84. ИТОГО - наш финиш
  85.     реализация full coverage
  86.     тест-план для full coverage
  87.     примененный репортинг (приведи парочку скриншотов алюр-репорта - чтоб был виден и приаттаченый скриншот)
  88.     примененные принципы - предки тест-класса
  89. ***********************************************************************************    
  90.    
  91. Builder pattern
  92.  
  93.   https://jlordiales.me/2012/12/13/the-builder-pattern-in-practice/
  94.    http://www.journaldev.com/1425/builder-design-pattern-in-java
  95.  
  96.    По этим линкам - по моему мнению - неплохо и несложно разъяснено про паттерн Builder
  97.    по второй линке - вообще пошагово
  98.  
  99.    еще и это пригодится
  100.     вот неплохие линки - про использование this
  101.            https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
  102.            http://stackoverflow.com/questions/2411270/when-should-i-use-this-in-a-class
  103.  
  104.    буду иносказательной и я)
  105.  
  106.    У нас будет класс = то, что мы строим
  107.    и его внутренний класс (а если точнее - nested static class) = builder = как мы это строим
  108.  
  109.    мы хотим строить пошагово - сначала рассказать в сколь угодно много шагов(любая их комбинация)
  110.    а потом - по собранной в шагах информации - построим наш объект
  111.  
  112.    и поскольку - чтобы строить объект - мы применяем класс-строитель
  113.    то - конструктор для нашего объекта - не нужно делать public
  114.  
  115.    Допустим, мы делаем некий напиток
  116.    мы можем добавлять
  117.        воду
  118.        сахар
  119.        красители
  120.        алкоголь
  121.        фрукты
  122.    паковать это в некую тару
  123.  
  124.    ну и вот это все в комплексе - и есть создание напитка
  125.  
  126.    вот и создаем класс Drink = т к делаем мы напиток
  127.    и у него внутри - реализуем и класс-строитель = Barman
  128.  
  129.    public class Drink {
  130.        private int water;
  131.        private int sugar;
  132.        private List<Colour> colours;
  133.        private List<Alcohol> alcohols;
  134.        private List<Fruit> fruits;
  135.        private Bottle bottle;
  136.        /*
  137.            все свойства конечного объекта - описываем как private поля объекта
  138.        */
  139.  
  140.        private Drink(Barman barman) {
  141.            water = barman.water;
  142.            sugar = barman.sugar ;
  143.            colours = barman.colours;
  144.            alcohols = barman.alcohols;
  145.            fruits = barman.fruits;
  146.            bottle = barman.bottle;
  147.            ...
  148.        }
  149.        /*
  150.            конструктор этого класса = тоже private
  151.            и в качестве параметра он получает как раз объекта-строителя
  152.  
  153.            в конструкторе - переносим данные из строителя  - в поля нашего объекта
  154.            и далее - (см "..." в коде) при необходимости как-то работаем с данными
  155.        */
  156.  
  157.  
  158.        public static class Barman {
  159.            private int water;
  160.            private int sugar;
  161.            private List<Colour> colours;
  162.            private List<Alcohol> alcohols;
  163.            private List<Fruit> fruits;
  164.            private Bottle bottle;
  165.            /*
  166.                у класса-строителя - такой же набор полей
  167.                и они тоже private
  168.  
  169.                все методы этого класса, кроме одного(build()) -
  170.                как раз и будут собирать эти свойства
  171.            */
  172.  
  173.            public Barman(Bottle bottle) {
  174.                this.bottle = bottle;
  175.                colours = new ArrayList<Colours> ();
  176.                ...
  177.            }
  178.            /*
  179.                конструктор класса-строителя - объявляем как public
  180.                здесь мы инициализируем все поля этого класса
  181.  
  182.                если это необходимо - можно реализовать конструктор с параметрами
  183.                цель - передать то, что будет обязательным для заполнения
  184.            */
  185.  
  186.            public Barman addWater(int water) {
  187.                this.water += water;
  188.                return this;
  189.            }
  190.            /*
  191.                каждый из методов, заполняющих какое-либо из свойств - это public метод
  192.                и возвращает такой метод самого объекта-строителя
  193.            */
  194.  
  195.            public Barman addFruits(Fruit... fruits) {
  196.                for (Fruit fruit:fruits) {
  197.                    this.fruits.add(fruit);
  198.                }
  199.                return this
  200.            }
  201.            /*
  202.                заметь - такие методы не заново заполняют соответствующие поля - а лишь дополняют то,
  203.                что мы изначально задали в конструкторе
  204.  
  205.                цель - иметь возможность многократно и в любой последовательности вызывать методы строителя
  206.  
  207.                для каждого из свойств - реализуем такого плана метод
  208.            */
  209.  
  210.            public Drink build() {
  211.                return new Drink(this);
  212.            }
  213.            /*
  214.                а этот метод класса-строителя - возвращает новый объект - который мы как раз строим
  215.                и передаем в конструктор - this = наш объект-строитель
  216.  
  217.                собственно - фактически это и будет создание нашего объекта Drink
  218.                (вспомни - что мы делали в конструкторе класса Drink)
  219.            */
  220.        }
  221.    }
  222.  
  223.    /*
  224.        если минимально - то это все)
  225.  
  226.        теперь мы можем создать нашего строителя
  227.        new Drink.Barman(bottle)
  228.  
  229.        а чтоб эту часть кода сделать нагляднее - можем в классе Drink
  230.        реализовать static метод, возвращающий новый объект типа строитель
  231.  
  232.        например
  233.  
  234.    */
  235.    public class Drink {
  236.        ....
  237.  
  238.        public static Barman composeDrink(Bottle bottle) {
  239.            return new Barman(bottle);
  240.        }
  241.  
  242.        public static class Barman {
  243.            ...
  244.        }
  245.    }
  246.  
  247.    /*
  248.         и далее в коде
  249.         применив import static для  composeDrink -
  250.         писать
  251.    */
  252.  
  253.        composeDrink(bottle)
  254.  
  255.        а не
  256.  
  257.        new Drink.Barman(bottle)
  258.  
  259.    /*
  260.        ну и далее - начинается самое интересное
  261.  
  262.        composeDrink(bottle) - возвращает объект-строитель
  263.        у которого много методов, "доливающих" наш напиток = уточняющих наш рецепт
  264.  
  265.        а т к каждый из этих методов - возвращает тот же объект
  266.        мы можем строить любые цепочки вызовов
  267.        и заканчивать такую цепочку - вызовом build
  268.  
  269.        только в вызове build -  и будет построен объект
  270.        согласно тому - что мы уточнили ранее
  271.  
  272.    */
  273.       composeDrink(bottle).addWater(...).addAlcohol(...).addFruits(...).addColor(...).addFruits(...).build(); - некий коктейль )
  274.       ...
  275.       composeDrink(bottle).addWater(...).build(); - просто бутылка с водой
  276.       ...
  277.       composeDrink(bottle).build();  - вообще пустая бутылка )
  278.  
  279.  
  280.       теперь вспоминаем - о чем это мы
  281.  
  282.       мы собирались делать вот что
  283.        given().build() - ни одной таски
  284.        given().activeTasks("a","b","c").completedTasks("d", "e").atAllFilter().build() - разные таски на таком-то фильтре
  285.        given()......build() - можно разные делать - в зависимости от потребностей
  286.  
  287.       Видишь сходство? )
  288.  
  289.       в общем-то - экономически не оправдано в задаче такого уровня применять этот паттерн
  290.       тут можно прекрасно реализовать несколько гивен-методов
  291.       и этого будет  - с головой достаточно)
  292.  
  293.       можно просто - в начале реализовать базовый гивен-метод
  294.       и затем - когда он уже будет работать - развить его до такого решения
  295.       чтоб отдельно решать задачу - разобраться с тем что сделать и как сделать
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement