yashaka

Untitled

Feb 6th, 2017
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.57 KB | None | 0 0
  1. ========================================================================================================================
  2. >>>>>>>> предлагаешь писать что то типа
  3.  
  4. THEN().atInboxPage()
  5. .emails()
  6. .shouldHave(size(1));
  7.  
  8. ?
  9.  
  10. >>>>>>>> не, предлагаю писать:
  11.  
  12. THEN().atInboxPage()
  13. .emails()
  14. .shouldHaveTopics(topic);
  15.  
  16. // и оно должно проверить что топиков ровно один и ровно с таким текстом в списке...
  17. ну точно также как и в селениде работает shouldHave(exactTexts(topic)) если бы emails
  18. возвращали ElementsCollection а не виджет
  19.  
  20. >>>>>>>> а, я сразу не понял) крутая идея, посмотри, как у меня вышло, как по мне очень топорно и не будет
  21. таких красивых сообщений как в селениде, ну мож я чего не понял...
  22.  
  23.  
  24. >>>>> не, ну вы сударь изрващенец-с...
  25.  
  26. зацени, твой вариант:
  27.  
  28.  
  29. public Emails shouldHaveTopics(String... texts) {
  30. mails.shouldHaveSize(texts.length);
  31. for (int i = 0; i < texts.length; i++) {
  32. get(i).shouldHaveTopic(texts[i]);
  33. }
  34. return this;
  35. }
  36.  
  37. и тот на который я тебе намекал:
  38.  
  39.  
  40. public Emails shouldHaveTopics(String... texts) {
  41. mails.shouldHave(texts(texts));
  42. return this;
  43. }
  44.  
  45. мне не понятно зачем городить фор, если он уже встроен внутрь кондишена CollectionCondition.texts
  46. ========================================================================================================================
  47. /*
  48. ты таки не всегда используешь проверку Tasks.itemsLeftShouldBe(...); - даже если это воможно
  49. а она ведь - уточняет проверки и улучшает покрытие
  50.  
  51. и почти не усложняет фиче-тестов
  52.  
  53. почему?
  54. */"
  55.  
  56. >>>>>>>> потому что из за одной этой фичи (которая проверена на разных контекстах в достаточном
  57. количестве вариантов) могут упасть все фича тесты, если включать её проверку куда только
  58. можно...
  59.  
  60. получается тест вроде как тестирует edit, destroy, add....а упали все сразу, да еще и с
  61. ошибкой should be items left.
  62.  
  63. >>>>>>>> да, мужик, замечательный аргумент :) Правильно мыслишь. Но :) Дело в том, что со стороны разработки, это работает не так... Эта фича - каунтера - она будет размазана по коду... Оно не реализована где то отдельно... Она будет разбита на количество "подфич" - привязанных к действиям соответствующим. И в реальной жизни будет так, что где то для какого то действия = девелопер забудет "учесть подфичу каунтера" - и тест к этому действию упадет - и упадет правильно - указывая для какого именно действия "подфича каунтера" не сработала. А другие тесты будут проходить. Возможно если бы ты знал как работает фронтенд, то ты это учел. И кстати именно поэтому, нужно что бы девы писали аксептенс тесты а не автоматизаторы ;) Но ты конечно молодец что подумал об этом нюансе, даже очень :) Ты первый студент из всех кто об этом задумался, даже пускай и оно привело тебя к неверным решениям :)
  64.  
  65. >>>>>>>> есть план в google sheet, где было распланировано что мол фича itemsLeft
  66. должна быть протестирована в местах высокого приоритета (add, destroy)
  67. на всех контекстах, в местах низкого (переход между фильтрами, еще что то)
  68. только на одном из фильтров (постаратся нужно было чтоб было размазано по
  69. всем поровну, я старался)), что и было сделано =)
  70.  
  71. Юля настаивала что мол нам ничего не стоит проверить items left в фича тестах,
  72. а я не хотел, и аргумент вот как написал) и до сих пор так считаю, не надо
  73. тулить абы натулить, если проверять уже эту фичу всеобъемлюще, то делать это
  74. организованно, а не рандомно разбрасывая проверки по тестам не для этого написанным)
  75.  
  76.  
  77. >>>>>> чувак, ты не понял. Фича items left - это не фича сама по себе. Это технически 7 или сколько там подфич фич действий. Раставлять проверки каунтера - это не рандомно раставлять - а там где нужно. Проверка каунтера - это часть проверки действия. В гугл шите эти "подфичи" были отдельно только потому что будучи подфичами - они меньшего приоритета... и поэтому можно было не спешить их раставлять в тестах. А когда мы уже перешли к "полному покрытию" - мы их "не рандомно раставили" - а дописали туда где им и место. У меня мозг плывет от твоего "тулить абы тулить". Ты что реально не понимаешь что проверить каунтер для ед таскас, это то же что проверить что задача добавилась? тольк типа "еще одна дополнительная проверка меньшего приоритета". Еще раз - каунтер - это не отдельная фича - это комплекс отедльных подфич которые являются частями фич действий. И поэтому абсолютно логично их проверять там же где и проверяются эти "основные" фичи. есть такое понятие как cohesion в программировании. Которое говорит о том - что связанные вещи должны быть вместе. В контексте системного тестирования поведение каунтера под действие связано с действием. Поэтому это прямой идентификатор "должно быть вместе", и "тулить где попало" - это тут совсем не причем. наоборот - тулить туда где ему и место и по логике поведения пользователя, и по внутренней реализации. Если бы мы писали юнит тесты - там все дробиться как можно меньше.. И там были бы отдельные тесты на добавление задачи в список, и отдельное на каунтер... При этом каунтер бы проверялся даже не через дейсвие, а через искуственно созданный ивент, или еще чего там такого... там бы пришлось симулировать эффекти добавления, реально его не делая... потому что такая уж философия у юнит тестов - вс тестировать раздельно всегда... Но системные тесты - на то и системные что бы тестировать "как оно работает" вместе, особенно учитывая то что каунтер - это часть действия а не отдельная от него вещь.
  78. ========================================================================================================================
  79. @Step
  80. public static ItemsLeft itemsLeft() {
  81. return new ItemsLeft();
  82. }
  83.  
  84. public static class ItemsLeft {
  85. private static final SelenideElement element = $("#todo-count>strong");
  86.  
  87. public void shouldBe(int itemsCount) {
  88. element.shouldHave(exactText(String.valueOf(itemsCount)));
  89. }
  90. }
  91.  
  92. вот тудуемвісі - это пример того приложения где виджеты имхо - это перебор :)
  93.  
  94. но если ты просто хотел потренироваться - тогда ок:) пускай будет :)
  95.  
  96. но тогда если уж "тренироваться" - то наверное стоило бы вынести отдельный виджет Task :)
  97.  
  98. да и еще такой нюанс...
  99.  
  100. мы нигде в других классах не используем ItemsLeft и это значит - что да, норм держать его внутри класса TodoMvc
  101.  
  102. но с другой стороны у нас "запахло Large Class Code Smell"... и типа как "проще" и более понятней, было разложить нашу кучу большую на маленькие в разных местах, а не разложить кучу на кучки по меньше запхать самые маленькие кучки в мешки и положить в мешок с самой больешой кучей внутрь :)
  103.  
  104. Ну такое... смотри сам...
  105.  
  106. >>>>>>>> это ты где смотрел? в текущем варианте проекта вроде остался метод
  107. один, и все) создавал потренироватся просто, согласен что нужно было
  108. бы создать отдельный класс, хотя...
  109.  
  110. >>> ну... не знаю... по твоим же линкам ходил и нашел... где то :)
  111.  
  112. приложение маленькое, и учитывая что этот класс может пригодится
  113. ТОЛЬКО в классе Tasks, то как бы вроде и не надо выносить отдельно,
  114. если этот класс используется только в контексте другого, а
  115. самостоятельно он существовать не может)
  116.  
  117. >>>>> я же тебе тоже самое по сути и написал... что можно и так и так... и "смотри сам"
  118. ========================================================================================================================
  119. а когда нужно писать:
  120.  
  121. new WebDriverWait(...).until(jsReturnedTrue("return $._data($('#clear-completed').get(0), 'events').hasOwnProperty('click')"))
  122.  
  123. >>>>>>>> не понял что ты тут делаешь) вообще ниче не понял, кроме того что текущая реализация
  124. может при медленном интернете падать))
  125.  
  126.  
  127. ========================================================================================================================
  128. вижу ты хромдрайвер держишь в проекте :)
  129. помню Юля уже "жаловалась на тебя" :)
  130. Ну ок, делаешь как хочешь. Но знай, что этим ты перечеркиваешь весь тот путь которым идет Селениум :) То есть ты как бы "споришь с авторами селениума" :)
  131. Значешь почему теперь нет FirefoxDriver ? А есть марионет в виде бинарника ?
  132. Только по одной причине :)
  133. Что бы не зависеть от исходных сорсов :)
  134.  
  135. >>>>>>>> помню помню, спорили)
  136.  
  137. в чем дело было, в двух словах:
  138.  
  139. у меня на проекте один автомейшн и 4 дева, нет отдельной машины, нет ни девопсов ни админов, все решаем
  140. своими силами) было принято решение когда то что тесты будут бежать на виртуалках на машинах девов, т.к.
  141. ресурсов больше нету) и в рабочем проекте у меня хромдрайвер как ресурс, потому что если бы он был
  142. на каждой машине отдельно, то обновление означало бы что мне пришлось бы бегать и руками у каждой виртуалки
  143. хромдрайвер скачивать, ребят от работы отвлекать, да и лень) а так он прям в проекте, обновленные
  144. бинарники сами стягиваются с ремоут репозитория, и все, парится ни о чем не надо)
  145.  
  146. >>>> это реашется простющим скриптом который посылает реквест серверу с хромом и проверяет появилась ли новая версия... и обновляет ее, если локально и хром более новый стоит... где то вот тут можно например на питоне примеры найти: https://github.com/SergeyPirogov/webdriver_manager/blob/master/webdriver_manager/driver.py
  147.  
  148. я другого не видел никогда, и долго противился тому, что это не правильно, хранить такие ресурсы в проекте
  149. с тестами)
  150.  
  151. но все таки одумался, если вдруг у вас еще будут такие же бараны, то вот аргумент который меня убедил на 100%:
  152.  
  153. - хромдрайвер нужен для БРАУЗЕРА по сути, а не для тестов, в них мы его возможности нигде не используем,
  154. а раз такое дело, значит он ближе к браузеру, чем к проекту с тестами, т.к. проекты могут быть разные,
  155. а хром и хромдрайвер одни на всех будут, а значит их и хранить нужно отдельно
  156.  
  157.  
  158. >>>>>>> да хороший аргумент :) это получается то что положить в сорс код - сам установленный хром )
  159.  
  160. не сразу я понял, но лучше поздно, чем никогда :)
  161.  
  162. так что я согласен что хромдрайвер это часть окружения, а не тестового проекта, но в рабочем проекте менять
  163. не буду ничего, т.к. бегать ручками везде менять лень, лучше уж уйти от виртуалок совсем :)
  164.  
  165.  
  166. >>>>>>> да че, виртуалки это еще норм) я бы просто скрипт написал который все делает сам а не руками... но если сейчас все работает, и все привыкли то пускай конечно и будет так...
  167. ========================================================================================================================
  168. Зачем тебе DefaultFail категория с тестом? :)
  169. Ты конечно шаришь :) Я знаю для чего нужен этот трюк, но хочется услышать от тебя обьяснение :)
  170. Я просто не знаю, вы с Юлей говорили об этом уже или нет...
  171.  
  172. >>>>>>>> говорили, не то чтоб ей очень эта идея понравилась, но и настаивать на полном её удалении не стала)
  173.  
  174. моя идея в том, чтоб сделать пустышку с юзер-френдли сообщением, которая будет сообщать в случае неверной
  175. конфигурации, что произошло не так (в частности не существует выбранного тест класса, или в имени очепятка)
  176. и сразу падать, чтоб если вдруг мы чет пушнули, хотим на дженкинсе проверить, и ждем пока пробегут все тесты
  177. в проекте, потому что пропустили букву в имени тест класса)
  178.  
  179. а так сразу все упало и сказало тебе, что мол ты дружище что то напортачил, проверь конфигурации)
  180.  
  181.  
  182.  
  183. >>>>> хм... совсем не то для чего бы я это использовал (как то напомни мне, я тебе позже обьясню зачем это может еще понадобится)... то для чего ты это используешь реально выглядит извращением и абсолютно не KISS:) я пока не понял почему это оно сразу не завалится иза очепятки... у тебя реально были такие случаи?
  184.  
  185.  
  186. ========================================================================================================================
  187. мне кстати не совсем нравиться твоя идея называть "пакет куда ты складываешь полезняшки" как api...
  188. оно просто конфузит слегка... к чему АПИ? :)
  189.  
  190. причем иногда ты называешь так часть которая относится к тест модели - здесь апи как раз подходит...
  191. а иногда часть которая как раз "полезняшки" - типа кастомкондишенов и так дале...
  192.  
  193. ну такое... не уверен знаю ли я лучшее имя... мы обычно называем как core полезняшки
  194. еще есть практика называть common
  195.  
  196. а тестовую модель я называю model... но в этом случае и api подойдет...
  197.  
  198. >>>>>>>> мне просто нравится как это звучит, и пишется :)
  199.  
  200. можно core назвать, возможно оно лучше подходит под описание...
  201. common не нравится, получается что у меня тогда будет верхний коммон, и коммон todomvc, и коммон gmail...
  202. так себе)
  203.  
  204. >>>>>>> так в том то и фишка, что не будет... в тех слоях что вертикальные - вверху будет common (или core) а внутри (для todomvc) будет model ну или api - тут как раз оно подходит....
  205. а в паралельных слоях если будет одинаково - то тоже ок, оно ведь там будет только потому что ты в один проект все налепил... в реальных случаях оно бы в разных проектах было бы скорее всего... да и вообще - для паралельных слоев - оно норм если бы одинаково называлось... пейджобджектс же также и там и там есть...
  206.  
  207. а по поводу model я не совсем понял, поясни пожалуйста)
  208.  
  209. >>>>>>>> ну то что у тебя api для todomvc - это по сути "вход в модель тестового приложения...." поэтому я бы так его и назвал... с другой стороны пейджобджекты тоже часть модели приложения... поэтому я иногда делаю такую структуру:
  210. model/pageobjects/...
  211. model/Application.java
  212.  
  213.  
  214. ========================================================================================================================
  215. public class Application {
  216.  
  217. @Step
  218. public InboxPageObjects atInboxPage() {
  219. return new InboxPageObjects();
  220.  
  221. // мне не совсем понятно почему InboxPageObjects ? почему не InboxPage или Inbox?
  222. // ты же вот почему то не назвал ApplicationPageObjects?
  223. // есть такое понятие как контекст. Если он задан то зачем каждый раз напоминать что я Яша Украинец?
  224. // У меня и так в паспорте написано что я из украины. Я о том что создай один пакет, назови его pageobjects, или как тебе больше нравиться и потом уже незачем повторять в каждом имени класса это PageObjects. И так понятно что оно такое.
  225. }
  226.  
  227. >>>>>>>> ApplicationPageObjects не назвал потому что класс Application олицетворяет собой все приложение,
  228. а не кучку html-elements и "виджетов" :)
  229.  
  230. по поводу InboxPageObjects... не знаю, экспериментирую с названиями классов и пекеджей, стараюсь как
  231. то так сделать, чтоб были разделены классы описывающие страницы приложения на верхнем уровне, и классы-
  232. "виджеты"...
  233.  
  234. >>>> Зачем, мы же в реальной жизни так не делаем? я тебе с Яшей Украинцем вон привел пример... Зачем быть многословным там где и так все достаточно очевидно...
  235.  
  236. если назвать InboxPage то получается что я буду отличать pageobjects высокого уровня от тех что пониже
  237. только приставкой Page... и опять вернусь к тому с чего начал)
  238.  
  239. >>>> к чему вернешься?? что не так... те что полные страници - те с приставкой Page, те что "части страниц, то есть виджеты" - те без. Помоему норм подход. Все различается, что еще нужно? Хотя я сам забил на все эти приставки, мне и так все очевидно. Для мени с точки зрения юзера не важно что то страница или нет, потому что я сам как юзер - не говорю - зайди на фейсбуке на страницу сообщений. Я просто говорю - зайди в сообщения, и точка :)
  240.  
  241. а то что есть это попытка показать что мол вот класс, который содержит в себе все инструменты по
  242. работе с Inbox page)
  243.  
  244. сделал как ты сказал, может в дальнейшем как нибудь красивее придумаю или увижу где то)
  245.  
  246. >>>> смотри смотри :)
  247. ========================================================================================================================
  248. $(".cmsg").waitUntil(hidden, 15_000);
  249. // во первых плохо хардкодить вейты... лучше напиши Configuration.timeout * 3, что бы ты мог их конфигурировать где нужно...
  250. // во вторых - зачем этот вейт здесь? степы не должны проверять результат своих действий... сделал дело гуляй смело... следующий степ должен сам уметь подождать чего там ему нужно... ты вот, мне кажется, вообще начал неблагодарное дело... "точечно вейты раставлять", лучше поставть глобальный таймаут равный 15000 и тогда все и так будет работать. когда ты захочешь кликнуть по кнопке компоуз - оно и так подождет 15 секунд пока она появится... Или ты так пробовал и жмейл у тебя все равно фокусы выкидывал?
  251. Точечно имеет смысл раставлять вейты когда - таких тормознутых мест мало... а жмейл этот один весь сплошной тормоз :) я бы нем лучше глобальный таймаут поставил...
  252.  
  253. >>>>>>>> тут буду спорить :)
  254.  
  255. по поводу хардкодить вейты - а в чем собственно проблема? если я знаю, что именно вот тут в приложухе
  256. все медленно, то почему не поставить точечное ожидание, больше чем обычное?
  257. Configuration.timeout * 3 - не уверен что это лучше, т.к. если вдруг этот момент растянется
  258. на 20,25 секунд то что, увиличивать из за него общий таймаут? смысл точечного вейты заключается
  259. как раз в том, что есть конкретное место, которое отличается от других, и в тестах это отражается
  260. в виде отдельного вейта)
  261.  
  262. >>>> не, именно тут даже спорить не о чем. Configuration.timeout * 3 лучше, потому что вот захардкодил ты 15 секунд. А твои тесты специально запустили на медленной машине, что бы проверить что там все также будет работать как надо, но зная что она медленная увеличили таймаут общий до 15 секунд. И все. Хана. Приложение стало ВЕЗДЕ тормозить в три раза больше... но никак повлиять на твое "захардкодженое место" - возможности нет. Именно поэтому если и раставлять где то точечные таймауты - то все равно делать их "относительными к какой то базе, которую можно конфигурировать".
  263.  
  264. по поводу неблагодарное дело - в чем плюс ставить глобальный вейт на 15 секунд? у нас похожий спор
  265. был в общаке с неделю назад, только тогда я приводил в пример моменты, когда например на
  266. экране появляется анимация, которая идет заданное кол-во секунд...
  267. я говорил о том, что если например у нас есть 100 тестов, и в одном анимация на 25сек, если
  268. мы поставим глобальный таймаут на 30сек (а был допустим 5сек), то это будет означать что все
  269. упавшие тесты станут бежать медленнее на 25 секунд (раньше они падали через 5, а теперь через 30)
  270. что понятно не очень хорошо)
  271. если такие места повторяются, можно вынести в переменную это время, и конфигурировать это в
  272. одном месте)
  273.  
  274. >>>> твой аргумент с анимацие верный. Именно для таких случаев и с такой логикой - и стоит использовать точечные таймауты. Все верно. Но... С жмейлом другая ситуация. Анимация - это конкретный детерминированный случай. Лучше такие сразу "точечно определять и в тестах". Но жмейл - не детерминированный - он реально тормоз. Причем часто и много где. Поэтому с точки зрения эффективности - именно для этого приложения - ты сэкономишь больше времени как раз не на том что падающие тесты будут меньше времени занимать. А на том что не будешь в начале автматизации - заморачиваться с этими точечными вейтами... Потом, позже... У тебя появится какая то статистика, и ты действительно сможешь определить "стабильные тормоза" типа из твоего примера с анимацией. И тогда уже их раставить. Это именно то что я тебе сразу хотел обьяснить.
  275.  
  276. по поводу зачем этот вейт вообще - с одной стороны метод называется ensureLoggedAs(), т.е. во первых
  277. из названия следует что он таки должен привести юзера в статус залогиненного, а чтобы в этом
  278. убедится нужно подождать ошибку, или наоборот, подождать пока появися какой то элемент на
  279. inbox page...
  280. с другой стороны если в логине ошибка, то она должна вылетать из методы который собственно
  281. сам логин и совершает, но не из метода inbox page, который уже хотел куда то там клацнуть, в
  282. то время когда был все еще по факту на Login page...
  283. согласен что вейт возможно не в самом удачном месте, но слово ensure покрывает такую бяку, в
  284. этом конкретном случае)
  285.  
  286.  
  287. >>>> да, согласен, именно изза того что это "еншеа" а не просто степ - то да, в нем асерт допустимый...
  288.  
  289. я правда не уверен что именно сдесь нужна эта "еншуерность", ну то такое...
  290. ========================================================================================================================
  291. public class Emails {
  292. private final ElementsCollection mails;
  293.  
  294. private Emails(ElementsCollection visibleMails) {
  295. this.mails = visibleMails;
  296. }
  297.  
  298. public static Emails all() {
  299. return new Emails(
  300. $$(".Cp tr") // вот этот локатор дублируется, возможно стоит его таки "заDRYить" вынеся его в стическую переменную
  301.  
  302. >>>>>>>> возможно, но он используется почти в одном месте (3 метода рядышком), и я такой типа CopyAndReplace рулит,
  303. Яков на своих видосах говорил, зачем создавать поле если можно и так без проблем поменять локатор когда придется :)
  304. мне не мозолит, но могу вынести, если критично :)
  305.  
  306. >>>> ну... для меня это таки уже не "рядышком" :) ну такое... все субьективно конечно... просто этот локатор сам по себе - не читабельный... я бы его вынес в переменную просто с целью дать ему красивое имя :)
  307.  
  308. ну такое... может сдесь это и не сильно актуально, смотри сам...
  309. ========================================================================================================================
  310. .filterBy(visible)
  311. .filterBy(cssClass("zE"))
  312.  
  313. возможно при большем количестве мейлов это будет медленно в селениде, и быстрее было бы так:
  314.  
  315. filterBy(and("visible and unreaded", visible, cssClass("zE")))
  316. потому что так оно будет "один раз в цикле пробегаться по всем", а в твоем случае будет два раза пробегаться...
  317.  
  318. >>>>>>>> ок, заменю, спасибо за подсказку)
  319. выглядит жутко, странно что селенид создал отдельный свой класс кондишен, но не прикрутил возможность
  320. писать filterBy(visible().and(cssClass())) или чет такое...
  321.  
  322. >>>> ну... вперед - прикрути если хочешь :) законтрибьють в селениде :)
  323. там просто это будет сложнее... там не все так просто... иногда что бы сделать красиво прийдется так извращаться в коде, что лучше уж пускай оно будет не так красиво :)
  324. ну мы будем же писать свой фреймворк, захочешь - попробуешь потом в конце реализовать именно такой вариант как тебе более красивым кажется :) Возможно у тебя получится все достаточно не сложно... мне пока не очевидно, нужно пробовать... у меня еще самого к этому руки пока не дошли...
  325. ========================================================================================================================
  326. не уверен что это хорошая идея - начинать индексы с единици а не с нуля...
  327.  
  328. уж проще научить новичков что в программирования индексы начинаются с нуля, чем потом конфузить более продвинутых инженеров...
  329.  
  330. >>>>>>>> не в программировании, а в большинстве языков скорее)
  331. сделал для того чтоб писалось естественно на уровне тестов
  332.  
  333.  
  334. THEN().atInboxPage()
  335. .emails()
  336. .get(1);
  337.  
  338. потому как мы все таки берем первое письмо, а не нулевое) нули это в программировании, внутри где то, а
  339. в поведениях мне кажется можно допустить нумерацию с еденицы, т.к. это только программисты с нуля нумеруют)
  340.  
  341.  
  342. >>>> ну я же сказал... "проще подучить людей что бы были чуть чуть как программисты чем везде где есть индексы - извращаться в коде" :)
  343. в общем... тут я переубеждать не буду... я когда то сам думал о том что бы так делать как ты... но передумал.
  344.  
  345. я и так много чего делаю "для людей" в тестах. И еще им и индексы с единици начинать - это уже перебор был бы :)
Advertisement
Add Comment
Please, Sign In to add comment