首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >页面对象模型与自动化混淆?

页面对象模型与自动化混淆?
EN

Stack Exchange QA用户
提问于 2018-05-29 13:38:55
回答 3查看 668关注 0票数 5

因此,在构建自动化框架时,我一直在研究。大多数示例都是用Java完成的,但是由于im在Rails中使用Capybara和Selenium (Ruby),我想我没有理由也不能使用POM。

不过,我看到的大多数POM示例都是简单的东西,比如登录/etc.,我遇到的问题是,开发框架的Web应用程序im并不那么简单。

当我想到POM时,从我所知道的情况来看,每个"Page“都是一个单独的类。然而,在这个应用程序中,创建一个我们称之为"Widget“的过程是一个7-8步的过程。有时,Page可以是15+项。这就是我困惑的地方,还有以下几个问题:

  1. 我应该把每一步/每一页都变成一门课吗?
  2. 在有大量表单的页面中,每个“输入”应该是一个定义/方法吗?还是应该使用构造函数中定义的所有输入来初始化类?
  3. 由于页面主要是表单+提交button....what,所以类中的方法应该是吗?
  4. 因为创建小部件的“脚本”是7-8个不同的steps...would,所以我只是在脚本中创建7-8个不同的POM对象?这似乎没什么意义。但是,我可以看到,如果有人只想测试1部分,那么它就有意义了(所以我猜它确实是模块化的)。
EN

回答 3

Stack Exchange QA用户

回答已采纳

发布于 2018-05-29 19:23:44

一些网站的一种选择是拥有一个页面对象库,或者至少从一个页面对象库开始,这样可以避免复杂性。特别是如果您使用高度描述性的名称,例如,如果您使用“click_submit”作为一个名称太笼统,也有多个不同的名称。但是,如果使用“click_submit_initial_loan_application”、“click_submit_add_cosigner_application”和“click_submit_add_personal_contact”,那么将它们都放在一个文件中就可以了。

我在几个地方用过这种型号的红宝石-rspec-capybara。

目前,我使用Page对象如下:

name:selector的键值对创建一个页面对象yaml文件,例如(示例)

代码语言:javascript
运行
复制
# spec/support/page_objects.yml
...
student_dob_day: 'STU_ST_DOB2'
student_dob_month: 'STU_ST_DOB1'
student_dob_year: 'STU_ST_DOB3'
dialog_frame: 'iframe#dialogIFrame'
how_to_apply: 'BO_HowToApplyChoice'
how_to_apply_individual: 'BO_HowToApplyChoice[value="I"]'
electronic_consent: 'img#ElectronicConsentAccept'
...

然后,通过使用以下元编程动态创建方法,创建将它们加载到Page对象中的方法:

代码语言:javascript
运行
复制
# spec/support/page_object.rb
class PageObject

  def initialize
    load_page_object_file('spec/support/page_objects.yml')
  end 

  private

  def load_page_object_file(file)

    page_object = YAML.load(File.read(file))
    page_object.each do |k, v|
      self.class.__send__ :define_method, k do v end 
    end 
  end 

end

上面的字面意思是为页面对象名称创建方法名,返回(键)值是选择器。

然后,在我想在其中使用Page对象的规范中:

代码语言:javascript
运行
复制
describe "some test" do
    p = PageObject.new

然后在测试本身中,我使用Page对象,如下所示:

代码语言:javascript
运行
复制
...
select 'JAN', from: p.dob_month
fill_in p.dob_day, with: '01'
fill_in p.dob_year, with: '1978'
...

在另一个级别上,您可能也提到了这个级别,我创建了自定义命名方法,以抽象出详细信息,并得到如下所示的DSL:

代码语言:javascript
运行
复制
fill_out_school(p, 'COLUMBIA UNIVERSITY')
fill_out_first_degree_major_enrollment_status_dropdowns(p)
fill_out_first_grade_level(p)
fill_out_years(p, this_year)

使用这些方法,可以使用实际的capybara WebDriver查找、单击和键入命令。我传入已经创建的PageObject。

我通常不喜欢缩略语,但由于‘页面’会出现数百次或数千次,我将它减少到"p“,因为它是如此明显。我想是鲁比主义的极简主义者在我身上!

