Существуют ли какие-либо плагины Rails, которые могут генерировать модели, представления и т. Д. С использованием сценариев Cucumber?

Я планирую создать плагин, который будет генерировать код приложения на основе сценариев Cucumber, но я хочу убедиться, что не изобретаю велосипед здесь заново. Кто-нибудь знает о плагине, который работает с Cucumber и генерирует модели, контроллеры и представления?

Небольшая предыстория того, что я пытаюсь сделать, на случай, если это не имеет смысла. Когда я создаю новое приложение, вот мой рабочий процесс:

  1. Нарисуйте на моей доске 2 типа высокоуровневых дизайнов. 1, который показывает модели и взаимосвязи, а другой показывает некоторые примитивные экраны для макетов, форм и т. Д.

  2. Напишите сценарии с огурцом, основанные на дизайне высокого уровня (но более мелкомасштабном). Многие из этих шагов просто описывают то, что я увижу в конкретном представлении, а также обрисовывают ход работы приложения. Я считаю, что создавать все сценарии, которые я могу придумать, прежде чем я начну кодировать, лучше, чем делать по одному и кодировать после написания каждого сценария.

  3. Я запускаю сценарии с огурцом, смотрю на первый сбой и начинаю кодировать оттуда. Обычно перед этим шагом у меня есть дополнительная настройка, чтобы настроить мое приложение Rails в соответствии с моими предпочтениями и включить драгоценные камни, которые я знаю, что буду использовать. Я также нахожу логический порядок запуска моих файлов функций, поскольку некоторые из них зависят от других. Очевидно, начиная с таких вещей, как аутентификация.

  4. Затем я использую генераторы Rails (каркас или просто модель), чтобы помочь мне создать код, необходимый для передачи сценария. Я изменяю некоторые шаблоны генератора, чтобы получить то, что я хочу.

  5. Затем при необходимости подправляю сгенерированный код. В большинстве случаев это включает в себя настройку отношений в модели, работу с ассоциациями в представлениях и любые другие нестандартные функции, которые не могут обеспечить скаффолдинг.

  6. При необходимости я запускаю свои миграции

  7. Затем я повторно запускаю свои сценарии и повторяю все шаги из 4-6, пока сценарий не пройдет.

  8. Повторяйте шаги 4-7, пока все сценарии не пройдут.

Возможно, я ошибаюсь, но я думаю, что многие люди, вероятно, используют подобный подход. Что меня раздражает, так это то, что я вижу много дублирования между написанием сценариев и генерацией / настройкой кода. Я хочу иметь возможность генерировать скелатон моего приложения с моими сценариями огурца и использовать определения шагов, чтобы помочь мне настроить то, что сгенерировано. Вот пример:

Scenario: MODEL widget exists
  Given a widget model exists
  Then it should belong to a "manufacturer"
  And it should have a "quantity:integer" field
  And it should validate the presence of "quantity"
  And it should have many "wadgets"
  And it should accept nested attributes for "wadgets"
  #etc...

Scenario: VIEW new widget page
  Given I am on the new widgets page
  Then I should see a "quantity" field
  And I should see a "wadgets:name" nested field
  And I should see a button with text "Save Widget"

Scenario: CONTROLLER widget is created
  Given a new widget is created
  Then I should be on the widgets page

Это сгенерирует такой код:

#FROM SCENARIO 1
class Widget < ActiveRecord::Base
  has_many :wadgets
  belongs_to :manufacturer
  validates_presence_of :quantity
  accepts_nested_attributes_for :wadgets
end

#FROM SCENARIO 1      
class CreateWidget < ActiveRecord::Migration
  def self.up
    create_table :widgets do |t|
      t.integer :quantity, :null=>false
      t.integer :manufacturer_id

      t.timestamps
    end
  end

  def self.down
    drop_table :widgets
  end
end

#FROM SCENARIO 2
#new.html.haml (using formtastic helpers)
=semantic_form_for(@widget) do |f|
  = f.inputs do
    = f.input :quantity
    = f.semantic_fields_for :wadgets do |wadget|
      = location.input :name
  = f.buttons 
    =f.commit_button "Save Widget"

#FROM SCENARIO 3 (using inherited resources)
class WidgetsController < InheritedResources::Base
  def create
    create!{ widget_urls }
  end
