页面对象模型,方法有多离散?

时间:2019-04-05 16:47:50

标签: automation capybara pageobjects

所以我一直在一个新项目上实施PoM,这是我第一次这样做。我使用Capybara和Rspec(硒)来编写我的框架。

我经常遇到的一件事是我应该如何在“页面对象类”中创建方法。涉及到两个方面:

让我们进入一个制作小部件的页面:

选项1(通用,更侧重于用户的操作)

class WidgetPage

   def click_widgets_tab
        click_on('Widgets')
    end

    def create_widget_button
        click_on('Add Widget')
    end

    def enter_widget_name(name)
        fill_in 'Widget Name', with: name
    end

    def enter_widget_type(type)
        fill_in 'Widget Type', with: type
    end

    def widget_success?
        expect(page).to have_content('.alert', text: 'Widget Successfully created!')
    end
end

(在上述情况下,“填充”方法甚至可以组合使用

或选项2:

class WidgetPage

    def click_widgets_tab
        widget_tab_link.click
    end

    def create_widget_button
        widget_add_element.click
    end

    def enter_widget_name(name)
        widget_form_name.fill_in(name)
    end

    def enter_widget_type(type)
        widget_form_type.fill_in(type)
    end

    def widget_success?
        widget_success_alert.has_text? 'Widget successfully created!'
    end


    private

    def widget_add_element
        find_button('Widget')
    end

    def widget_form_name
        find_field('Widget Name')
    end

    def widget_form_type
        find_field('Widget Type')
    end

    def widget_tab_link
        find_link('Widgets')
    end

    def widget_success_alert
        find(.alert, text: "Widget successfully created!")
    end

end

我觉得我看到大多数Page Object教程都使用选项2 ...,但是似乎有很多额外的代码,几乎没有投资回报。如果有多种方法可以使用返回元素的方法,这对我来说很有意义...但并非每个方法都适用。

就断言而言,选项1更有意义。但是我也听说过,您不应该在页面对象中包含断言。因此,也许只有一种方法可以返回例如警报是否可见的方法才更有意义?仍然不确定处理该问题的最佳方法。

1 个答案:

答案 0 :(得分:1)

我认为这是一个公平的问题,很多问题都归结为偏好,但是如果您为自己的情况选择了错误的“偏好”,则可能会遇到一些真正的陷阱,因此,我认为值得一谈关于。

  • 部分意见:如果您的应用不稳定/易变/需要解决方法,请在页面对象中考虑使用更精细的方法,而在步骤定义中考虑使用较少的Capybara。在步骤def中有数十个page.element.click()调用都需要更新,这很烦人,因为应用程序更改为每次单击之前都需要将鼠标悬停。如果该操作以page.clickElement()的形式包装在页面对象中,则您可以在一个位置进行更新(或实施变通方法)。
  • 大多数意见:如果绝对包装Capybara可以为每个元素执行的所有操作,则最终将导致一个难以使用的page肿页面对象。如果存在一组步骤defs将在90%的时间内使用的动作,我将其公开为显式方法,并让其余10%的边缘情况类型的动作直接使用这些元素。
  • 部分意见:请注意,水豚的click_on / fill_in方法会限制您使用其定位器的概念(名称,ID或标签)。与任意CSS相比,我总是发现它是如此严格,以至于我避免使用它们。
  • 少见:避免在页面对象中放入断言!页面对象是页面的抽象,不是对业务规则的测试。对于上面的示例,这两个选项都将失败,并带有一个平面的“找不到元素”或“ false!= true”,这不是很有用。考虑改为从页面对象返回文本(无论文本是什么),并在步骤def中声明。

类似

def get_widget_alert
    find(.alert).get_text()
end

从步骤def中调用为

expect(widget_page.get_widget_alert).to eq('Widget Successfully created!')

如果有人决定沿途更改标点或消息的大小写,将失败,并显示一条有用的消息。