下面的故事展示了使用 Ember+Rails 堆栈编写应用程序时冒烟测试的重要性。它涵盖了最基本的示例,即使那样事情也会出错。此外,它还展示了一个端到端测试的示例以及为冒烟测试设置环境的一些困难。最后,它提到了 exhaust ,一个可以减轻这种痛苦的库。
原作者:迈卡·伍兹 ( @mwoods79 )
想象一下,您已准备好开始编写下一个出色的应用程序。这就像 TodoMVC 遇上 Twitter 遇上 eBay:用户将写下他们的待办事项列表,并以 140 个字符或更少的字符将任务拍卖给其他用户。投资者非常兴奋。你很兴奋。全场击掌。您将改变世界,并且您将使用所有正确的技术来做到这一点:客户端的 Ember 和后端的 Rails!
这是您的第一个用户故事:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
开始使用 Ember Rails
小菜一碟!首先安装最新的 Ember:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
“我不在乎@dhh 说什么,”你大声说出来。 “我是一个摇滚明星开发者,所以我要试驾它就像我偷了它一样!”您还没有要测试的 API,所以您先模拟它。您安装
pretender
并生成您的第一个验收测试:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
是时候启动测试运行器并看着它全部燃烧了:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
是的,它像魔鬼一样红。第一个错误,没有路线。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
现在测试找不到文本“Todo List”。你也解决这个问题:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
现在测试中断,因为页面上没有待办事项。你前进:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
找不到“todo”模型。另一种修复:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
哇,是绿色的!你拍拍自己的背。但是,除非有一个 API 来支持它,否则您无法真正交付故事。是时候获取最新版本的 Rails 了。
测试 Ember Rails 应用程序
这将是一个 API 而不是一个成熟的应用程序,因此您只需要几个 gem。您花了几分钟思考
刚刚阅读的关于构建 Rails API 应用程序的帖子
,并决定是否使用 Rails 5
--api
标志。但是,您希望该产品在“昨天”投放市场,因此您只需使用稳定的产品即可:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
您还跳过了
test-unit
因为您更愿意使用 Rspec 雄辩的 DSL 来进行该项目的测试。
是时候将 Gemfile 压缩为您真正需要的几个 gem 了。这个 API 只需要为 JSON 提供服务,所以与资产管道相关的任何东西:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
捆绑它并准备编写一些规范!
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
是时候制定第一个请求规范了:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
你运行测试。看着它变红!第一个抱怨:没有模型。你解决这个问题:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
现在是迁移时间!
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
当然,它需要一条路线。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
测试仍然是红色的,因为没有控制器。下一步修复:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
全绿!是时候启动应用程序并沉浸在您自己的创意天才中了。您在不同的终端中运行以下命令:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
您迫不及待地想看到您的宝宝奔跑。你打开“http://local:4200/todos”……你会看到一个空白屏幕。现在这令人失望。两个测试套件都是绿色的。可能出了什么问题?
在对问题进行一些检查后,您注意到日志中
GET http://localhost:4200/todos 404 (Not Found)
。好吧,废话。 Ember 不知道 API 位于不同的域中。好吧,这很容易解决。您只需要在应用程序适配器中指定一个主机。而且由于您既有魅力又聪明,您知道最好不要对主机进行硬编码。毕竟,它会因演出和制作而改变。因此,您在 Ember 应用程序中打开
config/environment.js
,并添加以下内容:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
您将测试环境的 API_HOST 设置为空字符串,以便当前测试继续运行。除非设置了
API_HOST
环境变量,否则所有其他环境都使用 Rails 的默认
http://localhost:3000
。现在您可以创建一个应用程序适配器并修复错误:
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
W00T!解决了那个问题。是时候运行测试了。再一次,您在两个不同的终端中启动 Rails 和 Ember 应用程序。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
该死的。该应用程序仍然无法运行。您没有设置 CORS,以便现代浏览器可以与 Rails API 对话。您将 rack-cors 添加到 Gemfile 中,将其捆绑,然后添加您能想到的最简单的策略来让事情正常进行。允许一切!
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
你交叉手指,运行测试,然后启动服务器。当您访问
todos
路线时,您会看到您的应用正在运行。呸!即使您的应用程序现在可以正常运行,您也不会 100% 满意。您在最后一个小时内测试了一个无法运行的应用程序,即使所有测试都是绿色的。而且你甚至没有关注单元测试——你所有的测试都是集成测试。集成测试不应该防止这样的事情发生吗?
为 Ember Rails 应用编写冒烟测试
此时,您记得 Hashrocket 博客上的一篇关于 使用 cucumber 测试驱动 elixir 应用程序的 帖子。您决定在实践中尝试这些技术并编写一些冒烟测试。刚刚编写的集成测试类型非常适合单独测试应用程序。这些孤立的集成测试运行得非常快。因为它们运行速度很快,所以您的大部分测试应该是请求规范或 Ember 集成。没有理由用冒烟测试来全面覆盖(测试每一种可能性)。
但是,为了确保应用程序实际运行,每个 API 端点至少应该进行一次冒烟测试。知道 cucumber-rails 已经加载了您的测试环境,您想到了最简单的解决方案来尝试编写冒烟测试。只需添加 cucumber-rails,手动启动 Ember 和 Rails,然后覆盖 capybara 的工作方式。这是您提出的解决方案。您将黄瓜添加到 Gemfile 并安装它。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
然后你覆盖水豚的行为。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
然后您编写第一个功能和步骤定义。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
现在,您可以在不同的终端中同时运行 Rails 和 Ember。这次 Rails 在测试环境中启动,以便 Ember 请求命中 Rails 测试数据库。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
你用
rake
运行测试套件,瞧!您会看到测试套件通过了。您知道 Ember 和 Rails 都在进行端到端通信。即使你为自己感到超级自豪,你也不快乐。 “服务器应该自动启动。为什么我不能只输入
rake
?你自己想想。这是您提出的第一个解决方案。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
这个解决方案工作正常。 Rails 和 Ember 在不同的端口上运行,因此两个服务器的开发版本可以保持运行。唯一的问题是
sleep 2
。随着 Rails 和 Ember 应用程序的增长,等待服务器启动所需的时间也会增加。另外,这个数字很神奇;在另一台机器上可能需要更长的时间。在 CI 服务器上需要多长时间?
您真正想要做的是停止测试,直到您知道 Rails 和 Ember 正在运行。然而,经过一些调查,您意识到无法知道 Ember 是否运行成功。但随后您会注意到 EmberCLI smoke 是如何自我测试的 。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
现在您知道 Ember 在输出“Build successful”时已经启动,并且对如何等待 Rails 有了一些了解。
cucumber
Given I am a user
When I go to the todos page
Then I should see a list of all todos
这不是一个完美的解决方案,但对于第一天来说已经足够了。在第二天,您可能决定将冒烟测试移动到他们自己的存储库中。毕竟,它们不是特定于 Rails 的,因此它们可能应该是一个单独的项目。
像这样的问题和许多其他问题都发生在我身上。这就是我引入 exhaust 的原因,这是一个新的 gem,有望减轻一些与冒烟测试 Ember+Rails 堆栈相关的头痛。享受!