首页 > 解决方案 > Rails - Minitest + Capybara + Selenium - 测试破坏动作

问题描述

我是 Minitest / Capybara / Selenium 的新手。但我想测试我的销毁控制器动作。我尝试以下但失败了

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>

有人可以帮助我测试我的破坏动作吗?

标签: ruby-on-railsrubytestingcapybaraminitest

解决方案


假设您使用的是现代版本的 Rails (5.2/6) 和标准系统测试配置(不在线程中运行并行测试),那么 Gregório Kusowski 的答案中的关注点是无关紧要的,因为数据库连接在您的测试和您的应用程序,防止测试无法看到您的应用程序更改的问题。

还假设您在这些系统测试中使用 Selenium,您要处理的主要问题是浏览器中的操作与您的测试异步发生,所以仅仅因为您告诉您的测试接受对话框并不意味着当公司返回时,删除公司的操作已经完成。验证这一点的方法是在检查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 提供的断言具有等待/重试行为,允许应用程序在特定的时间内赶上测试的预期。

注意:我已经用page.driver...Capybaras 系统模态 API 的正确用法替换了 - 如果你使用page.driver...它通常表明你做错了。


推荐阅读