关于我想要做的事情的一点背景,如果这没有意义.当我在这里创建新应用程序时,我的工作流程是:
>在我的白板上绘制出两种类型的高级设计. 1显示模型和关系,另一个显示布局,表单等的原始屏幕.
>根据高级设计编写黄瓜场景(但更细粒度).其中许多步骤仅描述了我将在特定视图中看到的内容,并概述了应用程序的流程.我发现在开始编码之前创建我能想到的所有场景比在编写每个场景之后一次执行一个并编码更好.
>我运行黄瓜场景并查看第一次失败并从那里开始编码.在此步骤之前,我通常会进行一些额外的设置,以便根据我的偏好配置我的Rails应用程序,并包含我知道我将使用的宝石.我还找到了运行我的功能文件的逻辑顺序,因为有些文件依赖于其他文件.显然从身份验证开始.
>然后我使用Rails生成器(脚手架或只是模型)来帮助我创建传递场景所需的代码.我改变了一些生成器模板,给了我想要的东西.
>然后我根据需要调整生成的代码.大多数情况下,这涉及在模型中设置关系,使用视图中的关联以及脚手架无法提供的任何其他非标准功能.
>如有必要,我会运行迁移
>然后我重新运行我的场景并重复4-6中的任何步骤,直到场景通过.
>重复步骤4-7,直到所有方案都通过.
我可能错了,但我认为很多人可能会使用类似的方法.让我烦恼的是,我在编写场景和生成/调整代码之间看到了很多重复.我希望能够使用我的黄瓜场景生成我的应用程序的skelaton,并使用步骤定义来帮助我自定义生成的内容.这是一个例子:
- 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场景中定义应用程序然后根据这些场景中的内容生成代码将是一个真正的节省时间.这将允许您同时创建测试和编写代码.并且您不必键入scaffold生成器命令行的所有字段,它将自动设置关联并在视图中创建正确的字段类型.此外,它还允许您将整个功能设计保存在一个文件中.使用此方法,您将首先在场景中运行生成器,然后在生成后运行黄瓜测试.如果它设置正确,一切都会在第一次通过,你会有一个非常可靠的原型,你可以自定义.
谢谢你花时间阅读这篇文章..我知道它有点长.
解决方法
在我开始工作之后,我正在考虑在生成器中挂钩以基于dsl创建功能文件.
我有一个spike运行,需要以下输入:
- 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
史蒂夫