julia_v_iluhina

Untitled

Oct 11th, 2016
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 24.30 KB | None | 0 0
  1. public class TaskBuilder {
  2. /*
  3.     да, ты развил структуру проекта)
  4.  
  5.     все эти классы - TaskBuilder, TaskStatus
  6.     можно было бы расположить в Helpers
  7.     разумно переименовать класс Helpers на GivenHelpers
  8.     почитай про nested classes in java
  9.     https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
  10.     https://www.tutorialspoint.com/java/java_innerclasses.htm
  11.  
  12.     ведь все эти классы нужны именно для реализации гивен-методов
  13.     потому - можно их так скомпоновать
  14.  
  15.     что касается класса TaskBuilder
  16.     что он такого строит
  17.     фактически - он является хранилищем данных о таске
  18.     и у класса есть статические методы build - которые создают одну или несколько тасок
  19.  
  20.     т е - класс TaskBuilder объединяет в себе  2 задачи
  21.         - хранить данные о таске
  22.         - создавать таски
  23.     Почитай о Single Responsibility Principle
  24.          если кратко - у каждого класса - есть своя ответственность
  25.          должен быть класс Task - хранилише данных о таске
  26.          и можно реализовать класс TaskBuilder - который будет реализовывать методы
  27.          создающие таску или таски
  28.          но, честно говоря, если класс Task будет жить внутри GivenHelpers
  29.          то там же, в GivenHelpers я бы поселила и эти методы
  30.          не вижу большого смысла для таких 2-ух методов создавать отдельный класс
  31. */
  32.  
  33.    ....
  34.     public String getName() {
  35.     public TaskStatus getStatus() {
  36.     /*
  37.         http://stackoverflow.com/questions/5055177/example-of-getters-setters-as-a-bad-choice-in-java
  38.         http://joxi.ru/Y2LXgYnfn6XnV2
  39.  
  40.         из вот таких соображений - можно не реализовывать геттеры в данном случае
  41.     */
  42.    ...
  43.     public static List<TaskBuilder> build(TaskStatus taskStatus, String... taskNames){
  44.     /*
  45.         я бы реализовывала метод как возвращающий массив Task[]
  46.         почему - ниже станет понятнее
  47.  
  48.         и в обоих методах build - в качестве первого параметра использовала TaskStatus taskStatus
  49.         тоже - ниже станет понятнее
  50.     */
  51. ************************************************
  52.      public void given(TaskBuilder task) {
  53.      public void given(List<TaskBuilder> tasks) {
  54. /*
  55.     реализация этих 2-ух методов - похожа
  56.  
  57.     был бы вариант given(Task... tasks)
  58.      он бы покрыл варианты
  59.         пустой список тасок
  60.         одна таска
  61.         несколько тасок
  62.  
  63.     и метод нужен был бы один - что более DRY
  64.     и все варианты вызова этого метода - достаточно простыми были бы - не надо  собирать список
  65.         given()
  66.         given(build(ACTIVE, "a"))
  67.         given(build(ACTIVE, "a"), build(COMPLETED, "b"))
  68.         given(build(ACTIVE, "a", "b"))
  69. */
  70. *****************************************************
  71. public class BaseTest extends AllureAttachmentTest {
  72.  
  73.     protected TaskManagerPage page = new TaskManagerPage();
  74.     /*
  75.         не очень это хороший вариант - прятать в предка тест-класса - создание пейджа
  76.         был у нас тут спор уже про это)
  77.  
  78.         наше мнение - не стоит это прятать в предка
  79.         ниже - приведу подобный диалог
  80.     */
  81.  
  82.     @Before
  83.     public void setUp() {
  84.         open("https://todomvc4tasj.herokuapp.com/");
  85.     }
  86.  
  87.     @After
  88.     public void cleanUp() {
  89.         executeJavaScript("localStorage.clear()");
  90.     }
  91.  
  92.     /*
  93.         мы наследуем тест-класс от этого класса
  94.  
  95.             перед запуском теста - открываем наше приложение
  96.             после - чистим локалсторидж
  97.  
  98.             гивены можно вызывать и для варианта, когда надо задать пустой список тасок
  99.             значит - можно вызывать в каждом тест-методе гивен-метод
  100.             и убрать очистку локал сториджа после теста - вот уже облегчили код
  101.  
  102.             дальше - раз все тесты происхолят после открытия одного и того же урла
  103.  
  104.             можно вначале гивен-метода проверить
  105.             если сейчас урл не такой, то открыть нужный урл
  106.  
  107.             этот кусочек кода можно оформить в виде метода,
  108.             который будет вызываться вначле гивен-метода
  109.             такого плана методы = если сейчас не так, то сделать так
  110.             часто называют, начиная со слова ensure = обеспечить
  111.  
  112.             вот и не нужен нам код - по открытию урла в бифор-методе
  113.             сразу вопрос - какой предок нужен тест-классу)
  114.  
  115.             вот тебе и еще одна оптимизация)
  116.             кода меньше
  117.             сущностей меньше
  118.             действий лишних меньше
  119.     */
  120. }
  121. **************************обещанный диалог про то, где инициализировать пейдж ****************************
  122. /*
  123. Правильнее - создавать пейджи в тест-классе
  124. т к в разных тест-классах - нужен разный набор инструментов
  125.  
  126. Если принять во внимание, что для всех тест-классов нужен один и тот же набор инструментов - то можно
  127. создать предка для тест-классов с подходящим именем
  128. там создать пейджи
  129. и от этого предка уже наследоваться
  130.  
  131. public class AtTodoMVCTest extends BaseTest{
  132.     protected TodoMVCPage todoMVCPage = new TodoMVCPage();
  133. }
  134.  
  135. ***********
  136.     student
  137.     Всім привіт.
  138.     стосовно зауваження по ініціалізації пейджи в базовому тест класі https://www.refheap.com/120326
  139.     "Соображения -
  140.        даже в рамках тестов одного приложения не факт, что в разных тест-классах понадобидся одна и та же пейджа
  141.        не хочется портить универсального предка для тест-класса
  142.        хочется быть более KISS - чтобы не приходилось из тест-класса искать - что за пейджа у нас "
  143.  
  144.     Я залишусь при свої думці. В захист своєї позиції, що досить зручно коли ініціалізація всіх пейджів знаходиться в одному класі. А те що з тестового класу не видно що саме за пейджа, то у випадку комплексного веб додатку це вирішується лаконічними назвами змінних в парент тест-класі і звикається до цього досить швидко.
  145.  
  146.     yashaka
  147.     ти порушуєш деякі принципи
  148.  
  149.     наприклад:
  150.     Single Responsibility Principle
  151.  
  152.     твій бейс клас починає відповідати і за пейджі…
  153.     хоча перед цим він відповідав за інше…
  154.     А тепер він вже став “контейнером пейджів" (edited)
  155.  
  156.     більше того, ім’я твого класу нічого не каже про те що він є контейнером пейджів
  157.  
  158.     такий код - є магічним - тому що приховує важливу інформацію
  159.  
  160.     те що до цього можна звикнути - бо запам’ятати - це погана практика…
  161.     бо колись твоя пам’ять зламається, якщо ти будеш забагато магії тримати в голові
  162.  
  163.     тести мають бути очевидними - це основне правило…
  164.  
  165.     і це значить що все що стосується тест логіки - має бути в тесті, навіть якщо воно дублюється
  166.  
  167.     тут KISS важливіше за DRY
  168.  
  169.     якщо тобі так сильно хочеться тримати всі пейджі в одному місці - то для цього варто створити окремо клас - контейнер пейджів
  170.     назвати наприклад його App
  171.     і вже через нього мати доступ до цих пейджів…
  172.  
  173.     можливо у вигляді статичних просто змінних
  174.     щоб писати App.todoMVCPage
  175.     ну чи просто
  176.     App.page
  177.     сокільки у нас інших пейджів немає…
  178.  
  179.     так що ти звісно можеш робити як завгодно, але при такому рішенні ти отримаєш не done, а accepted )
  180.     бо ми таки не згодні з таким варіантом )
  181.  
  182.     якщо хочеш “зручності”
  183.     то або створи окремо контейнер пейджів
  184.     або забери з бейс теста пейджу і запхни в базовий тест клас з відповідним іменем
  185.     типу AtTodoMVCPageTest
  186.     щоб було зрозуміло за що цей клас відповідає
  187.  
  188.     але можеш ще нас переконати ) якщо знайдеш аргументи )
  189.  
  190.     >  А те що з тестового класу не видно що саме за пейджа,
  191.     то у випадку комплексного веб додатку це вирішується лаконічними назвами змінних в парент тест-класі
  192.  
  193.     не зрозумів чому “лаконічні назви” допомагають “видимості” )
  194.  
  195.     проблема все одно є, і “я все запам’ятаю бо назви лаконічні і у мене хороша пам’ять” - це якийсь заслабкий аргумент
  196.  
  197.     не у всіх хороша пам’ять… плюс тести сапортяться часто тими хто їх не писав, наприклад програмістами -
  198.     їх теж ти змусиш запам’ятати все що живе в базовому класі?
  199.  
  200.     > що досить зручно коли ініціалізація всіх пейджів знаходиться в одному класі
  201.  
  202.     “досить зручно” це не аргумент
  203.  
  204.     аргументом було б щось типу “це зручно тому що… “
  205.  
  206.     ну і знову ж таки… вище я писав - що "одне місце” можна реалізувати і іншим способом,
  207.     більш “безпечним” і простим, не вимагаючим великих затра пам’яті всієї команди
  208.  
  209.     з приводу зручності - він хоче сказати що є “одна точка доступу” до всіх вже наперед ініціалізованих пейджів…
  210.     але знову ж таки… сумнівна зручність тримати їх в базовому классі…
  211.  
  212.     мати до них доступ через окремий обьект контейнер типу App
  213.     чи Pages
  214.     імхо набагато зручніше тому що це явно
  215.     і через крапочку можна отримати доступ тільки до пейджів, а не до ще чогось, що може жити в тому ж базовому класі
  216.  
  217.     при цьому хоча такий варіант з контейнером - я б прийняв як для done
  218.     я все одно не вважаю це добрим рішенням
  219.     бо імхо явно в тесті показати з якими пейджами іде робота  - набагато більш очевидніше і
  220.     інформативніше ніж в кожен тест “передавати всю пачку пейджів"
  221.  
  222.     julia.v.iluhina
  223.     т е мы заранее считаем - что нам в любых тест-классах нужен одинаковый набор пейджей?
  224.  
  225.     yashaka
  226.     ну… ми не вважаємо - але це так, є мінусом цього рішення )
  227.  
  228.     що ми трохи “запудрюємо мозги” надлишковою інформацією )
  229.  
  230.     це як таскати з собою повний мішок інструментів “на всі випадки життя” :slightly_smiling_face:
  231.  
  232.     хоча можна було б передбачити що сьогодні тобі знадобиться тільки те то і те то
  233.  
  234.     і доречі… поки у нас всього одна пейджа…
  235.     що означає - що нам App - якби трохи зайвий )
  236.     і можна вважати що сам TodoMVC - і є єдиною точкою входу)
  237.  
  238.     таке… враховуючи що це “єдина точка входу і так” - то можна в принципі і винести її кудись в базовий тест клас…
  239.     але все одно - треба створити його окремо, з гарним іменем типу AtTodoMVCPage
  240.     вже й плюс заодно і винести туди прекондішен відкриття сторінкиі очистки даних…
  241.  
  242.     але знову ж таки… як на мене - все це трохи занадто складно як для тестів для еплікейшена
  243.     тільки з одною сторінкою…
  244.  
  245.  
  246.     > Тоді якщо пейджа одна, чому її інітити в різних класах?
  247.  
  248.     тому що це ООП
  249.  
  250.     а в ньому нормально все інітити скрізь де потрібно заюзати
  251.  
  252.     якби це було модульне програмування - то там не треба нічого інітити
  253.  
  254.     > Прекондішини вже використовуються з хелпера, того виходить городити окремий клас в ієрархії
  255.     наслідування заради пейджи тільки....
  256.  
  257.     ну так… правильно мислиш…
  258.     ієрархіх наслідування - це складно, це не КІСС
  259.     але точно така сама логіка з вбудовою пейджі в BaseTest
  260.     ти теж ускладнюєш ієрархію наслідування - тим що “роздуваєш” один з класів в цій ієрархії,
  261.     при цьому порушуючи SRP (Single Responsibility Principle)
  262.  
  263.     таке… тут звісно можна довго сперечатися...
  264.  
  265. */
  266. **************************************
  267. public class TaskManagerPage extends Helpers{
  268.  
  269. /*
  270.     а вот это неожиданно)
  271.  
  272.     могу понять решение отделить возню с гивенами в отдельный класс
  273.  
  274.     но - для чего пейджу наследовать это все? )
  275.  
  276.     применяй наследование - если можешь сказать фразу
  277.     потомок - это тоже предок
  278.  
  279.     и она не будет противоречивой
  280.  
  281.     если с такой фразой есть проблемы, то значит ты не верно используешь наследование)
  282.  
  283.     строим такую фразу    
  284.     TaskManagerPage - это тоже GivenHelpers
  285.     ну, нет, я не могу согласиться с таким утверждением)
  286.  
  287.         можно GivenHelpers - реализовать как второй пейдж
  288.         будет у тебя 2 пейджа
  289.         GivenPage & TaskManagerPage
  290.    
  291.         а можно - внутри пейджа оперировать объектом GivenHelpers givens;
  292.         тогда - немного придется подправить имена методов в GivenHelpers
  293.  
  294.         отложи пока это на конец работы с ревью
  295.         потом поймешь, почему
  296. */
  297. ******************************************
  298. http://joxi.ru/52akqzoUGMRwzr
  299.  
  300. /*
  301.     1 - предков тест-класса - собери в пекедже testconfigs
  302.     тут же, возле тест-классов
  303.  
  304.     2 - сомнительная польза от пекеджа test
  305.     у нас же ветка =  src \ test \....
  306.     т е  - для тестов
  307.  
  308.     дополнительно во внутренний пекедж test все запихивать - смысла нету
  309. */
  310. **********************************
  311.  
  312.     public void testEdit(){
  313.  
  314.         page.given(build("a", ACTIVE));
  315.         page.filterActive();
  316.  
  317.         page.startEdit("a", "a edited").pressEnter();
  318.         page.assertVisibleTasks("a edited");
  319.     }
  320.  
  321.     @Test
  322.     public void testEdit(){
  323.  
  324.         page.given(build("a", COMPLETED));
  325.         page.filterCompleted();
  326.  
  327.         page.startEdit("a", "a edited").pressEnter();
  328.         page.assertVisibleTasks("a edited");
  329.     }
  330.  
  331.     @Test
  332.     public void testEditAtAll() {
  333.  
  334.         //given
  335.         page.create("a");
  336.  
  337.         page.startEdit("a", "a edited").pressEnter();
  338.         page.assertVisibleTasks("a edited");
  339.         page.assertItemsLeft(1);
  340.     }
  341. /*
  342.     смотрим на фиче-тесты для edit
  343.  
  344.     во всех 3-х методах - оперируем единственной таской
  345.  
  346.     правильнее - в разных фиче-тестах для одной фичи реализовывать разные тестовые ситуации
  347.     например
  348.         редактируем единственную таску
  349.         редактируем вторую таску
  350.         редактируем единственную видимую (при том, что есть и не видимые)
  351.  
  352.     также
  353.        во всех тест-методах - используй гивен-метод для реализации предварительных действий
  354.        расположи фиче-тесты - в соотвествующем им классе (раз уже побежал вперед - надо довести эту идею до ума)
  355.        в качестве последней проверки - делай assertItemsLeft
  356.  
  357.     примени это и к другим фиче-тестам
  358.  
  359.     еще момент
  360.  
  361.        мы получаем - что предварительные действия мы делаем в 2 шага
  362.        page.given(build("a", ACTIVE));
  363.        page.filterActive();
  364.  
  365.        сначала - готовим локалсторидж, потом - если надо - переходим на фильтр
  366.  
  367.        было бы лучше - чтобы этот переход на фильтр делался внутри гивен-метода
  368.        собственно, поэтому я и предлалала создать givenAtActive, givenATCompleted
  369.        (см слек)
  370.        и вот тут мы столкнемся с проблемкой)
  371.        т к гивен-методы у тебя живут в одном классе, а методы переходов - в другом)
  372.        перенести методы переходов по фильтрам к гивен-методам - неверно
  373.        надо по-другому выкручиваться)
  374.  
  375.        в GivenHelpers - реализуй например prepareTasks (фактически - это твой  given(Task... tasks))
  376.        а набор гивен-методов - реализуй в пейдже TaskManagerPage
  377.        и в методах - используй prepareTasks и методы переходов по фильтрам
  378.  
  379.        это как вариант
  380.        есть конечно еще варианты
  381.        этот - неплохой, структурно верный, и стабильный
  382.        советую его, но не буду настаивать
  383.  
  384. */
  385. ****************************
  386. public class TodoMVCTest extends BaseTest {
  387.  
  388. /*
  389.     тут у тебя останется - только е2е
  390.     остальные - распредели по соответствующим тест-классам
  391.  
  392.     этот тест-класс можно будет назвать более детально -
  393.     TodoMVCGeneralTest or TodoMVCIntegrationTest
  394. */
  395. **********************************
  396. CompletedFilterFTest
  397. /*
  398.     F - я бы не стала вот это F лепить в имя тест-класса
  399.  
  400.     это не устоявшаяся аббревиатура
  401.     да и эта информация особо ничего не дает на этом уровне
  402.  
  403.     мы указали - что речь про тесты на таком-то фильтре
  404.     для имени тест-класса этого достаточно
  405.  
  406.     а отчет - покажет что там за тесты
  407.  
  408.     касается и других тест-классов
  409. */
  410. **********************************
  411. /*
  412.     в задании не требуется, но можно оптимизировать покрытие
  413.    
  414.     в чем оптимизация
  415.         - что покрыто в е2е - не покрываем фиче-тестами
  416.         - низкоприоритетное - покрываем единожды, на каком-то из контекстов (пример - delete by emptying text)
  417.         - низкоприоритетные варианты фичи, у которой есть покрытые варианты - не покрываем (пример - reopen all & add)
  418.        
  419.     если будешь применять оптимизацию - приведи тест-план с указанным покрытием и приоритетами - только так я и смогу понять
  420.     ход мысли
  421.        
  422.     а не будешь - то покрывай все )
  423.     тогда конечно можешь тест-плана не приводить
  424.        
  425.     полезнее оптимизировать  
  426.  
  427.     да, не забудь еще про фиче-тесты для не покрытых переходов с фильтра на фильтр -
  428.     проверь себя по тест-плану - все ли покрыл, что запланировал
  429.  
  430. */
Advertisement
Add Comment
Please, Sign In to add comment