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

Я планирую создать плагин, который будет генерировать код приложения на основе сценариев 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

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

Существуют ли плагины, похожие на этот вид тестирования и генерации?

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

Ответы [ 2 ]

3 голосов
/ 23 ноября 2012

У меня была та же идея пару дней назад. Однако, подумав еще немного, я отказался от идеи создания моделей из файлов компонентов. Вместо этого я играю с dsl, который генерирует модели / скаффолды / ресурсы, используя генератор 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

Steve

2 голосов
/ 21 декабря 2010

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

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

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

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

...