所以我想开始使用RSpec故事,但我不确定编写控制器、模型和视图规范的位置。
例如,你有一个故事"登录"的"用户提供了错误的密码"场景,你不是最终测试了与控制器/型号规格相同的东西吗(response.should render…,User.sshould be_nil,etc.)
所以我的问题是:对于那些习惯于用RoR做bdd(或story-dd)的人来说,你还写模型/控制器规范吗?如果是这样的话,你遵循的工作流程是如何的("第一个故事,然后缩小到特定的规格")?
如果你现在从故事开始(而不是有很多遗留故事),你可能想看看Cucumber,它是RSpec故事运行器的长期替代品。
在规范和故事之间进行拆分的最简单方法是使用故事对业务需求进行全栈测试,并使用规范对组件(视图、助手、控制器和模型)的隔离低级别规范进行测试。"全栈"可以是从控制器/模型/数据库到Webrat的客户端模拟,再到Watir或Selenium的浏览器内测试。
BDD的终极"内外结合"方式是从基于客户需求的故事开始,然后在实现故事时为您发现需要的组件添加规范。理想情况下,您将用规格完全覆盖各个组件,并为用户最重要的工作流程提供故事,这样您就可以在最高级别检查您的应用程序是否提供了所要求的功能。
我发现故事在测试用户实际执行或观察到的行为时很有用——因此,与其测试"失败登录"模板的呈现,不如测试响应中是否包含"登录失败"。IMHO最好是故事从不直接引用模型、视图或控制器,尽管有时如果不手动创建模型实例,很难使步骤正常工作。
在我看来,视图、控制器和型号规格只是画面的一部分。他们讲的是实现语言("控制器操作X应该对模型Z执行Y"),并测试应用程序的各个部分是否都做了正确的事情。故事通过讲述用户的语言("当我发布评论时,我应该看到我发布的评论")并测试零件是否符合客户的验收标准来完成图片。
我发现一个有用的工作流程是:
- 写一个故事场景,描述我需要添加的功能
- 尽快为这个故事编写步骤,这样你就可以运行它(即使所有步骤都失败了)
- 为这个故事所需要的东西写一个规范(模型可能是一个很好的起点)
- 编写代码使规范通过
- 编写更多的规范和代码,直到故事结束
这样,这个故事可以指导你测试什么样的规格。
编辑:这是一篇很好的文章,涉及故事和规格之间的关系。
Pat Maddox(RSpec核心团队)认为,在某些假设下,使用Cucumber故事/功能时可以跳过控制器规格
在这里阅读他的观点
如果你有Cucumber+Capybara,跳过视图规范怎么样?我倾向于发现不需要视图规范。