因此,在构建自动化框架时,我一直在研究。大多数示例都是用Java完成的,但是由于im在Rails中使用Capybara和Selenium (Ruby),我想我没有理由也不能使用POM。
不过,我看到的大多数POM示例都是简单的东西,比如登录/etc.,我遇到的问题是,开发框架的Web应用程序im并不那么简单。
当我想到POM时,从我所知道的情况来看,每个"Page“都是一个单独的类。然而,在这个应用程序中,创建一个我们称之为"Widget“的过程是一个7-8步的过程。有时,Page可以是15+项。这就是我困惑的地方,还有以下几个问题:
发布于 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文件,例如(示例)
# 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对象中的方法:
# 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对象的规范中:
describe "some test" do
p = PageObject.new
然后在测试本身中,我使用Page对象,如下所示:
...
select 'JAN', from: p.dob_month
fill_in p.dob_day, with: '01'
fill_in p.dob_year, with: '1978'
...
在另一个级别上,您可能也提到了这个级别,我创建了自定义命名方法,以抽象出详细信息,并得到如下所示的DSL:
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对象是一种可以有几个实现的方法。
发布于 2018-05-29 17:25:48
你探索过SitePrism吗?
SitePrism为您提供了一个简单、干净和语义的DSL,用于使用模式来描述您的站点,并与Capybara一起用于自动验收测试。
发布于 2018-05-30 11:13:48
POM是web应用程序的一个模型,因此,如果您有一个复杂的应用程序,该模型将自然地反映这一点。我参与了web应用程序的测试,包括许多页面对象(几十个,如果不是更多)、大型表单以及执行测试所需的许多步骤--这可能是有挑战性的,但也是可能的。我的示例基于Java,但应该适用于任何OO语言。
我应该把每一步/每一页都变成一门课吗?
我会说是的,你应该把每一页都变成一门课。这通常有助于提高可维护性和可读性。Protip:如果您还没有考虑它,那么考虑使用usecases,作为步骤定义和页面对象之间的一个层。
页面对象可能有enterUsername()、enterPassword()、clickSubmit()等方法。名为CreateUserUC的usecase可能有像createUser()这样的方法来调用前面提到的页面对象方法。最后,您的步骤定义将调用createUserUC.createUser(name,pass)。这不是最好的例子,但我看到它有助于方法的可重用性,特别是在有许多步骤和表单出现在工作流的各个阶段的情况下。
在有大量表单的页面中,每个“输入”应该是一个定义/方法吗?
我也会说是的,每个输入都有一个设置器。同样,这有助于维护性。不过,请考虑以下示例表格。
在这里,我们可以很容易地抽象出一个名称对象和一个地址对象。在本例中,我将为这两个对象创建类,而Page对象将包含以下方法:
前两个方法将调用私有方法。人们可能会说这是过度杀戮,但在我的经验中,过度杀戮比没有足够的结构和足够的灵活性来改变要安全。
还是应该用构造函数中定义的所有输入初始化类?
我当然不会建议采取这种做法,因为我说过,我能理解这一呼吁。可以隐藏在usecase方法中设置所有字段的详细信息。通常,我认为页面对象的构造函数应该用于设置页面模型,如果需要做任何事情,那么与页面的任何交互(比如填写表单)都应该在构建后调用方法来完成。这有助于提高可维护性。
由于页面主要是表单+提交button....what,所以类中的方法应该是吗?
这是web应用程序的标准。页对象的方法应遵循以下内容:
因为创建小部件的“脚本”是7-8个不同的steps...would,所以我只是在脚本中创建7-8个不同的POM对象?
是。我想说,上面的例子应该会有帮助,所以我将用以下几个例子来总结:
https://sqa.stackexchange.com/questions/33959
复制相似问题