Rails - Minitest + Capybara + Selenium - 测试破坏动作
Rails - Minitest + Capybara + Selenium - Test destroy action
我是 Minitest/Capybara/Selenium 的新手。但我想测试我的 destroy Controller 动作。我尝试了以下但失败了
test "destroy" do
companies_count = Company.count
visit company_path(@company)
click_on "Delete"
page.driver.browser.switch_to.alert.accept
assert_equal (companies_count - 1), Company.count
end
输出:
test_destroy FAIL (2.17s)
Expected: 6
Actual: 7
这个方法也试过了
test "destroy" do
assert_difference('Company.count', -1) do
delete company_url(@company)
end
end
输出:
Minitest::UnexpectedError: NoMethodError: undefined method `delete' for #<CompaniesControllerTest:0x000056171e550038>
有人可以帮我测试我的销毁动作吗?
这很可能会发生,因为您在测试中直接执行的操作发生在事务中,而您的 Web 驱动程序正在触发发生在另一个事务上的操作。你可以在这里阅读更多关于它是如何发生的:https://edgeguides.rubyonrails.org/testing.html#testing-parallel-transactions
这是一个类似的问题:Rails integration test with selenium as webdriver - can't sign_in
正如 Rails 指南和类似问题中所述,您可能必须使用 http://rubygems.org/gems/database_cleaner
这样的解决方案
如果您不想这样做,您还有另一个选择是通过网络驱动程序验证您的操作是否成功,例如断言 table 中有 6 行你列出所有公司。
假设您使用的是 Rails (5.2/6) 的现代版本和标准系统测试配置(不是 运行 线程中的并行测试)那么 Gregório 的回答中的问题Kusowski 无关紧要,因为数据库连接在您的测试和应用程序之间共享,从而防止了测试无法看到您的应用程序更改的问题。
还假设您在这些系统测试中使用 Selenium,您要处理的主要问题是浏览器中的操作与您的测试异步发生,所以仅仅因为您已告诉您的测试接受对话框returns 框并不意味着删除公司的操作已完成。验证方法是在检查 count
中的变化之前先睡一会儿。虽然这会起作用,但它不是一个好的最终解决方案,因为它最终会浪费时间。相反,您应该在验证新计数
之前检查指示操作已完成的视觉变化
test "destroy" do
companies_count = Company.count
visit company_path(@company)
accept_confirm do
click_on "Delete"
end
assert_text "Company Deleted!" # Check for whatever text is shown to indicate the action has successfully completed
assert_equal (companies_count - 1), Company.count
end
之所以可行,是因为 Capybara 提供的断言具有 waiting/retrying 行为,允许应用程序在特定时间内赶上测试的预期。
注意:我已将 page.driver...
替换为 Capybaras 系统模式的正确用法 API - 如果您使用的是 page.driver...
,这通常表示您做错了.
我是 Minitest/Capybara/Selenium 的新手。但我想测试我的 destroy Controller 动作。我尝试了以下但失败了
test "destroy" do
companies_count = Company.count
visit company_path(@company)
click_on "Delete"
page.driver.browser.switch_to.alert.accept
assert_equal (companies_count - 1), Company.count
end
输出:
test_destroy FAIL (2.17s)
Expected: 6
Actual: 7
这个方法也试过了
test "destroy" do
assert_difference('Company.count', -1) do
delete company_url(@company)
end
end
输出:
Minitest::UnexpectedError: NoMethodError: undefined method `delete' for #<CompaniesControllerTest:0x000056171e550038>
有人可以帮我测试我的销毁动作吗?
这很可能会发生,因为您在测试中直接执行的操作发生在事务中,而您的 Web 驱动程序正在触发发生在另一个事务上的操作。你可以在这里阅读更多关于它是如何发生的:https://edgeguides.rubyonrails.org/testing.html#testing-parallel-transactions
这是一个类似的问题:Rails integration test with selenium as webdriver - can't sign_in
正如 Rails 指南和类似问题中所述,您可能必须使用 http://rubygems.org/gems/database_cleaner
这样的解决方案如果您不想这样做,您还有另一个选择是通过网络驱动程序验证您的操作是否成功,例如断言 table 中有 6 行你列出所有公司。
假设您使用的是 Rails (5.2/6) 的现代版本和标准系统测试配置(不是 运行 线程中的并行测试)那么 Gregório 的回答中的问题Kusowski 无关紧要,因为数据库连接在您的测试和应用程序之间共享,从而防止了测试无法看到您的应用程序更改的问题。
还假设您在这些系统测试中使用 Selenium,您要处理的主要问题是浏览器中的操作与您的测试异步发生,所以仅仅因为您已告诉您的测试接受对话框returns 框并不意味着删除公司的操作已完成。验证方法是在检查 count
中的变化之前先睡一会儿。虽然这会起作用,但它不是一个好的最终解决方案,因为它最终会浪费时间。相反,您应该在验证新计数
test "destroy" do
companies_count = Company.count
visit company_path(@company)
accept_confirm do
click_on "Delete"
end
assert_text "Company Deleted!" # Check for whatever text is shown to indicate the action has successfully completed
assert_equal (companies_count - 1), Company.count
end
之所以可行,是因为 Capybara 提供的断言具有 waiting/retrying 行为,允许应用程序在特定时间内赶上测试的预期。
注意:我已将 page.driver...
替换为 Capybaras 系统模式的正确用法 API - 如果您使用的是 page.driver...
,这通常表示您做错了.