Cucumber 与许多客户一起在站点上实现Watir Webdriver覆盖的方法

Cucumber 与许多客户一起在站点上实现Watir Webdriver覆盖的方法,cucumber,watir,watir-webdriver,web-testing,Cucumber,Watir,Watir Webdriver,Web Testing,好的,我需要一个思维过程的推进——我的大脑受伤了。我想听听你对一些方法的反馈 我将提前发布我的问题,以防我在下面的描述中失去您的注意力: 您以前编写过类似的产品吗?你是怎么做到的 这些方法中有哪一种对任何人来说都是好的/糟糕的 原因?如果是,什么 你会找到其他的方法吗 更合适 我正在测试一个工作流,为了论证起见,我们将其称为购物车,它由各种文本字段、单选按钮和选择列表组成。一家公司为约60名客户提供此购物车,并非所有客户都使用相同的确切形式,但一般流程是相同的。客户机之间的总体思路是相同的(

好的,我需要一个思维过程的推进——我的大脑受伤了。我想听听你对一些方法的反馈

我将提前发布我的问题,以防我在下面的描述中失去您的注意力:

  • 您以前编写过类似的产品吗?你是怎么做到的

  • 这些方法中有哪一种对任何人来说都是好的/糟糕的 原因?如果是,什么

  • 你会找到其他的方法吗 更合适
我正在测试一个工作流,为了论证起见,我们将其称为购物车,它由各种文本字段、单选按钮和选择列表组成。一家公司为约60名客户提供此购物车,并非所有客户都使用相同的确切形式,但一般流程是相同的。客户机之间的总体思路是相同的(相同的目标功能),并且有一些客户机子集具有相同的确切工作流,但许多都是唯一的。在这种情况下,“唯一”可能意味着某些字段不是必需的,而其他客户端可能需要这些字段。或者,某个客户机存在某些问题/文本_字段,其他客户机根本无法使用这些字段

此时脚本的目标只是通过web界面生成一个订单,而不是作为“测试”验证流程的每个单独步骤。你得相信我一点。仍然有很多常见的细节能够以可接受的精度运行负面/边缘案例

到目前为止,我看到的方法是:

  • 使用页面对象模式,为每个客户端站点创建一个“页面”文件,并根据要测试的客户端使用不同的页面类。这是乏味的,大多是脆弱的和大量的工作要维护。但是,它可以工作,我可以为每个人使用相同的功能/场景,只要他们的特定页面文件是可访问的

  • 创建一个方法来从DOM中刮取所有输入元素,检测它们是否是我们需要向其中注入特定必需输入的保留字段,或者只是填写信息以获得完成的顺序。这并不依赖于数据库,因此总体性能应该更好

  • 钩住数据库,收集用于构建页面的特定客户机所需的所有信息,动态构建订单的字段,并相应地回答它们。从理论上讲,这听起来很棒,即使需要任何维护,也几乎不需要什么。DB抓取很容易,但我还不知道构建字段的难度

  • 现在我正在使用: 瓦蒂尔网络驱动程序 黄瓜 Cheezy的页面对象gem
    sequel

    我会使用cheezy的页面对象,包括所有可能包含的字段/问题。然后我会重载每个客户的默认值,只包括他们使用的字段/问题。希望我没有过分简化这一点

    更新: 在中,它将把您发送的任何数据(作为散列)与默认数据合并。在his中,他展示了如何使用默认数据。我想您可以创建一个类签出页面

     class CheckoutPage
      include PageObject
    
      text_field(:name, :id => “order_name”)
      text_field(:address, :id => “order_address”)
      text_field(:email, :id => “order_email”)
      select_list(:pay_type, :id => “order_pay_type”)
      button(:place_order, :value => “Place Order”)
    
      PageObject::PageFactory.routes = {
        :default => [[HomePage, :select_puppy],
                     [DetailsPage, :add_to_cart],
                     [ShoppingCartPage, :continue_to_checkout],
                     [CheckoutPage, :complete_order]]
      }
    
      def complete_order(data = {})
         data = DEFAULT_DATA.merge(data)
         self.name = data['name']
         self.address = data['address']
         self.email = data['email']
         self.pay_type = data['pay_type']
         place_order
       end
     end
    
    然后为使用该站点的特定供应商重载它,每个供应商都有自己的默认数据

    class Nordies < CheckoutPage
          DEFAULT_DATA = {
            ‘name’ => ‘cheezy’,
            ‘address’ => ‘123 Main Street’,
            ‘email’ => ‘cheezy@example.com’,
            ‘pay_type’ => ‘Purchase order’
          }
    
    PageObject::PageFactory.routes = {
      :default => [[HomePage, :select_puppy],
                   [DetailsPage, :add_to_cart],
                   [ShoppingCartPage, :setup_creditcard],
                   [CreditCardPage, :continue_to_checkout],
                   [CheckoutPage, :complete_order]]
    }
    end
    
    classnordies“cheezy”,
    “地址”=>“主街123号”,
    '电子邮件'=>'cheezy@example.com’,
    “付款类型”=>“采购订单”
    }
    PageObject::PageFactory.routes={
    :default=>[[主页:选择小狗],
    [DetailsPage,:将\添加到\购物车],
    [购物车页面:设置信用卡],
    [CreditCardPage,:继续到签出],
    [CheckoutPage,:完成订单]]
    }
    结束
    

    那么,每个供应商的.complete_订单都会有所不同。

    如果您认为我应该读一篇博客/文章,或者我应该买一本书,也请告诉我。我意识到我不能是第一个考虑这个决定的人,我也不希望别人为我做这些事情!客户机配置的稳定性如何,由谁配置?例如,测试维护人员是否知道表单/页面何时更改?表单是否经常更改,还是保持原来的执行状态?我要求更好地理解不同方法下所需的维护。@JustinKo-主要部分(页面顺序、问题)应该是静态的,不必担心它们会发生变化,除非在极端情况下。可用性(仅在可用状态上具有活动状态链接的美国地区地图)等功能将定期更改,但我已经有了一种方法来动态检测这些功能,或者接受用户对脚本的输入,并根据位置的可用性继续/失败。我不确定您所说的过载默认值是什么意思,但在剩下的答案中,听起来你基本上是通过“if field_one.exists”{fill it-fill}方法运行的?我正在尝试使用Cheezy的默认数据方法2,因为它在过去对其他项目一直很好,使用了更新的populate_page_with方法。从技术上讲,我不确定使用这种方法是否合适。是的,我使用的是他的gem(在它成为gem之前使用的是他的页面对象方法),但我不确定你所说的重载值是什么意思。我觉得我们有点太简洁了!那是一次意外。我觉得一条评论太过局限,说不出任何有用的东西,所以我更新了我的答案。有趣的是,默认数据将是每个客户端拥有的子集(如果有的话),然后客户端类