顺便说一下,我还使用了JSON和XML作为存储机制,这无疑教会了我,Page对象是一种可以有几个实现的方法。

票数 2
EN

Stack Exchange QA用户

发布于 2018-05-29 17:25:48

你探索过SitePrism吗?

SitePrism为您提供了一个简单、干净和语义的DSL,用于使用模式来描述您的站点,并与Capybara一起用于自动验收测试。

票数 1
EN

Stack Exchange QA用户

发布于 2018-05-30 11:13:48

POM是web应用程序的一个模型,因此,如果您有一个复杂的应用程序,该模型将自然地反映这一点。我参与了web应用程序的测试,包括许多页面对象(几十个,如果不是更多)、大型表单以及执行测试所需的许多步骤--这可能是有挑战性的,但也是可能的。我的示例基于Java,但应该适用于任何OO语言。

我应该把每一步/每一页都变成一门课吗?

我会说是的,你应该把每一页都变成一门课。这通常有助于提高可维护性和可读性。Protip:如果您还没有考虑它,那么考虑使用usecases,作为步骤定义和页面对象之间的一个层。

页面对象可能有enterUsername()、enterPassword()、clickSubmit()等方法。名为CreateUserUC的usecase可能有像createUser()这样的方法来调用前面提到的页面对象方法。最后,您的步骤定义将调用createUserUC.createUser(name,pass)。这不是最好的例子,但我看到它有助于方法的可重用性,特别是在有许多步骤和表单出现在工作流的各个阶段的情况下。

在有大量表单的页面中,每个“输入”应该是一个定义/方法吗?

我也会说是的,每个输入都有一个设置器。同样,这有助于维护性。不过,请考虑以下示例表格。

  • 列表项目
  • firstName
  • middleName
  • lastName
  • addressLine1
  • addressLine2
  • addressLine3

在这里,我们可以很容易地抽象出一个名称对象和一个地址对象。在本例中,我将为这两个对象创建类,而Page对象将包含以下方法:

  • 公共无效enterName(名称)
  • 公开无效enterAddress(地址)
  • 私有空enterFirstName(String firstName)
  • 私有空enterMiddleName(String middleName)
  • 私有空enterLastName(String lastName)
  • 私有空enterAddressLine1(String addressLine1)
  • 私有空enterAddressLine2(String addressLine2)
  • 私有空enterAddressLine3(String addressLine3)

前两个方法将调用私有方法。人们可能会说这是过度杀戮,但在我的经验中,过度杀戮比没有足够的结构和足够的灵活性来改变要安全。

还是应该用构造函数中定义的所有输入初始化类?

我当然不会建议采取这种做法,因为我说过,我能理解这一呼吁。可以隐藏在usecase方法中设置所有字段的详细信息。通常,我认为页面对象的构造函数应该用于设置页面模型,如果需要做任何事情,那么与页面的任何交互(比如填写表单)都应该在构建后调用方法来完成。这有助于提高可维护性。

由于页面主要是表单+提交button....what,所以类中的方法应该是吗?

这是web应用程序的标准。页对象的方法应遵循以下内容:

  • 公共空enterFirstName(String firstName)
  • 公共无效enterName(名称)
  • 公共字符串getErrorMessage()
  • 公开无效checkSuccessMessagePresent()
  • 公开无效clickSubmit()

因为创建小部件的“脚本”是7-8个不同的steps...would,所以我只是在脚本中创建7-8个不同的POM对象?

是。我想说,上面的例子应该会有帮助,所以我将用以下几个例子来总结:

  • 考虑一下使用。它们应该足够高,足够简洁,但也应该足够低,这样您就可以重用它们,并且它们提供了价值。
  • 考虑将表单中输入的对象抽象出来,尝试使用每个表单(firstName等)的详细信息(地址、名称)进行更多操作。
  • 查找web应用程序中常见的项,可能会重用某些类型的表单。您可以有一个部分页对象,然后一个页面对象可能包含几个部分页对象。
  • 记住,web应用程序可能会有规律的变化,所以尝试编写干净的代码,让每个方法只做一件事。
票数 1
EN
页面原文内容由Stack Exchange QA提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://sqa.stackexchange.com/questions/33959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档