Ruby on rails 有人知道全套Desive Rspec/Capybara测试吗

Ruby on rails 有人知道全套Desive Rspec/Capybara测试吗,ruby-on-rails,testing,rspec,devise,suite,Ruby On Rails,Testing,Rspec,Devise,Suite,我一直在用Desive学习Rails 3,到目前为止,它似乎运行得很好。我有自定义会话和注册控制器,recaptcha正在工作,一个登录用户可以通过carrierwave上传一个头像,该头像保存在S3上。对我的进步很满意 现在我正在编写Rspec测试。不太顺利!我有一个合理的用户模型测试,但那是因为我在网上找到的(https://github.com/RailsApps/rails3-devise-rspec-cucumber/)并且能够通过遵循Michael Hartl的优秀“Ruby on

我一直在用Desive学习Rails 3,到目前为止,它似乎运行得很好。我有自定义会话和注册控制器,recaptcha正在工作,一个登录用户可以通过carrierwave上传一个头像,该头像保存在S3上。对我的进步很满意

现在我正在编写Rspec测试。不太顺利!我有一个合理的用户模型测试,但那是因为我在网上找到的(https://github.com/RailsApps/rails3-devise-rspec-cucumber/)并且能够通过遵循Michael Hartl的优秀“Ruby on Rails 3教程”来增加它

我真正的问题是控制器测试和集成测试,尤其是控制器测试。起初,我以为我能够转换Michael书中的测试,我必须要有一个小的程度,但进展缓慢,我似乎不断地把头撞到砖墙上——我想,部分原因是我对Rspec和水豚不太了解(犯了一些非常愚蠢的错误)但也因为我对Deave的理解还不够透彻,我想知道Deave是否能像Rspec那样发挥出色的作用;我在某个地方读到,因为Desive是基于机架的,所以它可能并不总是像Rspec预期的那样工作。不知道这是不是真的

我知道有些人会想为什么这可能是必要的,因为Desive是一个宝石,因此已经测试过了,但我有几个例子,其他地方的更改破坏了登录或注册,而我没有立即意识到。我认为一套好的控制器和集成测试可以解决这个问题

如果我自己能够做到这一点,我会并且我会为其他人发布它,但是,到目前为止,编写这些测试非常痛苦,我真的需要继续做其他事情

我肯定我不是唯一一个可以用这个的人。有人知道这样一套测试吗

作为对杰西善意帮助的回应…

这是我的注册\u控制器\u规范。“应该呈现‘编辑’页面”中的注释显示了我正在努力解决的问题。此外,“应该创建用户”还有一些我尝试过但无法测试的东西:

require File.dirname(__FILE__) + '/../spec_helper'

describe Users::RegistrationsController do
  include Devise::TestHelpers
  fixtures :all
  render_views

  before(:each) do
    @request.env["devise.mapping"] = Devise.mappings[:user]
  end

  describe "POST 'create'" do
    describe "failure" do
      before(:each) do
        @attr = { :email => "", :password => "",
                  :password_confirmation => "", :display_name => "" }
      end

      it "should not create a user" do
        lambda do
          post :create, :user_registration => @attr
        end.should_not change(User, :count)
      end

      it "should render the 'new' page" do
        post :create, :user_registration => @attr
        response.should render_template('new')
      end
    end

    describe "success" do
      before(:each) do
        @attr = { :email => "user@example.com",
                  :password => "foobar01", :password_confirmation => "foobar01", :display_name => "New User" }
      end

      it "should create a user" do
        lambda do
          post :create, :user => @attr
          response.should redirect_to(root_path)
          #response.body.should have_selector('h1', :text => "Sample App")
          #response.should have_css('h1', :text => "Sample App")
          #flash[:success].should == "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
          #response.should have_content "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
        end.should change(User, :count).by(1)
      end

    end

  end

  describe "PUT 'update'" do
    before(:each) do
      @user = FactoryGirl.create(:user)
      @user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the confirmable module
      sign_in @user
    end

    describe "Failure" do

      before(:each) do
        # The following information is valid except for display_name which is too long (max 20 characters)
        @attr = { :email => @user.email, :display_name => "Test", :current_password => @user.password }
      end

      it "should render the 'edit' page" do
        put :update, :id => subject.current_user, :user => @attr

        # HAVE PUT THE DEBUGS THAT I'D LIKE TO GET WORKING FIRST
        # Would like to be able to debug and check I'm getting the error(s) I'm expecting
        puts subject.current_user.errors.messages # doesn't show me the errors
        # Would like to be able to debug what html is being returned:
        puts page.html # only return the first line of html

        # Would like to be able to determine that this test is failing for the right reasons
        response.should have_content "Display name is too long (maximum is 20 characters)" # doesn't work

        response.should render_template('edit')
      end
    end

    describe "Success" do

      it "should change the user's display name" do
        @attr = { :email => @user.email, :display_name => "Test", :current_password => @user.password }
        put :update, :id => subject.current_user, :user => @attr
        subject.current_user.reload
        response.should redirect_to(root_path)
        subject.current_user.display_name == @attr[:display_name]
      end

    end
  end

  describe "authentication of edit/update pages" do

    describe "for non-signed-in users" do

      before(:each) do
        @user = FactoryGirl.create(:user)
      end

      describe "for non-signed-in users" do

        it "should deny access to 'edit'" do
          get :edit, :id => @user
          response.should redirect_to(new_user_session_path)
        end

        it "should deny access to 'update'" do
          put :update, :id => @user, :user => {}
          response.should redirect_to(new_user_session_path)
        end

      end

    end
  end

end
根据这一点,控制器测试必须是某种hibrid(单元+集成)测试。您必须在数据库中创建用户(或您的身份验证实体)的实例。相信我,嘲弄设计真的很难

试试这个:

使用Cucumber,您可以创建一个已经完成登录过程的步骤


希望能有所帮助。

好的,让这项工作顺利进行的几件事:

下面是您应该如何测试主体是否具有特定文本(您缺少.body)

response.body.should include "Display name is too long (maximum is 30 characters)"
您还可以测试@user是否有错误:

assigns[:user].errors[:display_name].should include "is too long (maximum is 30 characters)"
但是,您确实需要使名称的长度超过20/30个字符,因此我将属性更改为:

@attr = { :email => @user.email, :display_name => ("t" * 35), :current_password => @user.password }

我认为注册请求规范是测试套件中合理的一部分。为什么不创建一个注册和登录规范,然后在这里发布。我会帮助您解决任何问题。我认为您没有看到完整套件的原因是测试本身非常琐碎。我有这样一个规范,这看起来很简单工作正常。我遇到的最大问题是注册\控制器\规范(它工作正常,但没有我想要的那么好)你能帮我吗?…我很乐意发布我的注册和登录规范请求,如果它能帮助其他人的话?你是否覆盖了Desive控制器?如果不是,我会坚持使用测试整个堆栈的请求规范。如果我的术语正确,我只是继承。例如,我的注册\控制器包含到版本的代码ify recaptcha和my sessions\u controller只不过是为视图提供了一个额外的@title变量。如果您发布注册控制器的控制器规范,我将帮助诊断问题。是的,我已经尝试了您链接到的页面,尽管它有帮助,但我仍然无法按预期工作。可能是Cucumber是前进的方向!很高兴知道不只是我觉得有些设计很难。谢谢!谢谢。这真的很有帮助。