测试将 gem 分页为 Rspec/Capybara
Testing will paginate gem with Rspec/Capybara
在我的应用程序中有一个管理部分,仅限于超级管理员(具有 属性 superadmin: true
的用户)。我有一个商店清单,我想对其进行分页和测试。
当使用 save_and_open_page
调试当前代码时,我得到一个空白页面。如果我不是以超级管理员身份登录,我将被重定向到应用程序的根目录,并且在尝试使用 save_and_open_page
进行调试时会看到根页面。如果我根本不登录,那么我将被重定向到登录页面。所以基本功能应该可以工作。
我不知道为什么它不适用于 superadmin
以及为什么我在使用 save_and_open_page
.
进行调试时看不到商店列表
这是我的spec/controllers/shops_controller_spec.rb
(基本上是从here复制的):
require 'rails_helper'
RSpec.describe Admin::ShopsController, type: :controller do
context "GET methods" do
describe "#index action" do
before(:all) {
amount = Rails.application.config.page_size
amount.times { FactoryGirl.create(:shop) }
}
before(:each) {
login_as(FactoryGirl.create(:user, superadmin: true), :scope => :user)
}
context "with entries == config.page_size" do
it "has no second page" do
get :index
expect(response).not_to have_selector("a", :href => "/shops?page=2", :content => "2")
# visit admin_shops_path
# expect(page).to have_no_xpath("//*[@class='pagination']//a[text()='2']")
end
end
context "with entries > config.page_size" do
before { FactoryGirl.create(:shop) }
it "has a second page with too many entries" do
visit "/admin/shops"
save_and_open_page
expect(page).to have_xpath("//*[@class='pagination']//a[text()='2']")
end
it "correctly redirects to next page" do
visit admin_shops_path
find("//*[@class='pagination']//a[text()='2']").click
expect(page.status_code).to eq(200)
end
end
end
end
end
如您所见,我尝试以不同的方式进行测试("expect block" 取自 this SO-question),但其中 none 有效。使用 get :index
我收到
Admin::ShopsController GET methods #index action with entries == config.page_size has no second page
Failure/Error: expect(page).not_to have_selector("a", :href => "/shops?page=2", :content => "2")
ArgumentError:
invalid keys :href, :content, should be one of :count, :minimum, :maximum, :between, :text, :id, :class, :visible, :exact, :exact_text, :match, :wait, :filter_set
这是我的 AdminController.rb 如果有帮助的话:
class AdminController < ApplicationController
layout 'admin'
before_action :authenticate_user!, :verify_is_superadmin
before_action :set_locale
before_action :get_breadcrumbs
private
def get_breadcrumbs
splitted_url = request.original_fullpath.split("/")
# Remove first object
splitted_url.shift
result = splitted_url.map { |element| element.humanize.capitalize }
session[:breadcrumbs] = result
# debug
end
def set_locale
I18n.locale = params[:locale] || session[:locale] || I18n.default_locale
# session[:locale] = I18n.locale
end
def verify_is_superadmin
(current_user.nil?) ? redirect_to(root_path) : (redirect_to(root_path) unless current_user.superadmin?)
end
end
更新
使用 Thomas 的回答,我最终将我的代码放在 spec/features
中,现在看起来像这样:
require "rails_helper"
RSpec.feature "Widget management", :type => :feature do
before(:each) {
amount = Rails.application.config.page_size
amount.times { FactoryGirl.create(:shop) }
}
before(:each) {
login_as(FactoryGirl.create(:user, superadmin: true), :scope => :user)
}
scenario "with entries == config.page_size" do
visit admin_shops_path
#save_and_open_page
expect(page).to have_no_xpath("//*[@class='pagination']//a[text()='2']")
end
scenario "with entries > config.page_size" do
FactoryGirl.create(:shop)
visit admin_shops_path
expect(page).to have_xpath("//*[@class='pagination']//a[text()='2']")
end
scenario "with entries > config.page_size it correctly redirects to next page" do
FactoryGirl.create(:shop)
visit admin_shops_path
find("//*[@class='pagination']//a[text()='2']").click
expect(page.status_code).to eq(200)
end
end
一切正常!
你这里有很多问题。
首先,您 link 提出的另一个 SO 问题没有使用 Capybara,因此为匹配器复制其示例是错误的。
其次,您正在编写控制器测试,而不是视图测试或功能测试。默认情况下,控制器测试不会呈现页面,因此要测试页面上的元素,您可以编写视图测试或功能测试。 Capybara 专为功能测试而设计,而不是为控制器测试而设计。这就是默认 capybara/rspec
配置文件仅将 Capybara DSL 包含到类型 'feature' 的测试中的原因。它还将 Capybara RSpec 匹配器包含在视图测试中,因为它们对那里提供的渲染字符串很有用。
第三,您在同一个文件中混合使用 get/response
和 visit/page
,这只会混淆事情。
如果您将这些重写为功能测试,那么要检查您没有 link 和水豚中的特定 href,您可以这样做
expect(page).not_to have_link(href: '...')
如果您想确保 link 不存在特定文本和特定 href
expect(page).not_to have_link('link text', href: '...')
注意:检查给定文本和给定 href 是否都没有 link,文本或 href
仍然可能有 link
在我的应用程序中有一个管理部分,仅限于超级管理员(具有 属性 superadmin: true
的用户)。我有一个商店清单,我想对其进行分页和测试。
当使用 save_and_open_page
调试当前代码时,我得到一个空白页面。如果我不是以超级管理员身份登录,我将被重定向到应用程序的根目录,并且在尝试使用 save_and_open_page
进行调试时会看到根页面。如果我根本不登录,那么我将被重定向到登录页面。所以基本功能应该可以工作。
我不知道为什么它不适用于 superadmin
以及为什么我在使用 save_and_open_page
.
这是我的spec/controllers/shops_controller_spec.rb
(基本上是从here复制的):
require 'rails_helper'
RSpec.describe Admin::ShopsController, type: :controller do
context "GET methods" do
describe "#index action" do
before(:all) {
amount = Rails.application.config.page_size
amount.times { FactoryGirl.create(:shop) }
}
before(:each) {
login_as(FactoryGirl.create(:user, superadmin: true), :scope => :user)
}
context "with entries == config.page_size" do
it "has no second page" do
get :index
expect(response).not_to have_selector("a", :href => "/shops?page=2", :content => "2")
# visit admin_shops_path
# expect(page).to have_no_xpath("//*[@class='pagination']//a[text()='2']")
end
end
context "with entries > config.page_size" do
before { FactoryGirl.create(:shop) }
it "has a second page with too many entries" do
visit "/admin/shops"
save_and_open_page
expect(page).to have_xpath("//*[@class='pagination']//a[text()='2']")
end
it "correctly redirects to next page" do
visit admin_shops_path
find("//*[@class='pagination']//a[text()='2']").click
expect(page.status_code).to eq(200)
end
end
end
end
end
如您所见,我尝试以不同的方式进行测试("expect block" 取自 this SO-question),但其中 none 有效。使用 get :index
我收到
Admin::ShopsController GET methods #index action with entries == config.page_size has no second page
Failure/Error: expect(page).not_to have_selector("a", :href => "/shops?page=2", :content => "2")
ArgumentError:
invalid keys :href, :content, should be one of :count, :minimum, :maximum, :between, :text, :id, :class, :visible, :exact, :exact_text, :match, :wait, :filter_set
这是我的 AdminController.rb 如果有帮助的话:
class AdminController < ApplicationController
layout 'admin'
before_action :authenticate_user!, :verify_is_superadmin
before_action :set_locale
before_action :get_breadcrumbs
private
def get_breadcrumbs
splitted_url = request.original_fullpath.split("/")
# Remove first object
splitted_url.shift
result = splitted_url.map { |element| element.humanize.capitalize }
session[:breadcrumbs] = result
# debug
end
def set_locale
I18n.locale = params[:locale] || session[:locale] || I18n.default_locale
# session[:locale] = I18n.locale
end
def verify_is_superadmin
(current_user.nil?) ? redirect_to(root_path) : (redirect_to(root_path) unless current_user.superadmin?)
end
end
更新
使用 Thomas 的回答,我最终将我的代码放在 spec/features
中,现在看起来像这样:
require "rails_helper"
RSpec.feature "Widget management", :type => :feature do
before(:each) {
amount = Rails.application.config.page_size
amount.times { FactoryGirl.create(:shop) }
}
before(:each) {
login_as(FactoryGirl.create(:user, superadmin: true), :scope => :user)
}
scenario "with entries == config.page_size" do
visit admin_shops_path
#save_and_open_page
expect(page).to have_no_xpath("//*[@class='pagination']//a[text()='2']")
end
scenario "with entries > config.page_size" do
FactoryGirl.create(:shop)
visit admin_shops_path
expect(page).to have_xpath("//*[@class='pagination']//a[text()='2']")
end
scenario "with entries > config.page_size it correctly redirects to next page" do
FactoryGirl.create(:shop)
visit admin_shops_path
find("//*[@class='pagination']//a[text()='2']").click
expect(page.status_code).to eq(200)
end
end
一切正常!
你这里有很多问题。
首先,您 link 提出的另一个 SO 问题没有使用 Capybara,因此为匹配器复制其示例是错误的。
其次,您正在编写控制器测试,而不是视图测试或功能测试。默认情况下,控制器测试不会呈现页面,因此要测试页面上的元素,您可以编写视图测试或功能测试。 Capybara 专为功能测试而设计,而不是为控制器测试而设计。这就是默认 capybara/rspec
配置文件仅将 Capybara DSL 包含到类型 'feature' 的测试中的原因。它还将 Capybara RSpec 匹配器包含在视图测试中,因为它们对那里提供的渲染字符串很有用。
第三,您在同一个文件中混合使用 get/response
和 visit/page
,这只会混淆事情。
如果您将这些重写为功能测试,那么要检查您没有 link 和水豚中的特定 href,您可以这样做
expect(page).not_to have_link(href: '...')
如果您想确保 link 不存在特定文本和特定 href
expect(page).not_to have_link('link text', href: '...')
注意:检查给定文本和给定 href 是否都没有 link,文本或 href
仍然可能有 link