在 Capybara 测试期间调用 Coffeescript
Invoke Coffeescript during Capybara tests
我的应用程序有很多不同的地方,当用户单击 button/link/div 时,我通过调用 ajax 函数来更新数据库。我需要在我的测试中包含这些功能,但我对 Capybara 还不够了解。
下面是我要测试的一个 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
在开发和生产中,div 和 ajax 正在努力切换学生在数据库中被标记为 absent/present。但是在测试中,行 assert_not @ss.present 失败了。这是我试图在所有地方修复的模式:none 我的水豚测试正在调用任何 javascript.
我已经阅读了一些类似的问题和相关文章。我已经尝试了到目前为止我读过的所有建议,例如添加 selenium-webkit gem 以便我可以使用行 Capybara.javascript-driver = :selenium。到目前为止,我遇到的解决方案都没有对我有用。
提前感谢您的任何见解。
您可以尝试 Poltergeist 驱动程序并更改配置以使用它。不要忘记在您的路径上安装 PhantomJS(您可以使用以下命令安装它:npm install -g phantomjs
.
您应该在测试的某些部分添加 js: true
,我只是不记得在哪里。但是,您可以搜索它。 =]
祝你好运。
None 你的测试 运行 JS 通常是两个问题之一,然后你的测试还有两个问题可能会导致失败。
对于 JS 问题,第一个原因可能是您的一个 JS 资产有错误,导致它们在连接在一起时无法处理。由于您声明它在生产模式下工作(也发生串联),我们应该能够排除这种情况。第二个原因是您不是 运行 支持 JS 的驱动程序。确保您已按照自述文件中的说明进行操作 - https://github.com/teamcapybara/capybara#using-capybara-with-minitest - are deriving your test classes from ActionDispatch::IntegrationTest and that the last part of that section (where Capybara.current_driver = Capybara.javascript_driver) is being run before any tests that require JS. (If you want all your tests to run with JS support you can just set Capybara.default_driver = Capybara.javascript_driver after setting Capybara.javascript_driver). If using Rails < 5.1 you'll probably also need to install and configure database_cleaner - see https://github.com/teamcapybara/capybara#transactions-and-database-setup
那应该让你的测试 运行 一个支持 JS 的驱动程序 - 除此之外 -
第一:当您调用 find(...).click
时,不能保证等待由点击引起的任何操作完成。这意味着您需要为点击触发的可见更改设置一个断言(水豚提供的断言之一,因为它们具有 waiting/retrying 行为)以确保在尝试访问数据库中的元素之前它已完成。
第二:因为你已经加载了 @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
一直需要重新加载对象是对数据库对象进行断言通常不受欢迎的部分原因,您应该主要只是测试 UI behavior/changes(在功能中测试)
我的应用程序有很多不同的地方,当用户单击 button/link/div 时,我通过调用 ajax 函数来更新数据库。我需要在我的测试中包含这些功能,但我对 Capybara 还不够了解。
下面是我要测试的一个 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
在开发和生产中,div 和 ajax 正在努力切换学生在数据库中被标记为 absent/present。但是在测试中,行 assert_not @ss.present 失败了。这是我试图在所有地方修复的模式:none 我的水豚测试正在调用任何 javascript.
我已经阅读了一些类似的问题和相关文章。我已经尝试了到目前为止我读过的所有建议,例如添加 selenium-webkit gem 以便我可以使用行 Capybara.javascript-driver = :selenium。到目前为止,我遇到的解决方案都没有对我有用。
提前感谢您的任何见解。
您可以尝试 Poltergeist 驱动程序并更改配置以使用它。不要忘记在您的路径上安装 PhantomJS(您可以使用以下命令安装它:npm install -g phantomjs
.
您应该在测试的某些部分添加 js: true
,我只是不记得在哪里。但是,您可以搜索它。 =]
祝你好运。
None 你的测试 运行 JS 通常是两个问题之一,然后你的测试还有两个问题可能会导致失败。
对于 JS 问题,第一个原因可能是您的一个 JS 资产有错误,导致它们在连接在一起时无法处理。由于您声明它在生产模式下工作(也发生串联),我们应该能够排除这种情况。第二个原因是您不是 运行 支持 JS 的驱动程序。确保您已按照自述文件中的说明进行操作 - https://github.com/teamcapybara/capybara#using-capybara-with-minitest - are deriving your test classes from ActionDispatch::IntegrationTest and that the last part of that section (where Capybara.current_driver = Capybara.javascript_driver) is being run before any tests that require JS. (If you want all your tests to run with JS support you can just set Capybara.default_driver = Capybara.javascript_driver after setting Capybara.javascript_driver). If using Rails < 5.1 you'll probably also need to install and configure database_cleaner - see https://github.com/teamcapybara/capybara#transactions-and-database-setup
那应该让你的测试 运行 一个支持 JS 的驱动程序 - 除此之外 -
第一:当您调用 find(...).click
时,不能保证等待由点击引起的任何操作完成。这意味着您需要为点击触发的可见更改设置一个断言(水豚提供的断言之一,因为它们具有 waiting/retrying 行为)以确保在尝试访问数据库中的元素之前它已完成。
第二:因为你已经加载了 @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
一直需要重新加载对象是对数据库对象进行断言通常不受欢迎的部分原因,您应该主要只是测试 UI behavior/changes(在功能中测试)