测试 rails 页面是否正常工作的正确方法

Correct way to test if a rails page is working

作为我进入自动化测试的第一步,我想确保所有 "GET" 类型的页面都可以在浏览器中访问。我的规格还要求:

我今天的尝试要求我包括 RSpec、FactoryGirl 和 Capybara(用于检查视图)。这是一场噩梦。 Capybara 仍然无法正常工作。

这是大多数 rails 开发人员测试的方式吗?

尽管大多数 Devise 示例都使用 RSpec,但您可以使用 Minitest(内置 Ruby 测试框架)。你使用哪个完全取决于你,但我觉得用像 Ruby 这样动态的语言编写愚蠢的 Java-eske test 类 是错误的。

虽然这只是意见。

第一次设置像样的测试套件可能会很痛苦,但确实会带来长期的回报 运行。

通常我测试三个级别:

型号规格

在您的模型上测试低级功能。这比尝试设置 Web 请求来测试您的模型对不同输入的反应要快得多且容易得多。

使用 rspec-itsrspec-mongoid 测试模型的示例:

require 'rails_helper'

RSpec.describe Photo, type: :model do

  it { should validate_presence_of :flickr_uid }
  it { should belong_to_related :photoset }
  it { should belong_to :user }

  describe ".find_or_create_from_flickr" do
    subject do
      Photo.find_or_create_from_flickr(OpenStruct.new(
          id: 'ABC_123',
          title: 'foo'
      ))
    end

    its(:flickr_uid) { should eq 'ABC_123' }
    its(:title) { should eq 'foo' }
  end  
end

Feature specs

您在其中模仿访问者的行为 - 点击并在页面内容上写下期望。我用 RSpec & Capybara 写它们。我尝试至少覆盖整个应用程序的 "happy" 路径。

require 'rails_helper'

RSpec.feature "User profile management" do

  let!(:user) { create(:user) }

  background do
    login_as user
  end

  def visit_profile_page
    visit root_path
    click_link user.nickname
  end

  scenario "a user can edit his profile" do
    visit_profile_page
    click_link I18n.t('users.show.edit_profile')
    page.fill_in I18n.t('simple_form.labels.user.name'), with: 'New Name'
    click_button 'Update User'
    expect(page).to have_content 'New Name'
  end

  scenario "a user can view index" do
    visit users_path
    expect(page).to have_link user.nickname
  end
end

控制器规格

测试应用程序的 API。我通常只测试控制器:

  • returns 正确的 HTTP 代码。
  • 呈现正确的模板。
  • 授权用户,如果未授权则拒绝访问。

控制器规格示例:

require 'rails_helper'
require 'support/controller_spec_helper'

RSpec.describe UsersController, type: :controller do

  include ControllerSpecHelper

  let(:user) { create(:user) }
  before { set_current_user(nil) }
  subject { response }

  describe "GET #show" do
    before { get :show, id: user }
    it { should have_http_status :success }
    it { should render_template :show }

    it "should assign user as @user" do
      expect(assigns(:user)).to be_a User
    end
  end

  describe "GET #edit" do
    context "when unauthorized" do
      it "denies access" do
        expect {
          get :edit, id: user
        }.to raise_error(CanCan::AccessDenied)
      end
    end

    context "when authorized" do
      before do
        set_current_user(user)
        get :edit, id: user
      end
      it { should have_http_status :success }
      it { should render_template :edit }

      it "should assign user as @user" do
        expect(assigns(:user)).to be_a User
      end
    end
  end
  # ...
end