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

Testing 如何减少自动化测试中的重复?,testing,automated-tests,testcase,Testing,Automated Tests,Testcase,我正在测试用户可以添加国家和更新国家的功能。但是,添加国家/地区和更新国家/地区是在同一屏幕上的相同字段中完成的 例如,我可以进入“编辑国家”页面,通过添加名称和坐标创建一个新国家,或者我可以选择现有国家并更新名称和坐标。我遇到的问题是,字段上有验证规则,例如名称必须是唯一的,并且有一定数量的字符 我不想重复测试,但看起来我必须重复,因为当我们添加新国家/地区时,后端规则将插入新记录,我必须检查名称是否重复,例如国家/地区不存在。当我们更新国家时,后端规则将更新现有记录,我必须检查名称是否不存在

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

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

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

伪代码测试用例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 

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

测试仍然是代码。您可以用与任何代码相同的方法来解决它:编写函数。一些测试框架具有特殊的功能,如

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

下面是我如何使用RSpec以及Ruby和Rails处理它

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,但仅用于您正在测试的部件<代码>访问、
填写
单击按钮
都是水豚功能,它们操纵浏览器进入编辑页面,在框中输入文本,然后单击保存按钮。然后测试检查预期消息是否在结果页面上。不使用UI的是设置。我们不需要使用UI添加一个国家作为我们的副本进行测试。相反,我们使用测试工厂将其直接注入数据库;这就是
create(:country)
在上面所做的。这节省了大量的人力,而且速度快得多。@Junior类似地,当测试编辑没有更改我们通过数据库而不是UI检查的名称时。我们不是在测试UI是否可以显示一个国家,而是在检查UI是否更改了基础数据。它更简单、更快。检查显示的错误消息以及它是否按照所说的做了很重要。