2012-02-01 83 views
4

我在使用Rails使Capybara工作時遇到問題。只是測試這個有趣的測試。好的,在附加的代碼中有幾個等效的測試。第一個是使用Rails附帶的shoulda-context + Test :: Unit製作的。第二個測試是用水豚和應用背景進行的。水豚問題:@request必須是ActionDispatch :: Request

require 'integration_test_helper' 

class UsersTest < ActionDispatch::IntegrationTest 
    fixtures :all 

    context "signup" do 

    context "failure" do 

     setup do 
     @attr = { :name => "", :email => "", :password => "", :password_confirmation => "" } 
     end 

     should "not make a new user" do 
     assert_no_difference 'User.count' do 
      post_via_redirect "users", :user =>@attr # enviem les dades d'un nou usuari via create (POST /users) 
      assert_template 'users/new'  # ens retorna a users/new, que significa que no s'ha creat l'usuari 
      assert_select "div#error_explanation" # comprovem que conte missatges d'error 
     end 
     end 

     should "not make a new user (capybara)" do 
     assert_no_difference 'User.count' do 
      visit '/signup' 
      fill_in 'Name', :with => @attr[:name] 
      fill_in 'Email', :with => @attr[:email] 
      fill_in 'Password', :with => @attr[:password] 
      fill_in 'Confirmation', :with => @attr[:password_confirmation] 
      click_button 'Sign Up!' 
      assert_template 'users/new'  # ens retorna a users/new, que significa que no s'ha creat l'usuari 
      assert_select "div#error_explanation" # comprovem que conte missatges d'error 
     end 
     end 
    end 
end 

雖然第一個作品確定,水豚之一拋出此錯誤消息:

================================================================================ 
Error: 
test: signup failure should not make a new user (capybara). (UsersTest): 
ArgumentError: @request must be an ActionDispatch::Request 
    test/integration/users_test.rb:30:in `block (4 levels) in <class:UsersTest>' 
    test/integration/users_test.rb:23:in `block (3 levels) in <class:UsersTest>' 
================================================================================ 

所需* integration_test_helper.rb *文件是所有suposed解決方案,我發現周圍的Googling貯液器那對我不起作用。

require 'test_helper' 
require 'capybara/rails' 
require 'database_cleaner' 

# Transactional fixtures do not work with Selenium tests, because Capybara 
# uses a separate server thread, which the transactions would be hidden 
# from. We hence use DatabaseCleaner to truncate our test database. 
DatabaseCleaner.strategy = :truncation 

class ActionDispatch::IntegrationTest 
    # Make the Capybara DSL available in all integration tests 
    include Capybara::DSL 

    # Stop ActiveRecord from wrapping tests in transactions 
    self.use_transactional_fixtures = false 

    teardown do 
    DatabaseCleaner.clean  # Truncate the database 
    Capybara.reset_sessions! # Forget the (simulated) browser state 
    Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver 
    end 
end 

有沒有人有解決辦法?我應該嘗試另一個集成frmawork如webrat嗎?

我的設置是:

[email protected]:~/Desenvolupament/Rails3Examples/ror_tutorial$ rake about 
About your application's environment 
Ruby version    1.9.2 (x86_64-linux) 
RubyGems version   1.8.15 
Rack version    1.3 
Rails version    3.1.3 
JavaScript Runtime  therubyracer (V8) 
Active Record version  3.1.3 
Action Pack version  3.1.3 
Active Resource version 3.1.3 
Action Mailer version  3.1.3 
Active Support version 3.1.3 
Middleware    ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000002b9bac0>, Rack::Runtime, Rack::MethodOverride, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, Rack::Sendfile, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport 
Application root   /mnt/dropbox/Dropbox/DESENVOLUPAMENT/Rails3Examples/ror_tutorial 
Environment    development 
Database adapter   sqlite3 
Database schema version 20120127011330 

而且

shoulda-context (1.0.0) 
capybara (1.1.2) 

感謝

回答

11

你混淆了你的測試類型,並試圖在錯誤類型的測試斷言的模板。您應該只在功能測試中斷言模板,在這些模板中,您只是直接測試控制器,而不是實際模擬用戶交互。

水豚專門用於集成測試,它基本上是從最終用戶與瀏覽器交互的角度來運行測試。在這些測試中,您不應該斷言模板,因爲最終用戶無法深入瞭解您的應用程序。你應該測試的是一個行動使你踏上正確的道路。

current_path.should == new_user_path 
page.should have_selector('div#error_explanation') 

請參見 「DSL」 在水豚的README上的git部分:針對您的問題https://github.com/jnicklas/capybara

官方解釋:爲您提示@Ryan https://github.com/jnicklas/capybara/issues/240

+0

我試圖按照你的指示修復它,但'current_path.should == new_user_path'不起作用。我認爲這是RSpec,我沒有使用RSpec。另外,assert current_path'\ signup'不起作用。我怎樣才能檢查current_path? – 2012-02-02 17:39:23

+0

實際上,是的,*。應該*匹配器是RSpec的一部分。我的錯。然而,'current_path'應該被定義爲包含在'include Capybara :: DSL'中的DSL的一部分。當你嘗試使用'current_path'時,你是否得到一個方法沒有定義的錯誤,或者其他的東西? – Ryan 2012-02-02 22:30:41

+0

我並不同意你的看法,但是你能解釋爲什麼rspec特別提到請求規範的'render_template'和'redirect_to'方法,[在這個津津有味的頁面](https://www.relishapp.com/rspec/rspec -rails /文檔/請求功能/請求規格)?他們不爲我工作(接收與OP相同的錯誤),我很好奇爲什麼。 – bricker 2012-09-25 06:22:11

0

感謝。我試圖弄清楚如何將一些RSpec集成測試示例從http://ruby.railstutorial.org/chapters/sign-up#sec:rspec_integration_tests轉換爲Test :: Unit + Capybara。原來RSpec的集成測試是

it "should not make a new user" do 
    lambda do 
     visit signup_path 
     fill_in "Name",   :with => "" 
     fill_in "Email",  :with => "" 
     fill_in "Password",  :with => "" 
     fill_in "Confirmation", :with => "" 
     click_button 
     response.should render_template('users/new') 
     response.should have_selector("div#error_explanation") 
    end.should_not change(User, :count) 
    end 
end 

所以,你的回答後,我supose原來的例子不應該包含response.should render_template('users/new')

+0

在某些情況下,肯定有可能*在集成測試中執行特定模板的渲染檢查。我只是認爲這樣做是不明智的。 – Ryan 2012-02-02 22:34:29

1

對於我的完整性,因爲我就知道我會回來的這鏈接:

那些使用測試單位和水豚這也是一個很好的底漆:from techiferous

注意使用assert page.has_content?("something")

這是很好的測試路由使用以及assert_equal some_path, current_path

它是最完整的,不知道,但你不需要更多。