Как организовать определение спецификаций в 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
JUnit с соответствующими аннотированными методами @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 может помочь?).
Я совершенно новичок в огурце, поэтому, возможно, мой вопрос не является хорошим вопросом, и со временем и опытом структура будет очевидна, но я хочу получить хорошие отзывы о ее использовании...
Спасибо.
Ответы
Ответ 1
Я бы предложил группировать ваш код в соответствии с объектами, на которые он ссылается, подобно варианту №2, который вы представили в своем вопросе. Причины:
-
Структурирование вашего кода в зависимости от того, как и где оно используется, - это большое значение no-no. Это фактически создает связь между вашими файлами функций и вашим кодом.
Представьте себе такую вещь в вашем коде продукта - функция SendEmail()
не будет в классе с именем NewEmailScreenCommands
, не так ли? Это было бы в EmailActions
или некоторых таких.
То же самое касается и здесь; структурируйте свой код в соответствии с тем, что он делает, а не кто его использует.
-
Первый подход затруднит реорганизацию ваших файлов функций; Вам придется менять свои файлы кода всякий раз, когда вы меняете свои файлы функций.
-
Сохранение кода, сгруппированного по темам, делает DRYing намного проще; вы точно знаете, где весь код, относящийся к объекту user
, так что вам проще его повторно использовать.
В нашем проекте мы используем этот подход (класс BlogPostStepDefinitions
), с дальнейшим разделением кода, если класс становится слишком большим, к типам шагов (т.е. BlogPostGivenStepDefinitions
).
Ответ 2
Мы также начали использовать Cucumber-JVM для приемочных испытаний и имеют схожие проблемы с организацией кода. Мы решили иметь 1 этап определения класса для каждой функции. На данный момент это прекрасно, так как функции, которые мы тестируем, не очень сложны и совершенно раздельны, в наших функциях очень мало совпадений.
Второй подход, о котором вы говорили, будет лучше, я думаю, но часто сложно связать несколько разных классов определения шага для одного сценария. Я думаю, что лучшая структура проекта станет понятнее, если вы начнете добавлять дополнительные функции и рефакторинг как обычно.
Тем временем здесь есть плагин Eclipse для огурца,
https://github.com/matthewpietal/Eclipse-Plugin-for-Cucumber
у него есть подсветка синтаксиса, а также список существующих доступных шагов при записи функции.
Ответ 3
В текущем проекте, в котором я участвую, мы задали себе тот же вопрос.
После того, как мы немного поработали с возможностями, мы выбрали сочетание обоих решений, которые вы выставили.
- Устранены действия, сгруппированные по тематическим общим классам шагов
- шаги для запуска приложения
- шаги проверки безопасности
- [место случайной функции здесь] шаги
- И классы сценариев (и в некоторых случаях даже функции) конкретные шаги
Это должно было в то же время группировать факторизованный код, который довольно легко идентифицируется на нем whatabouts, whereabout и еще много чего.
Тем не менее, это позволяет не загромождать эти общие классы с чрезмерно определенным кодом.
Проводка между всеми этими классами осуществляется с помощью spring (с огурцом spring, который отлично справляется с тем, как вы его повесили).