我很擅长使用RSpec进行测试,并且已经解决了这个问题。
我为用户删除了他们的帐户进行了以下测试。
require 'rails_helper'
feature 'delete account' do
let!(:user) {create :user, :basic}
scenario 'successfully' do
login_as(user)
visit dashboard_path
click_link 'Settings'
click_link 'Cancel my account'
expect(page).to have_content("Your account has been cancelled.")
end
end
运行测试时,出现以下错误;
1) delete account successfully
Failure/Error: <%= account.radio_button :plan_id, @plan.id, data: { name: @plan.name, amount: @plan.amount}, checked: true, class: 'hidden' %>
ActionView::Template::Error:
undefined method `id' for nil:NilClass
这是控制器代码。当测试点击“设置”时,将显示展示页面。问题在于没有计划,但它们与我正在测试的内容无关。
def show
@plan = Plan.find_by(name: 'Premium')
@subscription_pending_cancel =
Account.check_subscription_status(@account)
end
我可以在测试运行之前创建计划,通过测试。
before do
Plan.create(name: 'Premium')
end
然而,随着测试套件的增长,不得不创建这样的对象似乎不可持续 - 特别是在速度和保持测试数据库清洁方面。
问题是 - 是否需要为上述测试创建/持久保存一个真实对象(在我的情况下是一个计划),还是有另一种方法?
答案 0 :(得分:0)
可以在“现实”的几个层面上进行测试,每个层次都有其目的。
您已编写了一个rspec功能规范。这些属于所谓的“接受”测试类别。
RSpec文档说:
功能规范是用于执行功能切片的高级测试 通过申请。他们应该只通过外部驱动应用程序 界面,通常是网页。
这些测试的重点应该是尽可能真实,这也意味着尽可能真实地使用对象。
你的观察是正确的,有很多设置要做这些类型的测试,并且它们确实非常慢得很快。这就是为什么你通常不会写太多这些。
快速测试属于单独的类别。这些被称为“单位”测试。它们的关键是只测试一个类的方法,如果对其他类有任何依赖,你应该将它们存根。
这些是你应该有很多的测试。你应该开车以这样的方式编写这些类,以便你可以轻松地删除所有外部依赖项(例如db)。
这个概念被称为测试金字塔。 https://martinfowler.com/bliki/TestPyramid.html