如何减少自动化测试的重复?

How can I reduce duplication on my automated tests?

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

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

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

伪代码测试用例1:

//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.

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

以下是我在 Ruby 和 Rails.

中使用 RSpec、FactoryBot, and Capybara 的处理方式
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 很复杂,会添加很多您没有测试的代码。
  • 有测试工厂可以快速设置测试数据。