新手问题 rspec capybara 测试 js 问题

lithium4010 · 2014年06月23日 · 最后由 billy 回复于 2014年06月23日 · 2750 次阅读

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

需要 登录 后方可回复, 如果你还没有账号请 注册新账号