代码之家  ›  专栏  ›  技术社区  ›  Steven

如何测试权限管理的Rails应用程序?

  •  0
  • Steven  · 技术社区  · 14 年前

    我正在开发一个Rails应用程序,它要求您登录才能看到几乎所有的东西。对于单元测试,这不是问题,因为它们直接与模型交互。对于集成测试,这不是一个大问题,因为我可以让适当的用户通过Rails登录 post 方法。似乎将所有对权限敏感的测试放在集成测试中是有意义的(例如,测试用户不能编辑其他人的评论)。

    但是,我在处理功能测试时遇到了问题。对我来说,测试不依赖于用户状态(而不是作为网关的能力)的独立于用户权限的功能似乎是有意义的。现在,我想不出一个好方法来实现这一点,因为所有请求都会将测试客户机跳转到登录页。

    我尝试过的一个不雅观的解决方案是将这个登录请求放在 setup 方法,但Rails测试人员试图访问一个操作,而不是路径。特别是,我

    def setup
      post /sessions/create, {:username => 'testdbadmin', :password => 'password}
    end
    

    但是根据日志,它只是试图访问SomeController#/sessions/create,这显然不是它的意图。

    2 回复  |  直到 14 年前
        1
  •  4
  •   Chris Heald    14 年前

    在功能测试中,我只需在设置中设置有效的登录会话数据,就可以有效地模拟一个用户已经通过身份验证(或者还没有通过身份验证,视情况而定)的请求。

    我的test\u helper.rb中有一个助手方法:

    def login(typ = :user, options = {})
        user = Factory.create(typ, {:username => "Joe"}.merge(options))
        session["user_id"] = user.id.to_s
      end
    

    然后在我的功能测试中:

    class AccountsControllerTest < ActionController::TestCase
      context "Fresh session" do
        setup do
          @user = Factory.create(:user)
        end
    
        should "be redirected to the login page if not logged in" do
          get :show
          assert_redirected_to login_path
        end
    
      context "Logged in user with profile" do
        setup do
          @user = login
        end
    
        should "get the account home page" do
          get :show
          assert_response :success
        end
      end
    end
    
        2
  •  1
  •   Ryan Bigg Andrés Bonilla    14 年前

    与其在功能测试中测试所有这些,我将结合使用功能测试和Cucumber特性。您希望在用户登录时测试这一点,以便他们能够访问应用程序的各个部分。这就是黄瓜的特点。然后,您需要测试当用户未登录时,他们无法访问这些部分。这是功能测试。

    我会这样写黄瓜特写:

    Feature: Viewing accounts
      In order to update my account information
      As a user
      I want to access my profile page
    
      Background:
        Given a user exists:
          | login | password      |
          | Radar | superpassword |
        And I am logged in as them
    
      Scenario: My profile page
        When I follow "Account"
        Then I should see "Profile Information"
    

    “我以他们的身份登录”步骤实际上并没有设置会话,而是实际经历了登录用户的过程。我会这样写这两个背景步骤:

    Given /^a user exists:$/ do |table|
      table.hashes.each do |user|
        @user = User.create!(user)
      end
    end
    
    
    Given /^I am logged in as them$/ do 
      steps(%Q{
        Given I am on the homepage
        And I follow "Login"
        And I fill in "Login" with "#{@user.login}"
        And I fill in "Password" with "#{@user.password}"
        And I press "Login"
        Then I should see "Login successful."
      })
    end
    


    现在是功能测试。我是RSpec类型的人,所以我会这样写。

    require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
    
    describe AccountsController do
    
      context "not logged in users" do
        it "cannot access the profile action" do
          get :profile
          flash[:alert].should eql("You must be logged in to access that action.")
          response.should redirect_to(login_path)
        end
      end
    end
    

    这个 before_filter 此功能测试将测试检查用户是否已登录的。因为这是一个 private 方法(这是一个 私有的 过滤器前 flash[:alert] 并重定向到 login_path .