Как организовать определение спецификаций в Cucumber?
Мы рассматриваем возможность использования Cucumber в нашем проекте для приемочных испытаний.
Когда мы пишем scenario
в огурце feature
мы пишем список Given
, When
а также Then
заявления.
Поскольку мы используем проект cucumber-jvm, Given
, When
а также Then
оператор связан с методами Java в (JUnit) классах.
Я хочу знать, какая организация лучше всего подходит для кода, связанного с Given
/ When
/ Then
в структуре проекта. Моей главной заботой является поддержание тестов на огурцы в большом проекте, где количество сценариев очень важно, особенно в отношении элементов, которые разделяются между функциями.
Я вижу как минимум 2 основных подхода:
Каждая функция связана с собственным классом JUnit. Так что, если у меня есть
foo/bar/baz.feature
огуречный файл, найду освобожденныйfoo.bar.Baz
Юнит класс с адекватным@Given
,@When
а также@Then
аннотированные методы.отдельный
@Given
,@When
а также@Then
методы в "тематические" классы и пакеты. Например, если в моем сценарии с огурцом у меня есть заявлениеGiven user "foo" is logged
тогда@Given("^user \"([^\"]*)\" is logged$")
Аннотированный метод будет расположен вfoo.user.User
метод класса, но потенциально,@When
метод, используемый позже в том же сценарии огурца, будет в другом классе и пакете Java (скажем,foo.car.RentCar
).
Для меня первый подход кажется хорошим, так как я могу легко установить связь между моими функциями огурца и моим Java-кодом. Но недостаток в том, что у меня может быть много избыточностей или дублирования кода. Кроме того, может быть трудно найти возможный существующий @Given
метод, чтобы избежать его воссоздания (IDE может помочь, но здесь мы используем Eclipse, и он, кажется, не дает список существующих Given
заявление?).
Другой подход кажется лучше по существу, когда у вас есть Given
условия делятся между несколькими функциями огурца, и поэтому я хочу избежать дублирования кода. Недостатком здесь является то, что может быть трудно сделать связь между @Given
Java-метод и Given
заявление огурца (может, опять же, IDE может помочь?).
Я совсем новичок в огурце, так что, возможно, мой вопрос не очень хороший, и со временем и опытом структура станет самоочевидной, но я хочу получить хорошие отзывы о его использовании...
Благодарю.
3 ответа
Я бы предложил сгруппировать ваш код в соответствии с объектами, на которые он ссылается, аналогично варианту № 2, представленному вами в вашем вопросе. Причины:
Структурирование вашего кода, основанное на том, как и где он используется, является большим нет-нет. Это на самом деле создает связь между вашими файлами функций и вашим кодом.
Представьте себе такую вещь в коде вашего продукта -SendEmail()
функция не будет в классе под названиемNewEmailScreenCommands
не так ли? Было бы вEmailActions
или что-то подобное.
То же самое относится и здесь; структурируйте свой код в соответствии с тем, что он делает, а не с тем, кто его использует.Первый подход затруднит реорганизацию ваших файлов объектов; Вам придется менять свои файлы кода каждый раз, когда вы меняете свои файлы функций.
Хранение кода, сгруппированного по темам, делает СУШКУ намного проще; вы точно знаете, где весь код, касающийся
user
сущность есть, так что вам будет проще использовать ее повторно.
В нашем проекте мы используем этот подход (т.е. BlogPostStepDefinitions
класс), с дальнейшим разделением кода, если класс становится слишком большим, по типам шагов (т.е. BlogPostGivenStepDefinitions
).
Мы также начали использовать Cucumber-JVM для приемочного тестирования и имеем похожие проблемы с организацией кода. Мы выбрали один класс определения шага для каждой функции. На данный момент это нормально, так как функции, которые мы тестируем, не очень сложны и довольно раздельны, наши функции практически не дублируются.
Мне кажется, что второй подход, который вы упомянули, был бы лучше, но часто бывает сложно связать воедино несколько разных классов определения шагов для одного сценария. Я думаю, что лучшая структура проекта станет более понятной, когда вы начнете добавлять больше функций и рефакторинг как обычно.
А пока вот плагин Eclipse для огурца,
https://github.com/matthewpietal/Eclipse-Plugin-for-Cucumber
он имеет подсветку синтаксиса, а также список существующих доступных шагов при написании функции.
Что касается текущего проекта, в котором я принимаю участие, мы задали себе тот же вопрос.
Немного поэкспериментировав с возможностями, мы выбрали сочетание предложенных вами решений.
- Сгруппируйте шаги в классы общих шагов, ориентированных на темы
- шаги запуска приложения
- шаги проверки безопасности
- [установите случайную особенность здесь] шаги
- И классы сценария (а в некоторых случаях даже особенность) конкретные шаги
Это должно было иметь в то же время группировку факторизованного кода, который довольно легко идентифицировать по его местонахождению, местонахождению и так далее. Тем не менее, это позволяет не загромождать эти общие классы чрезмерно специфичным кодом.
Проводка между всеми этими классами осуществляется пружиной (с пружиной огурца, которая отлично справляется, как только вы ее освоите).