2011-11-03 79 views
22

在建模页面对象时,如何处理具有窗体和大约50个输入字段的页面?这里最好的做法是什么?Selenium中的页面对象模型最佳实践

你会创建一个页面对象并为每个输入操作写一个单独的函数吗?或者你会写一个函数的参数传递给它并输入文本?

例如

public void enterFirstName(String firstName) { 
    driver.type("firstNameField", firstName); 
} 

public void enterSecondName(String secondName) { 
    driver.type("secondNameField", secondName); 
} 

public void fillInForm(String inputFieldName, String text) { 
    driver.type(inputFieldName, text); 
} 

我可以在第一模型中看到,编写测试时,测试是更具描述性的,但如果页面包含了太多的输入字段,创建页面对象变得麻烦。

这篇文章也是在页面构建Selenium测试挺有意思的对象 Functional Automated Testing Best Practices with Selenium WebDriver

+0

看看[我的stackoverflow问题](http://stackoverflow.com/questions/8149808/whats-the-best-way-to-use-selenium-pageobject-design-pattern)为例如何我将要使用页面对象设计模式。 我不是100%的自己,但从很多阅读,我敢肯定我的正确路线,希望我粘贴帮助你。 –

+0

http://selenium-tutorial.blogspot.com/2012/06/webdriver-page-objects-pattern.html –

+1

您可以将所有类似的WebElement类型放入列表中。所以,如果您有40个文本字段可以从列表中逐一绘制,请获取“名称”或“ID”以标识它,然后对其进行操作。 – djangofan

回答

9

我总是喜欢把任务分配的相关信息组。例如,如果我有一个用户类,我可能会将它分解为几个较小的类:LoginCredentials,ProfileInfo,Settings等,但我仍然通常拥有包含这些子类的顶级用户类。

我肯定会推荐的一件事是将对象传递给一个FillForm函数,而不是所有这些单独的函数。使用这种方法有很多优点。一个,你可以有一些用于许多测试用例的“通用”预配置对象。例如:

public class FormInfo 
{ 
    string Domain; 
    string Name; 
    string Category; 
    // etc... 

    public FormInfo(string domain, string name, string category) 
    { 
    Domain = domain; 
    Name = name; 
    Category = category; 
    // etc... 
    } 
} 


// Somewhere in your initialization code 
public static FormInfo Info1 = new FormInfo("myDomain1", "myName1", "myCategory1"); 
public static FormInfo Info2 = new FormInfo("myDomain2", "myName2", "myCategory2"); 

You can still update one of your common merchants if you need to do something one-off: 

// In your test case: 
Info1.Category = "blah"; 
FormPage.FillForm(Info1); 

或者,您可以根据需要为特定测试用例创建一个全新的商户对象。你也可以做这样的事情字段验证或者使用这些对象,或者我通常做的是打破特定字段验证的页面对象模式,所以如果我验证商家域场我可以这样做:

Info1.Domain = null; //This should make the FillForm function skip doing anything with this field. 
FormPage.FillForm(Info1); 
FormPage.DomainTextBox.Text = "field validation string"; 

这种方法的另一个重要优点是,如果页面被更新以添加,删除或修改字段,则只需要更新FormInfo对象和FillForm函数,并且不需要修改调用FillForm函数的特定测试用例 - 假设他们正在使用您的一个常见的FormInfo对象。获得更多覆盖的另一种可能性是设置一个常用的FormInfo对象,以便为每个符合最小/最大长度的字段生成随机字符串,并在所有不同的允许字符之间循环。这允许你从同一组测试中获得一些额外的测试,但是如果你只从特定的字符串开始获得失败结果,它也会增加一些噪音,所以要小心。

9

的页面对象模型背后的想法是,它抽象的实现从调用者了。在第一种机制中,你成功地这样做了,因为调用者不需要知道html输入字段名称是否从“firstName”更改为“user_first_name”,而在第二个实现中,对实际页面的任何更改都必须是流传给你的页面对象的所有调用者。

尽管在创建页面对象时可能需要更多的工作,但如果您维护封装,那么当真正的HTML页面不可避免地发生变化时,它将长期保存工作。

+0

谢谢digitalJoel, 如何创建在页面顶部定义了公共定位器变量(how)的页面,然后在我的Test类中,我实例化该页面,并将定位器变量传递给通用fillInform。从这个意义上讲,我的变量仍然位于一个位置,页面对象和我所有的测试都会引用这些变量,所以当它们发生变化时,我仍然需要维护一个位置。 –

+0

这将是一种方法。具有公共静态最终字段的名称,然后提供一种方法。直到你需要为一个值做一些特殊的处理,然后你有一个单独的方法来处理'myPage.setSpecialValue(blah)'和其他你有'myPage.fillInForm(MyPage.MY_NAME,blah)'的东西,它是不一致,但这可能是一个桥梁,你可以跨越/如果你来到它,而不是现在建立它。随你便。 – digitaljoel

+2

最好的“谢谢”是投票回答一些问题。在你的问题的14个答案中,你只有最多4个答案,并且没有接受任何答案。我不是在谈论我的答案,但是任何你认为有用的答案(比如山姆伍兹关于这个问题的答案)都可以/应该被提高。 – digitaljoel

0

我在表单中这样做的方式是获取页面上所有输入的列表。然后删除任何未显示的输入元素。之后,我可以将有效或无效的文本输入到每个输入中。从那里我收到验证总结,以确保我得到正确的错误或不。如果没有,则记录异常。

这样做的作用是允许我将文本输入到页面上的尽可能多的输入,它仍然允许我记录异常并通过电子邮件发送它们。我也在我的列表中捕获textareas和密码字段,并且我有一个单独的复选框字段和选项列表,因为我通常需要对这些字段进行不同的操作。

什么它归结为是我必须做的测试页面是这样的:

for (int i = 0; i < inputs.Count(); i++) 
{ 
    //This captures the error message string created in the input validation method 
    //nextButton is the IWebElement of the button to click to submit the form for validation 
    //ErrorMessageID is the ID of the Validation Summary display box (i.e. ErrorMessageID = "FormSummary" <asp:ValidationSummary ID="FormSummary" runat="server" CssClass="errorMessage" /> 

    string InputValidationText = utilities.InputValidation(driver, inputs, i, nextButton, ErrorMessageID) 
    if(InputValidationText != string.Empty) 
    { 
    //LogError 
    } 
} 
1

除了你enterWhatever()方法,我平时也创造一个createWhatever(field1, field2, ...)方法,我可以作为一个快速路径来创建任何形式建立,使用时测试的真正目的是别的东西使用。因此,如果我需要创建一个客户来测试提交工单,那么测试将转到CreateACustomer页面,并调用createCustomer(firstName, lastName, emailAddress, ...),然后继续进行使用该客户创建工单的更细微的任务。

1

我回答读者的利益的老问题。

除了这里的其他好的答案,我想在这里为那些刚接触POM的人添加一些建议。

页面对象是众所周知的设计模式,被自动化工程师广泛接受,为应用程序的每个页面创建单独的类文件,以将所有元素作为属性及其行为/业务功能作为类的方法进行分组。但是在为页面创建类时几乎没有问题 - 尤其是当页面具有更多/不同的元素集合/复杂元素(如网格/日历窗口小部件/ HTML表格等)时。

该类可能包含太多的责任处理。它应该重组并分解成更小的类。即,继Single Responsibility Responsible

查看图片这里的想法。

enter image description here

也就是说,创建可重用的页面片段&让主网页对象提供页面片段。

检查here了解更多信息。