end

На данный момент это просто псевдо, но я думаю, что было бы реальной экономией времени, если бы определить ваше приложение в сценариях Cucumber, а затем сгенерировать код на основе того, что есть в этих сценариях. Это позволит вам одновременно создавать тесты и писать код. И вам не нужно будет вводить все поля для командной строки генератора шаблонов, и он автоматически установит ассоциации и создаст соответствующие типы полей в представлении. Кроме того, это позволит вам сохранить весь дизайн функции в одном файле. Используя этот подход, вы должны сначала запустить генератор в сценарии, а затем запустить тесты огурца после генерации. Если бы он был настроен правильно, все прошло бы с первого раза, и у вас был бы довольно прочный прототип, который можно было бы настроить.

Есть ли какие-нибудь плагины, похожие на эту комбинацию тестирования и генерации?

И спасибо, если вы нашли время, чтобы прочитать это ... Я знаю, это было немного долго.


person johnmcaliley    schedule 13.12.2010    source источник
comment
Я думаю, что это довольно интересная идея, я думаю, это была бы работа для Рэйгеля.   -  person scaney    schedule 14.12.2010
comment
Вау, это крутая идея! Я не слышал ни о чем, что могло бы это сделать. Если вы продолжите реализацию своего плана, мне было бы очень интересно использовать этот плагин и, возможно, тоже внести свой вклад. Я надеюсь, что вы будете много писать об этом в блоге и, возможно, даже пингуетесь с Райаном Бейтсом, чтобы он мог сделать Railscast по этому поводу, тем самым гарантируя доступ к большей части сообщества Rails.   -  person Samo    schedule 14.12.2010
comment
@Samo - Я работаю над простым прототипом прямо сейчас, пытаюсь понять все тонкости ... и я, вероятно, напишу об этом в блоге на следующей неделе или 2. Я пришлю вам ссылку на репозиторий github после того, как я поработайте над этим и посмотрите, хотите ли вы в этом чем-то помочь. Спасибо!   -  person johnmcaliley    schedule 14.12.2010
comment
Зачем генерировать код из сценария с огурцом, если вы можете запустить сценарий прямо сейчас. Только тогда вам нужно будет протестировать сценарий ... Проблема в том, что ваши истории с огурцами не несут никакого делового значения. Вы сократили это до кода.   -  person iain    schedule 14.12.2010
comment
@iain - зачем генерировать код из сценария cuc, если вы можете запустить сценарий прямо сейчас - зачем писать код после запуска сценария, если он может сгенерировать его для вас? Это предназначено для быстрого прототипирования. Вы можете спорить, зачем тестировать сгенерированный код, но настройки после генерации могут нарушить тестовый пример, так что он вам все равно нужен. Основным преимуществом здесь является более простой DSL для генерации кода, а также создание бизнес-сценариев с тестовыми примерами.   -  person johnmcaliley    schedule 14.12.2010
comment
@iain - Проблема в том, что ваши рассказы об огурцах не имеют никакого делового значения. Вы сократили это до кода. Я согласен с тем, что пример модели немного многословен и, вероятно, мог бы быть написан на более простом DSL, но как они не передают бизнес-смысл (особенно сценарии 2 и 3)? Даже в модельном примере он по-прежнему определяет бизнес-объект и описывает его атрибуты и отношения. Деловой смысл мне довольно понятен. Описанные здесь сценарии не полностью предназначены для ваших бизнес-клиентов, но могут использоваться вместе с некоторыми из написанных ими кейсов.   -  person johnmcaliley    schedule 14.12.2010
comment
@Samo - у вас есть аккаунт на github? Я хочу поделиться с вами некоторыми идеями, если вы все еще заинтересованы в этом   -  person johnmcaliley    schedule 14.12.2010
comment
@cowboycoded: да, мой логин sslotsky. Я был бы рад услышать ваши идеи и внести свой вклад, если смогу, но предупреждаю, у меня есть дети, поэтому мое свободное время ограничено :)   -  person Samo    schedule 14.12.2010
comment
Единственная проблема в том, что при наличии кода и тестов велика вероятность обнаружения ошибок. Если вы генерируете свой код из своих тестов, то тесты ничего не проверяют.   -  person thomasfedb    schedule 15.12.2010
comment
@thomasfedb - Я согласен, что изначально он ничего не тестирует, так как сгенерированный код уже был протестирован тестами плагина. Но согласны ли вы с тем, что сначала нужно писать сценарии? Бизнес-пользователь должен определить, что он хочет видеть на страницах, прежде чем вы сможете начать писать какой-либо код. Почему бы не автоматизировать рутинный код, который вы напишете, и не сгенерировать его прямо из сценария? Это позволит вам определить, что вы хотите видеть, и написать код за один шаг ... поскольку вам нужно сначала написать сценарий, вы также можете использовать его для генерации.   -  person johnmcaliley    schedule 15.12.2010


