【问题标题】:How can I reduce duplication on my automated tests?如何减少自动化测试的重复?
【发布时间】:2021-05-28 17:35:03
【问题描述】:

我正在测试用户可以添加国家和更新国家的功能。但是,添加国家/地区和更新国家/地区是在同一屏幕的同一字段中完成的。

例如,我可以进入编辑国家页面并通过添加名称和坐标创建一个新国家,或者我可以选择现有国家并更新名称和坐标。我遇到的问题是字段有验证规则,例如名称必须是唯一的并且一定数量的字符。

我不想重复测试,但看起来我必须这样做,因为当我们添加新国家/地区时,后端规则将插入新记录,我必须检查名称是否重复,例如国家还不存在。当我们更新国家/地区时,后端规则将更新现有记录,我必须检查该名称不存在。

伪代码测试用例一:

//Go on edit country page to add new country
//enter a name which already exists 
//click save
//assert you get error message that country already exists 

伪代码测试用例2:

//Select existing country this will open edit country page 
//update the name to another country which already exists 
//click save
//assert you get error message that country already exists 

如何减少代码中的重复,我在国家测试规范中做所有事情。

【问题讨论】:

  • 测试只是代码。当你需要共享功能时,做你在普通代码中会做的事情:编写一个函数。一些测试框架有自己的方式来进行共享测试,比如RSpec shared examples。要说更多,我们需要知道您使用的是什么测试框架。

标签: testing automated-tests testcase


【解决方案1】:

测试仍然是代码。您可以像处理任何代码一样解决它:编写一个函数。一些测试框架具有特殊功能,例如RSpec shared examples

您还可以通过避开 UI 并更直接地插入数据来简化设置。

这是我在 Ruby 和 Rails 中使用 RSpec、FactoryBotCapybara 处理它的方法。

context "when a country already exists" do
  shared_example "it shows a message about the duplicate country" do
    it 'shows a duplicate name error' do
      expect(page).to
        have_content("We already have a country called #{existing_country.name}")
    end
  end

  # We're not testing the UI can create countries, so make one using the model.
  # In this case via FactoryBot to fill in all the details we don't care about.
  let!(:existing_country) { create(:country) }

  context "when making a new country with the same name" do
    # This is all setup for the test, it's not what you're testing, so it's context.
    before do
      visit "/country/new"
      fill_in "name", with: existing_country.name
      click_button 'Save'
    end

    # Use the shared example.
    it_behaves_like "it shows a message about the duplicate country"

    # And test specific behavior. Again, we're not using the UI, we're using models.
    it 'does not save the new country' do
      expect(Country.where(name: existing_country.name).count).to eq 1
    end
  end

  context "when changing a country to have the same name" do
    let!(:country) { create(:country) }
    let!(:old_name) { country.name }

    # Again, we're not testing that the UI can edit. This is context.
    before do
      visit "/country/edit/#{country.id}"
      fill_in "name", with: existing_country.name
      click_button 'Save'
    end

    # Use the shared example.
    it_behaves_like "it shows a message about the duplicate country"

    # And test specific behavior. Again, using the models. Be sure to reload
    # any existing objects, if that's how your system works, after changing them
    # in the UI.
    it 'does not save the new name' do
      country.reload
      expect(country.name).to eq old_name
    end
  end
end

你的细节会改变,但基本的想法会保留。

  • 测试只是代码。将它们分解并以类似方式共享功能。
  • 将上下文设置与实际测试分开并重用上下文。
  • 避免不必要地通过 UI 进行工作。测试 UI 很复杂,并且会添加很多您没有测试的代码。
  • 拥有测试工厂,快速设置测试数据。

【讨论】:

  • 我不明白你的意思,我怎么能不使用 UI?我必须在框中输入文本,然后单击保存按钮才能在屏幕上显示消息,这是 UI 测试,我没有测试数据库。
  • @Junior 它正在使用 UI,但仅适用于您正在测试的部分。 visitfill_inclick_button 都是 Capybara 函数,它们操纵浏览器进入编辑页面,在框中输入文本,然后单击保存按钮。然后测试检查预期的消息是否在结果页面上。 使用 UI 的是设置。我们不需要使用 UI 来添加一个国家来作为我们要测试的副本。相反,我们使用测试工厂将其直接注入数据库;这就是create(:country) 在上面所做的。这样可以节省大量劳动力并且速度更快。
  • @Junior 同样,当测试编辑没有更改名称时,我们通过数据库而不是 UI 检查。我们不是在测试 UI 是否可以显示国家/地区,而是在检查基础数据是否未被 UI 更改。它更简单,更快捷。检查显示的错误消息 是否按照它所说的那样做是很重要的。
猜你喜欢
  • 2019-04-27
  • 2021-07-03
  • 1970-01-01
  • 2022-11-29
  • 2021-03-19
  • 2014-07-18
  • 2015-01-05
  • 1970-01-01
  • 2017-04-07
相关资源
最近更新 更多