Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class TodoMVCTest extends OpenPageAndClearDataBeforeEachTest {
- TodoMVCPage tasks = new TodoMVCPage();
- Preconditions given = new Preconditions();
- /*
- класс Preconditions - ты используешь как пейдж, в общем-то
- и его можно рассматривать пейдж - как объект-контейнер вспомогательных для тестов методов
- предлагаю класс Preconditions - переименовать в PreconditionsPage
- и переместить в тот же пекедж, где пейдж
- или - пусть это будет класс-хелпер
- размести его так - src / main / java / helpers
- но - точно - с предками тест-класса - ему не место
- */
- ********************************
- public class Preconditions {
- public void givenAllActive(String... taskTexts){
- String commandToRun = "";
- for (String element : taskTexts){
- /*
- element - не самое удачное имя для текста таски
- */
- ...
- if (taskTexts.length > 1) {
- ...
- }
- /*
- тут мы запятую добавляем, если ....
- */
- }
- if (taskTexts.length > 1)
- {
- ....
- }
- /*
- и тут мы все равно обрезаем, если ....
- раз мы тут обрезаем лишнюю запятую, то может - изменив условие тут - можно избежать if-а
- внутри цикла?
- можно так улучшить
- а можно и вот так
- Реализация красивее может стать за счет использования String.join(",", ...)
- Есть об этов в прошлом ревью
- если вместо StringBuilder jsContent
- создать List<String> jsContent
- и в цикле собирать в этот список строки {...}
- то внутри цикла - можно будет вообще не заботиться о добавлении запятой
- а уже когда строку собираешь - сможешь применить String.join(",", jsContent)
- такая операция даст строку, в которой все ее элементы будут идти через запятую
- так код станет еще лаконичнее
- Настаивать на этих изменениях не буду, советую попробовать)
- https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
- http://joxi.ru/V2VBQLqf0ZW692 - фактически, вызываем второй из этих методов
- (переменную типа List<String> тут можно передать в качестве второго параметра)
- https://habrahabr.ru/post/260767/
- http://javarevisited.blogspot.com/2016/06/10-examples-of-joining-string-in-java-8.html
- */
- ******************************************
- public void givenAllCompleted(String... taskTexts){
- /*
- обрати внимание - этот метод в своей реализации - очень похож на предыдущий
- нету смысла реализовывать несколько методов, которые реализуют один и тот же алгоритм
- это не DRY
- в случае, когда мы говорим про реализацию какой-то уже не самой эелементарной логики (циклы, ветвления, ...)
- то грамотнее - реализовать ОДИН метод
- и его испоьзовать
- можно идти постепенно к цели
- в зависимости от того, насколько сложна эта задача для тебя
- если сложно
- первый шаг - реализовать метод given(boolean isCompleted, String... taskTexts)
- который сможет делать то, что уже делают твои методы
- конечно, параметр boolean isCompleted - не очень наглядно
- удобнее использовать метод с параметром типа enum - т к вызов метода - будет нагляднее
- т е - второй шаг - given(TaskType taskType, String... taskTexts)
- где - TaskType - это enum с 2-мя значениями - ACTIVE, COMPLETED
- (ниже - будет подробнее)
- следующий момент)
- не всегда нам подходит вариант - когда мы работаем с тасками в одинаковом статусе
- иногда нам будет нужно - чтобы таски в списке - были в разных статусах
- т е - с одной стороны - нам нужно добавить несколько тасок
- с другой стороны - для каждой таски нужно задать и текст, и статус
- это можно сделать - реализовав класс Task - который будет описывать таску
- и - реализовываем следующий вариант - given(Task... tasks)
- и вызов метода может быть таким
- given(new Task(COMPLETED, "a"), new Task(ACTIVE, "b"))
- чтобы получить вот такую картину
- закомпличеная таска a, и активная - b
- полезные линки
- классы
- http://www.tutorialspoint.com/java/java_object_classes.htm
- http://www.helloworld.ru/texts/comp/lang/java/java/07.htm
- внутренние классы (нас интересуют member inner classes)
- http://www.tutorialspoint.com/java/java_innerclasses.htm
- http://www.quizful.net/post/inner-classes-java
- http://www.javatpoint.com/java-inner-class
- если не сложно
- то сразу реализуй given(Task... tasks)
- */
- ******************************
- есть еще вопрос - какой тип использовать для типа таски (статуса таски)
- варианты на поверхности - boolean или String
- оба варианта имеют недостатки
- boolean
- new Task(true, "a") - это я какую таску создала?
- String
- я могу вызвать метод, передав в качестве второго параметра любую строку
- new Task("green", "a")
- эта ошибка проявится уже только в момент запуска тестов, а на этапе компиляции - мы не получим никаких сообщений -
- что что-то не так с вызовом метода
- вот для таких случаев очень хорошо подойдет использование enum
- если параметр taskStatus у нас будет типа enum TaskStatus,
- то мы только значение этого enum и сможем передать в качестве параметра
- по-другому - будут выданы сообщения об ошибке - еще на этапе разработки кода
- потому - лучший вариант для для типа таски (статуса таски) - использовать тип enum
- Кстати, для любого значения из enum - можно получать соотвествующую ему строку
- у нас задача - для каждого значения enum вернуть свою строку
- enum - это тоже класс
- у которого может быть и конструктор, и поля
- например
- */
- public enum Day {
- MONDAY("понедельник"),
- TUESDAY("вторник"),
- WEDNESDAY("среда"),
- THURSDAY("четверг"),//<<----------------------для каждого значения enum - вызов конструктора, фактически значение = объект класса
- FRIDAY("пятница"),
- SATURDAY("суббота"),
- SUNDAY("воскресенье");
- String description;//<<---------------------------поле для хранения описания дня недели
- public Day(String description) {
- this.description = description;//<<---------------------------логика конструктора - запомнить для объекта его описание
- }
- @Override
- public String toString() {
- return description;//<<---------------------------логика - вывести для объекта - то что для него заполнили
- }
- }
- /*
- все классы - потомки класса Object (enum - это тоже класс)
- у Object есть метод toString()
- который выполняет преобразование объекта к строке
- реализовав такой метод в рамках класса SomeClass -
- используя выражения типа "day is "+ Day.MONDAY
- получишь строку "day is понедельник"
- toString() - можно грамотно использовать в рамках всех вспомогательных классов и enum-ов
- это позволит упростить код
- конструкторы в enum-ах как раз и могут помочь решению задачи
- для каждого значения enum вернуть свою строку
- попробуй применить эти подходы
- вот хороший пример
- http://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html
- */
- **********************************************
- /*
- и далее - оставим реализованный алгоритм в самом универсально реализованном методе
- фактически - все остальные методы - были нужны чтоб разобраться и реализовать
- given(Task... tasks)
- а дальше - начнем реализовывать другие гивен-методы
- которые внутри себя - будут вызывать наш given(Task... tasks)
- и просто обеспечат - возможность наиболее наглядного и удобного вызова
- */
- мы реализуем полное покрытие
- и нам надо уметь в предварительных действиях - реализовывать следующие вещи (мо минимуму, самое необходимое)
- - на all
- - добавить таски с разными статусами
- - добавить таски с одним каким-то статусом
- - на active
- - добавить таски с разными статусами
- - добавить таски с active статусом
- - на completed
- - добавить таски с разными статусами
- - добавить таски с completed статусом
- */
- /*
- Тут приведу тебе рекомендации Якова для другого студента - про набор методов 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...)
- так что - все описанные варианты покрываются
- а вариант Якова - позволит лаконичнее код писать
- выбери, какие идеи тебе ближе
- */
- /*
- как переиспользовать внутри метода given(TaskType taskType, String... taskTexts)
- уже реализованный метод given(Task... tasks)
- задача - тебе внутри given(TaskType taskType, String... taskTexts)
- надо сделать то же что ты делал в given(Task... tasks)
- просто - не ясно
- как из параметров (TaskType taskType, String... taskTexts)
- получить (Task... tasks)
- вот решим эту задачу - сможешь внутри
- given....(TaskType taskType, String... taskTexts)
- написать код в одну строчку
- given(xxx(taskType, taskTexts))
- в given(Task...tasks) в качестве параметра можно передавать массив Task[] tasks
- погугли про varargs in java
- реализуй метод xxx
- возвращающий Task[]
- с параметрами (TaskType taskType, String... taskTexts)
- в котором
- объяви переменную типа Task[] и инициализируй ее как массив Task[....такого-то размера....]
- какого - посмотри на параметры нашего метода
- в цикле обойди taskTexts
- и каждый элемент массива заполни с помощью метода aTask
- верни полученный массив
- а далее - используй этот метод
- внутри given...(TaskType taskType, String... taskTexts)
- given(xxx(taskType, taskTexts))
- Если тяжело сразу xxx реализовать -
- то для начала просто внутри givenAt....
- реализуй этот код - собери массив Task[] по переданным параметрам
- И тогда будет что-то типа такого
- Task[] tasks = ....
- ....
- ....
- ....
- given(tasks)
- */
- ******************************************
- /*
- дальше - дореализуй полное покрытие
- смотри на свой тест-план
- реализуй фиче-тесты
- если хочешь (это не обязательно)
- оптимизируй его
- в чем оптимизация
- - что покрыто в е2е - не покрываем фиче-тестами
- - низкоприоритетное - покрываем единожды, на каком-то из контекстов (пример - delete by emptying text)
- - низкоприоритетные варианты фичи, у которой есть покрытые варианты - не покрываем (пример - reopen all & add)
- */
- *************************
- //можно остановиться раньше - если будет сложно
Advertisement
Add Comment
Please, Sign In to add comment