Ответы (2)


Пару дней назад у меня возникла такая же идея. Однако, подумав еще немного, я отказался от идеи создания моделей из файлов функций. Вместо этого я играю с dsl, который генерирует модели / scaffold / resources, используя генератор rails из dsl.

После того, как я получил эту работу, я подумал о подключении генераторов для создания файлов функций на основе dsl.

У меня есть спайк, который принимает следующие данные:

application :test do
  model :survey do
    attribute :name, :string
    has_many :questions
  end
  model :question do
    has_many :options
    has_many :answers
    belongs_to :survey
    attribute :body, :string
  end
  model :option do
    belongs_to :question
    attribute :body, :string
    attribute :selector, :string

  end
  model :result do
    belongs_to :survey
    has_many :answers
  end
  model :answer do
    belongs_to :result
    belongs_to :question
    attribute :value, :string
  end
  gen
end

и распечатывает следующий вывод:

rails new test
cd test
rails generate model survey name:string 
rails generate model question survey_id:integer body:string 
rails generate model option question_id:integer body:string selector:string 
rails generate model result survey_id:integer 
rails generate model answer result_id:integer question_id:integer value:string 
Updating class: Survey
  has_many:questions
Updating class: Question
  belongs_to:survey
  has_many:options
  has_many:answers
Updating class: Option
  belongs_to:question
Updating class: Result
  belongs_to:survey
  has_many:answers
Updating class: Answer
  belongs_to:result
  belongs_to:question

Стив

person Steve Pallen    schedule 22.11.2012

Я думаю, что вы использовали здесь огурец не так, как предполагалось.

Я предполагаю, что все мы согласны с тем, что функции огурца должны описывать определенные функции, которые хочет видеть заказчик - они в основном переводят карточки историй (требования) в выполняемые тесты. Эти истории не должны касаться реализации ваших моделей, контроллеров и представлений. Он должен проверять такие вещи, как «когда я нажимаю кнопку X, я должен быть переведен на страницу Y, и моя заявка должна быть одобрена». Это всего лишь один большой интеграционный тест, моделирующий взаимодействие между пользователем и вашим сайтом. В вашем примере вы ищете определенные поля на странице, которые можно неявно проверить, сказав «когда я заполняю поле количества цифрой 5».

Для тестирования поведения моделей и того, как они взаимодействуют с бизнес-логикой, лучше использовать RSpec или Test :: Unit - гораздо проще писать тесты и делать имитацию / заглушку. Я уверен, что есть плагины, которые генерируют тесты RSpec для каждого поля / отношения в вашей модели. Генераторы rspec-rails уже делают большую часть работы за вас, например rails generate rspec:scaffold Post

Я думаю, что лучшим улучшением для огурцов-рельсов было бы оставить тестирование модели и контроллера для RSpec, но затем иметь возможность генерировать стандартные действия CRUD для данного ресурса с сгенерированными функциями огурца, например: «Пользователь должен иметь возможность создавать X . "

person dkastner    schedule 21.12.2010
comment
Мне нравится ваш ответ, такого плагина нет, и, по-видимому, это не лучшая идея, тестирование основных функций рельсов должно появляться только тогда, когда это действительно важно, например, в некоторых особых случаях. Написание тестов для каждой базовой части приложения означало бы много усилий, которые бесполезны - создают больше проблем, чем решают. Написание таких тестов будет повторять код из моделей / контроллеров / представлений, другими словами, любое изменение в одном вызовет изменения во втором, дублированном или даже утроенном усилии. - person mpapis; 21.12.2010