julia_v_iluhina

Untitled

Sep 29th, 2016
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.40 KB | None | 0 0
  1. public class LazyFilteredCollection extends AbstractLazyCollection {
  2.     @Override
  3.     public String toString() {
  4.         return parentCollection.toString() + " filtered by condition " + condition.toString();
  5.     }
  6. /*
  7.     лучше
  8.     return parentCollection.toString() + " filter(" + condition.getClass().getSimpleName() + ")";
  9.  
  10.     посмотри на выражение в condition.toString()
  11.     вряд ли нам это надо)
  12.  
  13.     можно было бы поточнее - отобразить не только имя кондишена , но и ожидаемые значения - т е воспользоваться еще и
  14.     expected()
  15.         но тогда надо менять иерархию
  16.  
  17.         не AbstractCondition<T> implements Condition<T>, DescribesResult
  18.  
  19.         а
  20.  
  21.         AbstractCondition<T> implements Condition<T>
  22.         и
  23.         Condition<T> extends DescribesResult
  24.  
  25.         цель - чтобы методы интерфейса DescribesResult были доступны для переменной типа
  26.         Condition<T> или его потомков
  27.  
  28.         это не обязательно делать
  29. */
  30. **************************
  31. public class LazyFoundByConditionElement extends AbstractLazyElement{
  32. ...
  33.     @Override
  34.     public String toString() {
  35.         return parentCollection.toString() + " find by condition " + condition.toString();
  36.     }
  37. /*
  38.     имя класса - подправь согласно той же схеме
  39.  
  40.     схема = Lazy + откуда + уточнение + Element
  41.  
  42.     LazyCollectionFoundByConditionElement
  43.  
  44.     toString() - подправь аналогично описанному выше
  45. */
  46. **********************************************
  47. /*
  48.   суть в чем
  49.     например, при первом получении getWrappedEntity для
  50.         tasks.find(cssClass("editing")).find(".edit")
  51.  
  52.     в getWrappedEntity для LazyElementInnerElement
  53.     мы выполняем
  54.     parentElement.getWrappedEntity().findElement(innerLocator)
  55.  
  56.     а в этот момент
  57.     parentElement.getWrappedEntity() = null
  58.  
  59.     и мы получается у null пытаемся получить findElement(innerLocator)
  60.  
  61.     и тут происходит ошибка, которую мы не ловим
  62.     и которую ловить - нельзя (технически - можно, но - не правильно)
  63.  
  64.     вот линка, почитай, достаточно внятная
  65.     http://howtodoinjava.com/core-java/exception-handling/how-to-effectively-handle-nullpointerexception-in-java/
  66.  
  67.     а потом углуби понимание http://www.yegor256.com/2014/05/13/why-null-is-bad.html
  68.     особенно внимательно на вот этот кусок посмотри http://joxi.ru/5md7jYwtvV5k8r
  69.  
  70.     получается - что good practice = обходить эти проблемы
  71.     а не перехватывать NullPointerException
  72.  
  73.     можно конечно поступить так (это первое, что приходит в голову, НО МЫ ТАК ДЕЛАТЬ НЕ БУДЕМ)
  74.  
  75.         переписывать getWrappedEntity()
  76.             вместо
  77.             return parentElement.getWrappedEntity().findElement(innerLocator);
  78.             пишем
  79.             return parentElement.getWrappedEntity() == null ? null : parentElement.getWrappedEntity().findElement(innerLocator);
  80.  
  81.         аналогично - и в других классах
  82.  
  83.         кроме этого - поправить apply кондишена - чтобы check вызывался только если его аргумент не равен нуллу
  84.  
  85.     как ты понимаешь - это куча изменений, и достаточно легко что-то пропустить
  86.     лучше - опереться на одно правило и его придерживаться в коде
  87.  
  88.     правило - наш код не возвращает null,
  89.     вместо этого - вызываем исключение (напоминаю про http://joxi.ru/5md7jYwtvV5k8r)
  90.  
  91.     Дорабатываем наши кондишены
  92.         метод check - у нас уже возвращает значение типа boolean (прошла/не прошла проверка)
  93.         в apply -
  94.             если проверка не прошла - вместо того, чтобы возвращать null -
  95.             вызываем исключение WebDriverAssertionException (отнаследуй от WebDriverException)
  96.  
  97.             тут, в apply не применяем try-catch
  98.  
  99.     В WaitFor
  100.         дорабатываем метод until
  101.             как раз тут у нас уже есть try-catch
  102.  
  103.             получается, что если apply бросит ошибку
  104.             то мы попадем в секцию catch ( в которой эту ошибку просто запомним - в переменную)
  105.             (WebDriverException - мы тут ловим, значит - поймаем и WebDriverAssertionException)
  106.  
  107.             а если apply не бросит ошибку - значит все ок - проверка прошла
  108.             потому и делаем сразу return condition.apply(lazyEntity)
  109.  
  110.             итого получили
  111.               в реализация кондишена - мы нуллы нигде не возвращаем (или хорошее значение, или исключение)
  112.               в реализации вейт антила - тоже самое
  113.               причем исключения - используем разные (каждая ситуация = свое исключение)
  114.  
  115.            следующий момент
  116.              еще один источник null - результат getWrappedEntity() для потомков AbstractLazyElement
  117.              для коллекций такого не будет - с будет просто пустой список
  118.              а вот с элементами - да, будет
  119.              потому - надо чуть доработать код в getWrappedEntity() для классов семейства LazyElement
  120.  
  121.              применяем ту же логику - мы нуллы нигде не возвращаем (или хорошее значение, или исключение)
  122.                 в AbstractLazyElement реализуем getWrappedEntity()
  123.                 который вызывает абстрактный метод fetchWrappedEntity() (новый, возвращающий WebElement)
  124.                 и если результат fetchWrappedEntity() равен нулл
  125.                 то getWrappedEntity() вызовет исключение
  126.                 ElementNotFoundException (также отнаследуем от WebDriverException,
  127.                 раз у нас уже несколько своих исключений - в core создай для них свой пекедж exceptions)
  128.  
  129.                 а реализация fetchWrappedEntity() - это то, что мы ранее реализовывали в getWrappedEntity()
  130.  
  131.                 и тут тоже, смотри внимательно
  132.                 если мы сами пишем код (а не вызываем что-то стороннее)
  133.                 то тоже также - мы нуллы нигде не возвращаем (или хорошее значение, или исключение)
  134.  
  135.              получили и для getWrappedEntity() - нулла нам теперь этот метод не возвращает
  136.              а это значит - не надо думать про вызовы getWrappedEntity().... - как
  137.              про источник NullPointerExteption
  138.  
  139.           еще небольшой наворот, раз уж мы так развили работу с исключениями
  140.             в getWrappedEntity() класса LazyCollectionNthElement
  141.             перехватим с помощью try-catch исключение IndexOutOfBoundsException
  142.             и вместо него бросим свое исключение
  143.             LazyСollectionIndexOutOfBoundsException (также отнаследуем от WebDriverException)
  144.  
  145.             что это нам даст
  146.             в WaitFor.until
  147.             можно ловить только WebDriverException
  148.  
  149.             т е  - получили более стройную логику
  150.  
  151.           а за счет того, что помимо ранее выводимой детальной информации
  152.           о проверке, мы еще и выводим информацию об ошибке, которая привела к тому,
  153.           что ошибка не прошла - информация о проблеме - максимально полная
  154.  
  155.           да и то, что мы нигде сами не возвращаем нуллы
  156.           сделало наш код надежнее и проще
  157.  
  158.           теперь - тесты todoMVC падать не должны)
  159. */
  160. **********************************************
Advertisement
Add Comment
Please, Sign In to add comment