Здравствуйте.
У меня возник спор с коллегой на счет того, каким образом делать открытие пунктов меню.
Я все пункты вывел в константы, пусть не сразу поймешь в тесте, что это константа означает (на англ иногда сложно перевести эти пункты), иногда они имеют длинные имена, но можно ведь перейти и прочитать что она означает, зато мы уверены что не посадили ошибку, не используя стринг напрямую.
Он же говорит, что константы не дают наглядности, что это лишнее звено и что пункты надо копировать каждый раз из браузера.
Вот я не могу понять… Неужели его предложение логичное?
Использование констант более чем оправдано, и не только потому что это удобно и нельзя сделать ошибку, а еще и с точки зрения поддержки. При изменении текста необходимо будет заменить только один фрагмент кода и не искать по всему проекту данные. Решение в этом случае - делайте имена констант более длинными и содержательными, если начальству не нравятся короткие и немногословные.
Константы - это правильное решение. Более того, я бы предложил ещё 1 уровень абстракции: сгруппировать все эти константы в property файл.
Из плюсов - не будет требоваться менять код тестов, если изменится какое-либо название в менюшках. Кроме того, всегда знаешь, где нужно изменить, не надо лазить по классам и искать, в каком из них живёт данная константа.
Вы знаете, большинство ответит вам, что правильно использовать константы, да ещё и посоветуют вынести всё в файлы, эксельки, “карточки”, базу данных. Автоматизаторы любят всё усложнять.
А я думаю, что словах вашего коллеги есть рациональное зерно.
Вообще-то ответ зависит от того, в скольких местах используется это значение (например, MenuNodes.APPROVE_REQUESTS). Если оно используется в одном месте, то незачем выносить его в константу.
А если оно используется во многих местах, то есть смысл вынестив константу, потому что в будущем менять значение придётся в одном месте.
НО
если оно используется во многих местах, у меня встаёт большой вопрос, а правильно ли вообще организованы ваши тесты?
Вообще-то это не допущение, это вопрос.
Ну как, в правильно организованных тестах один и тот же элемент не должен дёргаться много раз. Ну один, ну два, ну три. А если у вас сотни тестов многократно заполняют одну и ту же форму, это же очевидная пустая трата времени! Надо избавляться от дубликации.
Так разговор ведь не о формах. Меню - это ключевой компонент любого веб приложения. И вполне логично, что многие тесты могут дергать одни и те же элементы меню для прохода по определенным участкам в совершенно разных сценариях.
У меня возникает встречный вопрос - от чего собственно тут избавляться? Приложения бывают разные, ровно как и взаимосвязи между компонентами посредством меню. И я могу с ходу привести несколько популярных кейсов, когда вариант прямой навигации куда-либо, чтобы скипнуть часть якобы “неважного” функционала, совершенно не будет работать. Так что, как говорится, depends on… Вариант с константами выглядит вполне адекватным, как по мне.
Ну конечно it depends.
Поэтому это и был просто вопрос. Но вопрос очень даже оправданный, потому что очень часто в тестах делается много лишних шагов , повторений и т.д. Это ж прям беда индустрии!
Использую константы в своих тестах, очень удобный подход, пишу как-то так (небольшая часть):
public class Constants {
public static final String BASE_DIRECTORY = System.getProperty("user.dir");
public static final String DS = System.getProperty("file.separator");
public static final String MAIN_RESOURCES = BASE_DIRECTORY + DS + "src" + DS + "main" + DS + "resources";
public static final String TEST_RESOURCES = BASE_DIRECTORY + DS + "src" + DS + "test" + DS + "resources";
public static final String DIRECTORY_TEST_FILE = TEST_RESOURCES + DS + "files" + DS;
public static class Settings {
public static final String LOGS_DIRECTORY = BASE_DIRECTORY + DS + "logs" + DS;
public static final String SCREENSHOT_DIRECTORY = BASE_DIRECTORY + DS + "screenshots";
public static final String DEFAULT_DATE_FORMAT = "MMM dd, yyyy - hh:mm:ss a";
public static class TestService {
public static final String TEST_MAIL_SERVICE = "@mailinator.com";
}
}
public static class Url {
public static final String BASE_URL = SystemProperty.BASE_URL.getValue();
public static final String CP_BASE_URL = SystemProperty.CP_BASE_URL.getValue();
public static final String DEMO_BASE_URL = SystemProperty.DEMO_BASE_URL.getValue();
}
public static class TestData {
public static class Email {
public static final String QA_EMAIL = "qa@foobar.com";
public static final String JENKINS_EMAIL = "jenkins@foobar.com";
public static final String DEBUG_EMAIL = "debug@foobar.com";
}
}
}
а вызываю как-то так:
Constants.TestData.Email.JENKINS_EMAIL
вроде наглядно в тестах получается, как по мне… Поэтому думаю, что для пунктов меню очень даже оправдано и даже для тестовых карточек, которые не меняются и используются в разных тестах…
Использую так, потому что мне это удобно… Если бы было неудобно, то я бы писал отдельную стрингу в каждом тесте. Для того, чтобы это еще было и читаемо, закидываю в разные подклассы и получаются записи такого вида:
Вы меня простите, но это тихий ужас. Ведь это можно гораздо короче написать.
Я ещё понимаю, что QA_EMAIL выделено в константу. Это ок.
Но все эти заморочки в путями…
Как минимум синтаксис можно укоротить:
public class Constants {
public static final String BASE_DIRECTORY = System.getProperty("user.dir");
public static final String MAIN_RESOURCES = "src/main/resources";
public static final String TEST_RESOURCES = "src/test/resources";
public static final String DIRECTORY_TEST_FILE = "src/test/resources/files";
public static class Settings {
public static final String LOGS_DIRECTORY = "logs";
public static final String SCREENSHOT_DIRECTORY = "screenshots";
}
И будет точно так же работать!
Но это не самое главное. Важнее вопрос - зачем вам вообще эти константы? Зачем, скажем, путь к src/test/resources? Все эти файлы будут доступны через classpath.
Дальше, зачем вам константа DEFAULT_DATE_FORMAT?
Все места в коде, которые её используют, будут совершенно одинаковыми. Они все делают new SimpleDateFormat(DEFAULT_DATE_FORMAT) и либо парсят, либо форматируют дату. Так? Значит, надо константу сделать приватной, и добавить пару публичных методов для парсинга/форматирования даты.
да это кусок из старого примерчика, что под рукой оказалось на личном компе
для путей вы правы, полностью с вами соглашусь, и недавно уже даже переделал, как вы выше написали, и их уже нет в константах
для “DEFAULT_DATE_FORMAT” у меня во всех проектах везде один формат даты выводится (так сложилось), и я сделал два метода в котором указал стандартный и перегрузил метод для того, чтобы указать кастомный… Не знаю, удобно мне так зайти в константы и заменить там дефолтную дату, оно поменяет везде, если в проекте изменится, нежели идти в метод с датой. Так удобней мне, я думал об этом ранее
вроде как есть логика в ваших словах, но когда проект расширяется и над ним начинают работать больше одного человека, и приходят новые, то наверное проще зайти в константы и там подсмотреть или поменять