julia_v_iluhina

Untitled

Nov 7th, 2016
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.05 KB | None | 0 0
  1.             <plugin>
  2.                 <groupId>org.apache.maven.plugins</groupId>
  3.                 <artifactId>maven-surefire-plugin</artifactId>
  4.                 <version>2.19.1</version>
  5.                 <configuration>
  6.                     <parallel>methods</parallel>
  7.                     <threadCount>5</threadCount>
  8.                     <forkCount>2</forkCount>
  9.                     <reuseForks>true</reuseForks>
  10.                 </configuration>
  11.             </plugin>
  12.  
  13. ...
  14. public class BaseTest {
  15.  
  16.     @Before
  17.     public void init() {
  18.         System.setProperty("webdriver.chrome.driver", "/home/belka/Chromedriver/chromedriver");
  19.         setDriver(new ChromeDriver());
  20. //        setDriver(new FirefoxDriver());
  21.     }
  22.  
  23.     @After
  24.     public void close() {
  25.         getDriver().quit();
  26.     }
  27.  
  28. }
  29. /*
  30.     пока предлагаю в  pom - закомментировать кусок по параллельный запуск
  31.     и в предке тест-класса - тоже перейди на BeforeClass & AfterClass
  32.  
  33.     цель - пока не тратить время при тестировании
  34.     на создание вебдрайверов и их удаление - для каждого теста
  35.  
  36.     когда идет разработка - такие моменты пожалуй мешают
  37.  
  38.     не настаиваю, но советую)
  39. */
  40. ******************************************
  41. public abstract class Condition<V> {
  42.  
  43.     public abstract V apply(By locator);
  44.  
  45.     public abstract String toString();
  46.  
  47.  
  48.     public static Condition<WebElement> text(final String text){
  49. /*
  50.     ага, у тебя получился - такой - многофункциональный класс Condition)
  51.  
  52.     вообще - лучше придерживаться принципа Single Responsibility Principle
  53.     погугли про это
  54.     суть - что у каждого класса - своя ответственность
  55.  
  56.     а этот класс у нас - и абстрактный предок для кондишенов, и контейнер для реализованных кондишенов, и контейнер для логики кетчера
  57.  
  58.     будем разделять )
  59.  
  60.     по пути уже
  61.         все без исключения классы - потомки класса Object
  62.         а у него  - реализуовн метод toString()
  63.         соотвественно - не нужно объявлять этот метод как абстранктный
  64.  
  65.         как надумаешь реализовывать - реализуй
  66.         а объявлять - не надо
  67.         это уже на уровне Object сделано
  68.  
  69.     твое предложение в слеке - сделать  Condition<V> - очень разумное
  70.     ведь нам нужно для начала - лишь декларировать - что классы, имплементирующие такой интерфейс - будут реализовывать такой-то метод
  71.  
  72.     Так что - реализуй интерфейс  Condition<V>
  73.     с объявленным методом V apply(By locator)
  74.     и это все)
  75.  
  76.     Сами кондишены - реализуй отдельныи классами, имплементирующими этот интерфейс
  77.     Не - объектами анонимного класса
  78.     а - именно - отдельными классами
  79.     Позже - получим выгоды от этого
  80.     В так реализованных классах - реализуешь
  81.         конструктор с нудными кондишену параметрами
  82.         собственно метод  V apply(By locator)
  83.         и toString()
  84.     да, пока ни кетчер, ни try-catch секции в apply - применять не нужно (мы эту логику по-другому встроим)
  85.  
  86.     Пока - реализуй лишь самые необходимые кондишены
  87.  
  88.     И отдельно - реализуй класс-контейнер статических методов Conditions для вызова кондишенов
  89.  
  90.     что-то типа вот такого получишь
  91.     public static Condition<WebElement> exactText(String expectedText) {
  92.         return new ExactText(expectedText);
  93.     }
  94.     цель реализации таких методов - чтоб использовать более лаконичный вариант
  95.     exactText(...)
  96.     вместо
  97.     new ExactText(...)
  98.  
  99.     и класс Conditions - будет понятным и лаконичным
  100.  
  101.     да, сущностей прибавится
  102.     но - код станет проще и структурнее
  103. */
  104. *************************
  105. /*
  106.     собственно - чтобы пощупать это новое решение в работе - мы можем использовать наш тестик google search
  107.  
  108.  
  109.     нам в задании предлагалось реализовать
  110.  
  111.     assertThat(elements, nthElementText(0, “some text”));
  112.     assertThat(element, visible());
  113.  
  114.     еще к этой паре - реализовать и size
  115.     и как раз попробовать вариант testSearchAndFollowLink
  116.  
  117.     остальные кондишены - пока не торопись, потом реализуем, по мере необходимости
  118.  
  119.     ты уже реализовала visibilityOfElementLocated()
  120.     как раз - вариант для нашего целевого visible()
  121.  
  122.     listNthElementHasText - тоже ок релизация
  123.  
  124.     size - в принципе тоже уже делали
  125.     не будет чего-то особо нового
  126.  
  127.     остальные - пока просто не реализовывай даже)
  128.  
  129. */
  130. *****************************
  131. public class Element {
  132. public class Elements {
  133. /*
  134.     это ты убежала далеко вперед)
  135.     это уже следующее задание
  136.     мы пока лишь вот этот кусочек делаем
  137.     http://joxi.ru/8An6LoZhqYgOBA
  138.  
  139.     пока - это отложи
  140. */
  141.  
  142. public class Html
  143. /*
  144.     пока не поняла - как это нам пригодится
  145. */
  146. *********************************************
  147. http://joxi.ru/zANDEYxulQ5R1m
  148. /*
  149.     это тоже переноси в core
  150.  
  151.     будем внутри core - раскладывать все по подпекеджам
  152.  
  153.     уже сейчас в core создай пекедж old - будем туда складывать то, что вскоре просто удалим
  154.     пока нам это может пригодиться - как источник некой нужной логики
  155.     туда уже уйдет CustomConditions
  156.  
  157.     и создай пекедж entities - для Element и Elements (мы пока не будем их развивать, но позже - будем)
  158.  
  159.     и еще - пекедж conditions
  160.     для кондишенов - интерфейса, собственно кондишенов, и класса Conditions
  161.  
  162. */
  163. *****************************************
  164.     public static <V> V waitUntil(By locator, Condition<V> condition){
  165.         ...
  166.         boolean conditionMatched = false;
  167.         /*
  168.             мы вполне можем обойтись без этой переменной
  169.         */
  170.         do {
  171.             try {
  172.                 V apply = condition.apply(locator);
  173.                 if (apply != null) {
  174.                     if (conditionMatched) {
  175.                         return apply;
  176.                     } else {
  177.                         conditionMatched = true;
  178.                         sleep(Configuration.timeout);
  179.                         continue;
  180.                     }
  181.                 } else {
  182.                     conditionMatched = false;
  183.                 }
  184.                 /*
  185.                     получили результат apply
  186.                     если он не равен нулл - сразу вернули его же
  187.                     все, if-блок закончили
  188.  
  189.                     а после него - просто чуть подождали sleep
  190.                     только не 4 секунды
  191.                     а миллисекунд 100 (тоже это вынеси в Configuration -
  192.                     другой переменной  - pollingInterval
  193.                     чтобы тоже можно было настраивать)
  194.  
  195.                     в наш общий таймаут 4 секунды мы должны многократно вызвать condition.apply
  196.                     и делать это разумно через маленькие интервальчики
  197.                     чтобы с одной стороны - лишнего не ждать (а значит - надо проверять почаще)
  198.                     а с другой стороны - не слишком частить (страница же не молниеносно загружается -
  199.                     зачем делать заведомо лишние проверки - они только ресурсы жрать будут)
  200.  
  201.                     и вот такой вариант - когда общий таймаут - 4 секунды,
  202.                     а проверяем мы в рамках ждущей проверки - через каждые 100 миллисекунд
  203.                     как раз и даст нам нужный эффект
  204.                 */
  205.             } catch (WebDriverException | InterruptedException  ex) {}
  206.             /*
  207.                 вот этот catch - и будет заменителем нашего кетчера
  208.                 в apply - не ловим исключений и не применяем кетчера в кондишенах
  209.                 а тут - будем ловить то, что ловили в кетчере
  210.  
  211.                 насчет InterruptedException - есть идея - как избавиться
  212.             */
  213.  
  214.             try {
  215.                 sleep(Configuration.timeout);
  216.             } catch (InterruptedException e) {
  217.                 e.printStackTrace();
  218.             }
  219.             /*
  220.                 вот этот блок - реализуй как метод sleep
  221.                 с параметром - сколько миллисекунд это делать
  222.  
  223.                 и уже оперируй этим методом
  224.                 как следствие - тут не придется ловить InterruptedException
  225.             */
  226.         }
  227.         while (System.currentTimeMillis() - startTime < Configuration.timeout);
  228.  
  229.         if (condition.apply(locator) == null) {
  230.             condition.toString();
  231.             return null;
  232.         } else {
  233.             return null;
  234.         }
  235.         /*
  236.             тут уже можно не выполнять condition.apply
  237.             на самом деле - мы в цикле многократно проверили наш кондишен
  238.             и вызовем мы еше раз condition.apply или нет - большой разницы не будет
  239.  
  240.             если мы внутри цикла не вышли - значит кондишен так и не выполнился
  241.             и значит - нам нужно вызвать исключение
  242.             нам же нужно - чтобы тест упал
  243.  
  244.             у селениума есть подходящее исключение - TimeoutException
  245.             в качестве сообщения - используй что-то типа
  246.                 failed while waiting ... seconds
  247.                 to assert __condition___
  248.  
  249.                  __condition___ - это как раз toString кондишена
  250.  
  251.             чтобы проверить как работает ждущая проверка
  252.             и как сообщается о возникших проблемах -
  253.             проверяй и на заведомо не выполнимые условия
  254.         */
  255.     }
  256. ******************************
  257.     public static WebElement $(By locator){
  258. /*
  259.     этот метод - верно реализовала
  260. */
  261.  public static List<WebElement> $$(By locator){
  262. /*
  263.     а этот не торонись пока реализовывать
  264.     и кондишен visibilityOfElementsLocated - тоже не торопись реализовывать
  265.  
  266.     пока закомментируй метод)
  267. */
  268. ************************************
  269. /*
  270.     пока  - GMail & todoMVC тесты и пейджи - тоже закомментируй
  271.     нам уже пора проверять наше решение
  272.  
  273.     проще это делать на google search )
  274.     пока)
  275. */
  276. *************************************
  277. /*
  278.     хорошая идея - реализовать умное ожидание в отдельном классе
  279.     с точки зрения Single Responsibility - так будет лучше
  280.  
  281.     наглядно этот класс назвать WaitFor
  282.     а статический метод-умный ожидатель выполнения кондишена - until
  283.     и в коде мы будем писать waitFor(byCss(...)).until(visible())
  284.     получится очень наглядная и понятная фраза
  285.  
  286.     в том же классе - расположи и метод sleep
  287.     а его сделай - private
  288.     т к sleep будет нужен только для реализации ждущей проверки
  289.  
  290.     чтобы так писать - waitFor(byCss(...)).until(visible())
  291.         реализуй конструктор с параметром By locator
  292.  
  293.         реализуй статический метод waitFor с параметром By locator
  294.         возвращающий - новый объект класса WaitFor
  295.  
  296.         реализуй метод until(...)
  297.     получишь
  298.        waitFor(byCss(...)). - создали объект типа WaitFor
  299.           until(visible()) - вызвали у него метод until
  300.  
  301.     конечно, until-у передавай как кондишен, так и таймаут
  302.     уже второй вариант  until-а - без таймаута (также как и раньше - такой берет таймаут по умолчанию)
  303. */
  304. *********************
  305. /*
  306.     это еще не все, что мы сделаем в этой работе
  307.     пока вперед не лети
  308.     только вот это
  309.    
  310.     не торопись с элементами, коллекциями и should-ами
  311.     это позже будет)
  312. */
Advertisement
Add Comment
Please, Sign In to add comment