Advertisement
julia_v_iluhina

Untitled

Jul 24th, 2016
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.81 KB | None | 0 0
  1. /*
  2.     Для первой версии - неплохо
  3.     но есть еще над чем поработать)
  4. */
  5.  
  6.     static {
  7.         Configuration.remote = Config.REMOTEHOST;
  8.     }
  9. /*
  10.     https://github.com/codeborne/selenide/blob/04561fd8e68ef8b475eecf0c8bdce767db57438d/src/main/java/com/codeborne/selenide/Configuration.java
  11.     http://joxi.ru/5md7jYwtvlRxOr
  12.    
  13.     можно вполне обходиться и без кода Configuration.remote = ...;
  14.     просто при запуске использовав "-Dremote=..."
  15.     понимаю, что так удобнее - при запусках из-под IntelIJ Idea, да и чтобы еще и лишего не писать
  16.    
  17.     судя по Config.REMOTEHOST - ты занулял эту строку перед выкладыванием в репозиторий
  18.     ну мог бы уже и null прописать - чтобы я у себя твой проект без проблем запускала - безо всяких правок)
  19.    
  20.     я бы все же - сам проект оставила без лишних вещей - типа класса Config и кода Configuration.remote = Config.REMOTEHOST;
  21.     прежде всего для того - чтобы понимать глядя на решение - что вот для решения такой-то задачи - надо то-то и то-то
  22.     ведь реально - для конкретно этой решения задачи - этого делать не нужно
  23.    
  24.     а чтобы тебе было по-прежнему удобно (или как ты там про лень писал что-то) - ну напиши bat-файл в 2-3 строки
  25.     и запускай проект где тебе нравится)
  26.    
  27.     в данном случае - я не настаиваю - чтоб избавился от Config и кода Configuration.remote = Config.REMOTEHOST;
  28.     т к в общем - более ничего в проекте не пришлось под это твое желание подпиливать
  29.     т е - все аккуратно получилось
  30.    
  31.     у нас есть задача - чтоб ты на выходе получил проект
  32.     который решает такую-то задачу
  33.     и это решение было если не идеальным, то достаточно хорошим)
  34.    
  35.     если этой цели твои ноу-хау не мешают - то ОК - так даже интереснее
  36.     а если будут засорять решение - буду возражать)
  37.    
  38.     пока норм)
  39.     оставляй если хочешь
  40.    
  41. */
  42. *****************************
  43.  
  44. public class EndToEndToDoMVCWorkflow {
  45.   ...
  46.     @Test
  47.     public void endToEndToDoMVCWorkflow() {
  48.  
  49. /*
  50.     вспомни про conventions  для имен тест-классов
  51.     https://docs.google.com/document/d/13dNyFGbI7mV22UUhH8E0LJ7SzabAmX7Bw7VCHScYfiU/edit#bookmark=id.bligsp5b94xo
  52.    
  53.     в тест-классе могут быть не только EndToEnd тесты, но и еще какие-то другие
  54.     потому информацию об этом выносить в имя тест-класса - не стоит
  55.    
  56.     в общем-то, понять - что это е2е сценарий - можно просто глядя на код
  57.     потому - вообще не стоит в именах тест-класса или тест-метода это подчеркивать
  58.    
  59.     помимо того, часто информацию о том, что это smoke покрытие - тоже, в имена тест-классов и тест-методов не выносят
  60.     далее по курсу будем разбирать категории - вот там как раз это можно и полезно указывать
  61.    
  62. */
  63. ***************************************
  64.  
  65.    public void endToEndToDoMVCWorkflow() {
  66.  
  67.         open("https://todomvc4tasj.herokuapp.com/");
  68.         /*
  69.             тут было бы полезно пропустить строку - чтобы отделить открытие приложения от уже тестируемых действий
  70.         */
  71.         add("1");
  72.         edit("1", "5");
  73.         /*
  74.             тут более полезным был бы код edit("1", "1 edited");
  75.             далее по тексту таски было бы яснее - что это такое за таска
  76.            
  77.             edit("1"... - проверяет предыдущую операцию, это ок
  78.            
  79.             после edit - нет проверки, ни просто проверки, ни косвенной через действие
  80.         */
  81.  
  82.         open("https://todomvc4tasj.herokuapp.com/#/active");
  83.         /*
  84.             пользователь выполняет переход на другой фильтр - не через открытие урла,
  85.             а через клик на нужной линке
  86.            
  87.             и если мы это действие тестируем (а мы его тестируем = это важная функциональность)
  88.             то и мы должны делать клик на линке
  89.         */
  90.         assertTasks("5");
  91.         /*
  92.             вспомни нашу переписку в слеке сегодня
  93.            
  94.             было в списке - таска "5"
  95.             перешли на другой фильтр
  96.             стало в списке - таска 5
  97.            
  98.             то ли ок переход на фильтр работает, то ли вообще ничего не делает
  99.            
  100.             обеспечь - чтобы было-стало  - отличалось
  101.            
  102.         */
  103.         delete("5");
  104.         /*
  105.             поторопился)
  106.             можно было под конец это сделать )
  107.            
  108.             понимаю, хотелось дальше работать со списком,
  109.             в котором только одна таска
  110.             т к проверки через действия только так и получится применять...
  111.            
  112.             но есть и другой способ
  113.             вот закомплитил бы таску еще на all фильтре - на этом фильтре получил бы пустой список тасок
  114.             да, вижу - ниже уже покрывал complete
  115.             а complete all - вообще не покрыл
  116.             вот и решение
  117.            
  118.             после delete - нет проверки
  119.             следующая операция не проверяет delete
  120.         */
  121.         add("2");
  122.         editCanceled("2", "333");
  123.         /*
  124.             тут тоже можно было бы
  125.              editCanceled("2", "2 edit cancelled");
  126.             чтобы и тестовые данные поясняли код
  127.         */
  128.         toggle("2"); //complete
  129.         /*
  130.             нет проверки
  131.         */
  132.  
  133.         open("https://todomvc4tasj.herokuapp.com/#/completed");
  134.         /*
  135.             тут тоже переход на фильтр надо реализовать
  136.             через клик на линке
  137.         */
  138.         assertTasks("2");
  139.         toggleAll(); //reopen all
  140.         /*
  141.             лучше в е2е покрой reopen, а не reopen all
  142.             т к у reopen - приоритет выше, чем у reopen all
  143.             прежде всего потому - что операция reopen более востребована
  144.            
  145.             нет проверки после действия
  146.         */
  147.  
  148.         open("https://todomvc4tasj.herokuapp.com/#/");
  149.         /*
  150.             тут тоже переход на фильтр надо реализовать
  151.             через клик на линке
  152.         */  
  153.         assertTasks("2");
  154.         toggle("2"); //complete
  155.         /*
  156.             если прислушаешься к советам - и покроешь complete all выше по сценарию
  157.             и delete не будешь делать раньше времени
  158.             то сможешь обойтись без второго использования complete
  159.            
  160.             в рамках smoke - нужно покрыть высокоприоритетные операции лишь единожды
  161.             с add так не выйдет
  162.             но вот с остальными операциями - точно выйдет
  163.            
  164.             еще в рамках этого е2е - стоит единожды покрыть проверку счетчика активных тасок
  165.             т к этот счетчик - работает всегда и должен после любой операции отражать реальное положение дел
  166.             не смотря на его не высокий приоритет - с учетом того, что он работает всегда -
  167.             раз стоит покрыть в е2е сценарии, реализующем smoke покрытие
  168.         */
  169.         clearCompleted();
  170.         assertNoTasks();
  171.     }
  172. /*
  173.     анализируем покрытие
  174.      all
  175.         add
  176.         edit
  177.  
  178.      active
  179.         delete
  180.         add
  181.         editCanceled
  182.         complete
  183.  
  184.      completed
  185.         reopen all
  186.  
  187.      all
  188.         complete
  189.         clearCompleted
  190.        
  191.        
  192.       complete - можно было бы покрыть единожды
  193.       вместо reopen all - покрыть reopen - как более высокоприоритетную операцию
  194.       где-то единожды покрыть проверку счетчика активных тасок
  195.      
  196.       а в целом - да, верно выделил - что стоит покрывать
  197.       и неплохо использовал неявные проверки через действия
  198.      
  199.       стоит равномернее распределить операции между фильтрами
  200.       такое равномерное распределение улучшит вероятности по нахождению таких проблем -
  201.       когда на одном из фильтров операции над тасками выполняются с ошибками
  202.      
  203.       в данном случае
  204.       на all - покрыли 4 операции
  205.       на active - тоже 4
  206.       а на completed - лишь одну
  207.      
  208.       возможно, идеально распределить операции не получится
  209.       но точно можно равномернее
  210. */
  211.  
  212. *****************************
  213.     private void assertNoTasks() {
  214.         tasks.shouldBe(empty);
  215.     }
  216.     /*
  217.         то, что в коде тест-класса сначала расположил тест-метод, а уже затем вспомогательные методы - это ОК
  218.        
  219.         можно было бы еще более упорядочить код
  220.         и тем самым облегчить его восприятие
  221.        
  222.         идем от общего к частному
  223.        
  224.         сначала - static initialization block
  225.         потом - тест-метод
  226.         потом - переменная tasks (поторая будет использоваться во многих вспомогательных методах)
  227.         потом - вспомогательные тест-методы
  228.         и они идут в определенном порядке
  229.         отдельно - ассерты
  230.         отдельно - действия
  231.         сначала - базовые, затем - остальные
  232.         рядом - похожие или противоположные штуки
  233.        
  234.         и тогда код будет читаться максимально просто - при том же наборе методов и переменных
  235.         изучая такой код - не придется бегать туда-сюда
  236.         просто прочитал код и все
  237.        
  238.         хотя технически - это не имеет значения - что в каком порядке
  239.     */
  240.  
  241. ***********************************
  242.  
  243.     private void edit(String e1, String e2) {
  244.         tasks.find(exactText(e1)).doubleClick();
  245.         tasks.find(cssClass("editing")).find(".edit").setValue(e2).pressEnter();
  246.     }
  247.  
  248.     private void editCanceled(String e1, String e2) {
  249.         tasks.find(exactText(e1)).doubleClick();
  250.         tasks.find(cssClass("editing")).find(".edit").setValue(e2).pressEscape();
  251.     }
  252.    
  253. /*
  254.     Имена параметров методов e1 & e2
  255.     Мы уже применяем терминологию - taskText
  256.     и тут  - для обозначения текста таски применим эту же терминологию
  257.     часто для обозначения было-стало - применяют old & new
  258.    
  259.     oldTaskText & newTaskText - будет ОК
  260.     придерживайся правила - одно понятие - один термин
  261.    
  262.     чтобы переименовать класс/метод/переменную/параметр
  263.     https://docs.google.com/document/d/13dNyFGbI7mV22UUhH8E0LJ7SzabAmX7Bw7VCHScYfiU/edit#heading=h.vwuqi54t6fyg
  264.    
  265.     Еще важный момент
  266.     Методы очень похожи
  267.     фактически отличие - pressEnter() или pressEscape()
  268.    
  269.     реализуй метод xxx
  270.     который будет выполнять весь одинаковый код
  271.         tasks.find(exactText(e1)).doubleClick();
  272.         tasks.find(cssClass("editing")).find(".edit").setValue(e2)
  273.     и возвращать SelenideElement = элемент, для которого вызывали setValue
  274.    
  275.     чтобы далее вызывать xxx(...).pressEnter()
  276.     подумай над именем этого метода
  277.     оно должно точно отражать - что делает метод
  278.     а делает он - старт/начало редактирования    
  279.    
  280. */
  281. ************************    
  282.     private void assertTasks(String... taskTexts) { tasks.shouldHave(exactTexts(taskTexts)); }
  283.     /*
  284.         используй стандартное форматирование
  285.         это тоже важно
  286.        
  287.         вырабатывай привычку - отдаешь код - отформатируй его
  288.        
  289.         кстати - и ты сможешь больше увидеть в хорошо отформатированном и организованном коде
  290.         это позволяет его лучше рефакторить
  291.        
  292.         в IntelIJ Idea выдели код, и с меню code->reformat code
  293.         запомни горячие клавиши и используй
  294.        
  295.         обрати внимание - что изменится
  296.     */
  297. **************************
  298.     private ElementsCollection tasks = $$("#todo-list li");
  299. /*
  300.     можно быть точнее в селекторе "#todo-list>li"
  301.    
  302.     иногда это будет важно
  303.     в нашем простом приложении - можно и так оставить)
  304. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement