2017-12-18 166 views
0

我的应用程序有很多不同的地方,当用户点击按钮/链接/ div时,我通过调用ajax函数来更新数据库。我需要在测试中包含这些功能,但我对水豚的了解还不够。在Capybara测试期间调用Coffeescript

下面是我想测试的一个div的示例,关联的ajax调用以及我想要通过的测试。我应该补充一点,我正在通过Cloud9 IDE进行构建,以防有所作为。

查看

<% @seminar.students.order(:last_name).in_groups_of(6).each do |group| %> 
    <div class="row"> 
     <% group.each do |student| %> 
      <% if student %> 
       <% this_ss = @seminar.seminar_students.find_by(:user => student) %> 
        <% if this_ss.present %> 
         <% thisClass = "col-md-2 seat clickySeat" %> 
         <% thisText = "Present" %> 
        <% else %> 
         <% thisClass = "col-md-2 seat clickySeat absent" %> 
         <% thisText = "Absent" %> 
        <% end %> 
        <div class = "<%= thisClass %>" id="<%= this_ss.id %>" name="ss_<%= this_ss.id %>"> 
         <%= student.first_plus_init %><br/> 
         <p class="presentTag"><%= thisText %></p> 
        </div> 
       <% end %> 
     <% end %> 
    </div> 
<% end %> 

CoffeeScript的

if $('.clickySeat').length > 0 
    $('.clickySeat').on "click", -> 
     this_tag = $(this).find(".presentTag") 
     seminar_student_id = $(this).attr('id') 
     url = '/seminar_students/'+seminar_student_id 
     if this_tag.text() == "Absent" 
      attendance = true 
      $(this).removeClass("absent") 
      this_tab.text("Present") 
     else 
      attendance = false 
      $(this).addClass("absent") 
      this_tab.text("Absent") 
     $.ajax 
      type: "PUT", 
      url: url, 
      dataType: "json" 
      data: 
       seminar_student: 
        present: attendance 

测试

test "attendance with click" do 
    @ss = @student_3.seminar_students.find_by(:seminar => @seminar) 
    assert @ss.present 

    capybara_login(@teacher_1) 
    click_on("desk_consult_#{@seminar.id}") 
    click_on("#{new_consultancy_button_text}") 
    find("##{@ss.id}").click 

    assert_not @ss.present 
    click_on("Create Desk Consultants Groups") 
end 

在开发和生产, divs和ajax正在努力切换数据库中被标记为不存在/存在的学生。但在测试中,assert_not @ ss.present行失败。这是我试图解决的模式:我的水豚测试都没有调用任何JavaScript。

我已阅读了几个类似的问题和相关文章。我尝试了迄今为止阅读过的所有建议,例如添加selenium-webkit gem,以便可以使用Capybara.javascript-driver =:selenium这一行。迄今为止我遇到的解决方案都没有为我工作。

非常感谢您的任何见解。

+0

您不会告诉我们您想要通过的测试实际失败。另外,当您设置“Capybara.javascript_driver”时,它只会被您指定使用支持javascript的驱动程序的测试使用。请参阅 - https://github.com/teamcapybara/capybara#selecting-the-driver。您应该能够判断它是否使用硒,因为它通常会打开Firefox或Chrome的实例(具体取决于您的配置)。 –

+0

啊哈。好点子。测试在线assert_not @ ss.present上失败。在开发和生产中,单击div更新数据库以在缺席和现在之间切换学生。在测试中,没有任何反应。 –

+0

这是我试图在任何地方修正的模式:我的水豚测试都没有调用任何JavaScript。 –

回答

1

无运行JS你的测试通常是两个问题中的一个,然后有你的测试另外两个问题,可能会导致故障的不止于此。

对于JS问题,第一个原因可能是你的JS资源中有一个错误这导致它们在串联在一起时不被处理。既然你声明它在生产模式下工作(在连接也发生的地方),我们应该能够规定这一点。第二个原因是您没有使用支持JS的驱动程序。确保您已按照README - https://github.com/teamcapybara/capybara#using-capybara-with-minitest中的说明 - 从ActionDispatch :: IntegrationTest派生您的测试类,并且在任何需要JS的测试之前运行该部分的最后部分(其中Capybara.current_driver = Capybara.javascript_driver) 。 (如果你想让所有的测试运行JS支持,你可以在设置Capybara.javascript_driver后设置Capybara.default_driver = Capybara.javascript_driver)。如果使用Rails 5.1 <你可能还需要安装和配置database_cleaner - 见https://github.com/teamcapybara/capybara#transactions-and-database-setup

这应该让你的测试用JS能驱动运行 - 超出 - 首先:当你打电话find(...).click未保证等待由点击完成的任何操作。这意味着你需要设置一个断言(由于它们具有等待/重试行为而提供的断言,因为点击触发的可见变化),以确保它在尝试从数据库访问元素之前完成了断言。
其次:因为您已经加载了@ss它不会反映数据库状态的变化,直到您重新加载对象。

在一起,这意味着你的测试将需要沿着

test "attendance with click" do 
    @ss = @student_3.seminar_students.find_by(:seminar => @seminar) 
    assert @ss.present 

    capybara_login(@teacher_1) 
    click_on("desk_consult_#{@seminar.id}") 
    click_on("#{new_consultancy_button_text}") 
    find("##{@ss.id}").click 
    assert_text("You are marked as absent") # An assertion for whatever visible change occurs due to the previous click which will delay the next statement until the app has completed processing 
    assert_not @ss.reload.present # Need to reload the object to see any DB changes 
    click_on("Create Desk Consultants Groups") 
end 

需要的线路更改为重新加载对象所有的时间是上DB对象做断言是在一般不赞成的原因之一,而你应该主要是测试UI行为/更改(在功能测试中)

+0

我认为我已经实施了所有的建议。现在看起来测试文件中的代码无法访问灯具。如果我将“调试器”放在测试文件中,User.count将返回零。 (这是因为database_cleaner已经“清除”了所有的数据?)为了解决问题,我试着在测试开始时创建一个新老师。不幸的是,这位新创建的老师无法登录。当“调试器”被放置在我的sessions_controller中时,User.count将返回所有来自灯具的124个用户。但它不包括我在测试中创建的老师。 –

+0

当我在没有清理器的情况下尝试时,出现以下错误:ActiveRecord :: StatementInvalid:SQLite3 :: BusyException:数据库被锁定: –

+0

@JeffZivkovic您尚未阐明您正在使用的Rails版本,但如果使用<5.1 (5.1+中不需要database_cleaner),并且您无法访问在测试中创建的记录,那么最有可能意味着在运行支持JS的测试时,您没有正确启用database_cleaner以使用截断或删除模式,并且而是仍然使用交易模式。 –

1

您可以尝试Poltergeist驱动程序并更改配置以使用它。不要忘了在你的路上安装PhantomJS(你可以使用以下命令安装它:npm install -g phantomjs

你应该在测试的某些部分添加js: true,我只是不记得在哪里。一下吧。=]

祝你好运。

+1

'js:true'只有在使用RSpec时才有效 - OP似乎正在使用minitest。 –

+0

如果我能弄清楚如何安装phantomjs,它是否可以与Minitest一起使用?使用Cloud9 IDE会有所作为吗? –