Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 1 Есть какое-то нарушение в логике теста
- Given по идее должен полностью заменить add но этого не происходит.
- https://bitbucket.org/wuppert/todomvc/src/bd2c3ca12f558bd7d5c108daad9374b5a443d54e/TodoMVCTestBackup/src/test/java/SmokeE2ETest/?at=master
- Element not found {#todo-list>li.filter(exact text '2')}
- Expected: visible
- Screenshot: file:/E:/Projects2Git/TodoMVCTestBackup/build/reports/tests/1485024883010.1.png
- @Test
- public void testTaskFlow() {
- given("1");
- assertTasksAre("1");
- toggleAll(); // complete all
- assertTasksAre("1");
- filterActive();
- assertNoVisibleTasks();
- given("2");
- /*
- given - это не аналог и не заменитель для метода add
- given - полностью заменяет таски в списке, и делает это через работу с данными
- add - добавляет таски, к уже существующим, причем делает это через UI (User Interface)
- применяй given - для создания НАЧАЛЬНОЙ ситуации в тесте
- чтобы обеспечить = что должно быть в списке тасок на начало выполнения тестов
- а вот если речь идет о тесте собственно добавления таски - используй метод add
- в начале этого метода - можно пойти 2-мя путями
- 1й путь
- given("1"); - не считаем - что в е2е на all покрыли добавление таски
- первая тестируемая операция
- и т д
- 2й путь
- given(); - обеспечили на начало теста пустой список тасок
- add("1"); - а это уже тестируемая операция, тестируем добавление таски на all фильтре
- оба пути возможны
- выбор повлияет на то, что и где мы покроем
- и что нужно будет допокрывать фиче-тестами для реализации full coverage
- */
- .....
- *****************************************************
- @Test
- public void testDelete() {
- given("1", "2");
- assertTasksAre("1", "2");
- assertItemsLeft(2);
- /*
- в целом - структура метода верная
- в начале тест-метода - задали тестовую ситуацию используя гивен-метод
- далее - тестируемая операция и проверки после нее
- причем - сначала - проверили более важное - списо тасок
- и затем - уточнили - проверили менее важное assertItemsLeft
- единственное замечание - не нужно проверок после вызова гивен-метода
- мне кажется, это мы уже обсуждали ранее, на этапе выполнения Smoke + F
- повторю текст про это
- */
- delete("2");
- assertTasksAre("1");
- assertItemsLeft(1);
- }
- /*
- Это к общему сведению)
- Есть разные способы выполнять предварительные действия
- Мы сейчас делаем это через действия на UI (User Interface)
- А есть еще методы - работать непосредственно с данными (далее вы такое тоже попробуете)
- Так вот через действия на UI - предварительные действия не быстрые и часто не достаточно надежные
- А через непосредственную работу с данными - предварительные действия быстрые и надежные
- Если предварительные действия медленные или не надежные
- То проверка в конце предварительных действий нужна
- А если мы уверены - что после предварительных действий гарантировано все ОК,
- то и проверок не надо после предварительных действий
- Но, поскольку наше приложение - простое
- Разумно не делать проверку в конце предварительных действий
- чтобы наши тесты были эффективнее
- Тестировали бы что-то типа соцсети и если бы предварительные действия были
- реализованы через UI - да, после предварительных действий было бы разумно
- выполнить проверку (проверка после предварительных действий нам позволяет отличить -
- ошибка возникла на этапе выполнения тестируемого действия, или все же раньше)
- */
- ******************************************************************************
- 2. Во второй версии не ясно выполнение в методе given - given(tasks);
- Подразумевалась перегрузка методов ?
- Два метода с одинаковым названием принимающих разные аргументы ?.
- /*
- да, именно это подразумевалось, все верно
- */
- @Step
- public void given(String... tasks) {
- /*
- во втором варианте реализации, что я тебе привела в качестве примера -
- такой метод оперировал параметром Tasks... tasks
- это важно
- т к позволяет создать несколько тасок - в разном состоянии
- например - активную a, закомпличеную b
- в некоторых тест-методах это будет важно
- такая реализация - самая универсальная
- именно в самом универсальном варианте - и стоит реализовать сам алгоритм
- а далее - уже реализуем вариант given(TaskType taskType, String... taskTexts)
- который как раз будет использовать наш универсальный вариант - given(Tasks... tasks)
- такой подход - когда реализуешь алгоритм в самом универсальном варианте
- и затем реализуешь методы с другим набором параметров - для других нужных вариантов вызова метода -
- и в этих вариантах - переиспользуй первый универсальный вариант
- так получишь DRY реализацию
- один раз - реализовали алгоритм
- и далее - реализовали набор методов, которые удобно вызывать в разных случаях
- given(new Task(ACTIVE, "a"), new Task(COMPLETED, "b")) - вариант для создания тасок в разных статусах
- given(new Task(ACTIVE, "a"), new Task(ACTIVE, "b")) - а для такого варианта - слишком длинно
- given(ACTIVE, "a", "b")) - так то же самое получится лаконичнее и нагляднее
- */
- ***********************************************************************************
- 3. И еще не ясно на каком этапе мы указываем состояние таски
- Сюда мы передаем (“ACTIVE”, “name”)
- public void given(TaskType taskType, String... taskTexts) {
- далее создаем масив размером [taskTexts.length]
- далее для каждой таски в массиве мы создаем новый объект с атрибутами тип и имя
- а далее мы вызывем пердыдущую весию given метода который принимает только имя таски потом передает
- в prepareGivenCommand которій в свою очередь склеивает строку
- такое впечатление что во второй версии given мы еще используем первую версию (без статуса таски).
- Может оно и DRY но что-то мне никак не KISS
- Может у тебя есть более доступная для понимания версия там где
- given принимает два аргумена given(TaskType taskType, String... taskTexts)
- далее их передает в prepareGivenCommand (TaskType taskType, String... taskTexts) который потом уже возвращает строку
- /*
- в коде тест-методов - очень важно быть KISS
- а вот в реализации вспомогательных методов - уже важнее быть DRY )
- тут важно не реализовывать один и тот же алгоритм в нескольких вариантах
- подумай - как это поддерживать
- представь - реализовали 2-3 варианта одного алгоритма
- и надо переделать что-то
- это что-то - придется переделать трижды
- а это - уже источник проблем - в одном месте исправили, в другом - нет
- ну или - в одном месте исправили правильно, в другом - не правильно
- так что советую - остаться именно в DRY реализации
- это критично, и это я требую в задании
- по поводу примера - я такого примера не буду давать
- думаю, примеров уже достаточно
- тем более, что не нужно двух реализаций одного алгоритма в двух методах prepareGivenCommand
- с разным набором параметров
- я напишу это - немного на будущее
- лично для себя я держу такую грань
- то что юзаю в тест-методах - должно быть более KISS
- а вот сама реализация пейджей/виджетов/хелперов/кондишенов - тут уже просто правила разработки ПО применяю
- DRY - тут уже важно )
- т е - снаружи все эти пейджи/виджеты/хелперы/кондишены = то что видно при использовании этого всего
- должно конечно обеспечивать KISS
- а вот внутри - там где мы алгоритмы реализуем, какую-то сравнительно серьезную логику - там уже значимость DRY - гораздо выше
- если это пока не очень понятно - то скоро станет понятнее)
- */
- ************************
- 4. Не понял зачем нам два метода
- Если мы передаем состояние и имя то нам нужен 2й..а зачем 1й?
- @Step
- public void givenAtActive(Task... tasks) {
- given(tasks);
- filterActive();
- }
- @Step
- public void givenAtActive(TaskType taskType, String... taskTexts) {
- given(taskType, taskTexts);
- filterActive();
- }
- /*
- я выше написала про это
- given(new Task(ACTIVE, "a"), new Task(ACTIVE, "b")) - а для такого варианта - слишком длинно
- given(ACTIVE, "a", "b")) - так то же самое получится лаконичнее и нагляднее
- для варианта, когда нужно создать несколько тасок в одном статусе - гораздо нагляднее будет вызов метода
- givenAtActive(TaskType taskType, String... taskTexts)
- ну и - почему мы создаем для каждого фильтра гивены
- чтоб в тест-методах - предварительные действия делались - одним вызовом нужного гивен-метода
- чтоб не раздувать сами тест-методы
- максимально KISS тест-методы реализовать
- */
- ************************************************************************************
- 5. Не понял зачем нам этот класс?
- public class Task {
- String taskText;
- TaskType taskType;
- public Task(TaskType taskType, String taskText) {
- this.taskText = taskText;
- this.taskType = taskType;
- }
- }
- Чего мы тут добиваемся и почему нельзя просто создать две переменные
- String taskText;
- TaskType taskType;
- Т.е вроде понятно что класс делает-хотя он вроде ничего и не делает..но с какой целью?
- Тут если можно как для дебилов ибо все равно не понял
- /*
- а как ты передашь в метод - несколько сущностей
- у каждой из которых будет 2 свойства - и тип таски и текст таски
- я другого метода не знаю
- найдешь - покажи)
- этот класс - нужен лишь для того - чтоб мы могли оперировать несколькими такими сущностями
- для реализации метода - given(Task... tasks)
- чтоб можно было вот так работать
- given(new Task(ACTIVE, "a"), new Task(COMPLETED, "b"))
- получим - список тасок
- с несколькими тасками
- причем - у разных тасок модет быть разный тип - активный или закомпличеный
- */
- ***************************************************************************
- Раньше мы делали метод, в него передавали 2 аргумента(считай свойства), далее их использовали в методе.
- А тут как-то все пошло не так..
- /*
- боролись за новые возможности
- мы их получили благодаря этому
- и это - нам нужно
- например
- чтоб проверить переход с фильтра на фильтр
- правильно - создать несколько тасок
- в разных состояниях - одну активную, вторую - закомпличеную
- для того - чтоб фильтеринг был проверен максимально точно проверен
- мы так одним махом проверим
- как влияет переход на такой-то фильтр - и на активные таски, и на закомпличеные таски
- */
- *****************************************************************************************
- 6
- по 3 вопросу
- надо тебе почитать на такую тему - java array initialization
- https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
- http://javadevnotes.com/java-initialize-array-examples
- https://docs.oracle.com/javase/specs/jls/se8/html/jls-10.html#jls-10.6
- http://stackoverflow.com/questions/1938101/how-to-initialize-an-array-in-java
- @Step
- public void given(TaskType taskType, String... taskTexts) {
- Task[] tasks = new Task[taskTexts.length];
- Подскажи, зачем мы тут указываем length (откуда эта length вообще берется?
- Это метод java доступный для любого текста?)а не просто
- Task[] tasks = new Task[taskTexts] –так было бы понятно
- Task[] tasks = new Task[taskTexts.length]; - так нет
- /*
- при инициализации массива - нам нужно передать в качестве параметра - количество элементов этого массива
- количество элементов должно быть = количеству переданных строк в качестве значения параметра - String... taskTexts
- http://www.java-tips.org/java-se-tips-100019/24-java-lang/481-using-the-varargs-language-feature.html
- At compile time a vararg is converted to an array.
- что это значит - At compile time a vararg is converted to an array.
- это значит - что с параметром taskTexts мы можем работать как с массивом
- taskTexts.length = количество элементов массива
- почитай про массивы в Java
- */
- Я ссылки прочитал.. и там в целом как в javarush описывается как поместить значение в массив.
- Т.е. будь там число описывающее размер массива- не было бы вопросов..ни или набор текстов
- (int[] testArray = new int[10];
- Это понятно
- int[] testArray1 = {1, 2, 3, 4, 5};
- и это понятно
- /*
- мы как раз что-то аналогичное int[] testArray = new int[10] сделали
- инициализировали массив такого-то размера
- */
- Если taskTexts.length это переменная ( а судя по всему так и есть)- то почему она нигде не определена?
- Т.е еще раз вопрос откуда берется именно length ?
- /*
- гугли array java
- вот например доходчиво описано
- http://developer.alexanderklimov.ru/android/java/array.php
- */
- **********************************************************************************************************
- 7 Тут https://tasj.slack.com/files/julia.v.iluhina/F3RS60NR3/-.txt
- начиная с 38й строки это новая реализация в ней все нужно ничего лишнего?
- /*
- да, это вариант окончательной реализации гивен-методов
- точнее, почти окончательной)
- далее - еще одно в них встроим
- но это позже
- можешь использовать в своем решении - такой вариант реализации
- я далее напишу - что еще тут чуть поменяем
- буквально - 1-3 строки в одном методе
- а так - да, тут уже все ок
- конечно, есть и другие варианты
- но они сложнее в реализации
- это = нормальный не сложный окончательный вариант гивен-методов
- можно чуть оптимизировать количество гивен-методов
- это уже такая, оптимизационная работа
- делать ее или нет - решать тебе
- */
- /*
- Тут приведу тебе рекомендации Якова для другого студента - про набор методов given
- ***
- но я вот подумал бы об этих методах givenAtAll дополнительных...
- я бы наверное оставил
- given(Tasks...)
- given(String...)
- given() // вот этот может стоит таки переименовать в givenAtAll
- // потому как без префикса звучит не однозначно
- givenAtActive(Tasks...)
- givenAtActive(String...)
- givenAtActive()
- givenAtCompleted(Tasks...)
- это был бы самый экономный вариант по количеству методов...
- и все еще достаточно гибкий и при этом понятный...
- */
- /*
- Лично мне нравится набор вот такой
- given(Tasks...)
- givenAtActive(Tasks...)
- givenAtCompleted(Tasks...)
- givenAtAll(Status status, String... texts)
- givenAtActive(Status status, String... texts)
- givenAtCompleted(Status status, String... texts)
- мне кажется - так универсальнее, и однозначнее
- для каждого фильтра - по 2 метода
- параметры методов для каждого фильтра - одинаковы = меньше думать/помнить + больше вариантов
- вызвать в варианте given() - можно метод given(Tasks...)
- так что - все описанные варианты покрываются
- а вариант Якова - позволит лаконичнее код писать
- выбери, какие идеи тебе ближе
- */
Advertisement
Add Comment
Please, Sign In to add comment