新手问题 rspec capybara 测试 js 问题

lithium4010 · June 23, 2014 · Last by billy replied at June 23, 2014 · 2757 hits

rspec 加入测试 js 后,使用 FactoryGirl 创建的对象在测试数据库中不存在,请问应该如何解决? 测试时从弹出的浏览器中发现登陆就失败了

相关测试代码如下:

describe "error message", :js => true do 
post_err_msg = "发布失败"
     let(:lithium) { FactoryGirl.create(:lithium) }
     before do 
        sign_in lithium
        post_btn.click
     end
     it { should have_content(post_err_msg) }
end

问题解决了,加入了一个 database_cleaner 的 gem 并修改了 spec/spec_helper.rb 除了加上js:true不用修改测试代码的其他部分

参考

http://stackoverflow.com/questions/8178120/capybara-with-js-true-causes-test-to-fail

http://blog.csdn.net/heliang7/article/details/7762165

发现 selenium 测试需要打开一个浏览器太慢了,打算换 web-kit 试试。

https://github.com/jnicklas/capybara/

let改成let!问题就解决了。

#1 楼 @billy 没有用。。。。测试这个带 js 的用例的时候,会弹出一个 firefox 的窗口,然后自动进行填写用户的操作,但是 FactoryGirl 所创建的用户对象不能登陆

试下在sign_in lithium下面加行sleep 2, 有时 db 写入速度跟不上

@lithium4010 原因可能是 before 执行在 let 的前面。

两个解决方法和一个改进意见。

方法一:把let!放到更高层的 context 或者 describe。这样就可以保证在这个 before 之前执行。

方法二:不用 let!,直接用 instance variable,在sign in...之前加入@lithium = create(:lithium)

改进意见:你这个 spec 其实不是测的 login 而是其他,所以你其实不必要把 login 的步骤加进去,因为那个已经测过了。如果你用 Devise,可以用 sign in helper 代替这个过程。其他库比如 Authlogic 或者手写 authentication 也可以做,不过我不太记得了。

#5 楼 @billy 原因是开了 js 支持后,这个用例的上下文和之前用例的上下文不一样了,好象是新开了一个数据库(我也不清楚),数据库直接是空的。问题已经解决了。加上 gem 配置后不用修改测试代码。这是那个 js 驱动(selenium)的问题。。。。let!放更高一层是没有用的,之前就是这么做的。。文件中所有无关 js 的用例都能正常通过,而 js 的用例就好像开了一个新的环境一样,之前所有 FactoryGirl 的用户在数据库中都不存在。我在 let!后 puts User.any?结果是 false

今天居然 stackoverflow 上找到了相同的问题(一楼有链接)

I've read the Capybara readme at https://github.com/jnicklas/capybara and it solved my issue.

Transactional fixtures only work in the default Rack::Test driver, but not for other drivers like Selenium. Cucumber takes care of this automatically, but with Test::Unit or RSpec, you may have to use the database_cleaner gem. See this explanation (and code for solution 2 and solution 3) for details.

But basically its a threading issue that involves Capybara having its own thread when running the non-Rack driver, that makes the transactional fixtures feature to use a second connection in another context. So the driver thread is never in the same

You need to Sign in before reply, if you don't have an account, please Sign up first.