使用 Selenium PageObject 设计模式的最佳方法是什么 [英] What's the best way to use Selenium PageObject Design Pattern

查看:17
本文介绍了使用 Selenium PageObject 设计模式的最佳方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Selenium 2 Web 驱动程序和 C#.Net 创建测试.在阅读了大量 Selenium 文档后,我仍然不确定如何使用 PageObject 设计模式进行测试.

I'm creating tests using Selenium 2 Web Driver with C#.Net. After reading through a lot of the Selenium documentation, I am left still feeling unsure on how to go about testing using the PageObject design patterns.

许多 selenium 示例仅在 Java 中显示,并且 .Net 的 API 绑定并不总是像人们想象的那样相似,这是由于某些语言设置的限制和标准.

Many of the selenium examples are only shown in Java and the API bindings for .Net are not always as similar as one would think they are due to limitations and the standards set by certain languages.

在 .Net Selenium Web Driver 中将 PageObject 设计模式与 PageFactory 结合使用的最佳方式是什么?

What is the best way to use the PageObject design pattern with PageFactory in .Net Selenium Web Driver?

最终,我希望我的 PageObjects 处理更多功能,而不是使用 PageObject IWebElements 进行 NUnit 测试.

Eventually, I want my PageObjects to handle more functionality, rather than my NUnit tests using the PageObject IWebElements.

以下是我目前将如何创建测试的示例.

Below is an example of how I am currently going to create my tests moving forward.

public class LoginPage
{
    private IWebDriver webDriver;

    [FindsBy(How = How.Id, Using = "ctl00_ctl00_ctl00_insideForm_insideForm_content_txtPassword")]
    public IWebElement Password { get; set; }

    [FindsBy(How = How.Id, Using = "ctl00_ctl00_ctl00_insideForm_insideForm_content_cmdSubmit")]
    public IWebElement SubmitButton { get; set; }

    [FindsBy(How = How.Id, Using = "ctl00_ctl00_ctl00_insideForm_insideForm_content_txtUserName")]
    public IWebElement UserName { get; set; }

    public LoginPage() { }

    public LoginPage(IWebDriver webDriver)
    {
        this.webDriver = webDriver;


        if(!webDriver.Url.Contains("Login.aspx"))
        {
            throw new StaleElementReferenceException("This is not the login page");
        }
        PageFactory.InitElements(webDriver, this);
    }

    public HomePage signIn(string username, string password)
    {
        UserName.SendKeys(username);
        Password.SendKeys(password);
        SubmitButton.Submit();

        // Even if i create a NUnit test for this
        // Issue with page loading still occures when I try and return new object
        HomePage homePage = new HomePage(webDriver);
        PageFactory.InitElements(webDriver, homePage);
        return homePage;
    }
}

目前这是我目前正在使用 NUnit 做的事情:

At the moment this is what I am currently doing with NUnit:

[TestFixture]
public class LoginPageTest : TestBase
{
    private IWebDriver driver;
    private LoginPage loginPage;
    private HomePage homePage;

    [SetUp]
    [Description("Sets up the test fixture page objects and navigates to the login page.")]
    public void SetUp()
    {
        driver = StartDriver();
        Log.Info("Driver started");
        driver.Navigate().GoToUrl("http://" + Environment + ");
        loginPage = new LoginPage();
        PageFactory.InitElements(driver, loginPage);
        //driver.Navigate().Refresh();
    }

    [Test]
    [Description("Enters invalid credentials and asserts that a correct error message is displayed.")]
    public void SubmitFormInvalidCredentials()
    {
        loginPage.UserName.SendKeys("invalid");
        loginPage.Password.SendKeys("invalid");
        loginPage.SubmitButton.Click();
        IWebElement invalidCredentials = driver.FindElement(By.Id("ctl00_ctl00_ctl00_insideForm_insideForm_ctl02_title"));
        Assert.AreEqual("Invalid user name or password", invalidCredentials.Text);
    }

    [Test]
    [Description("Enters valid credentials and asserts that the user is taken to the home page.")]
    public void SubmitFormValidCredentials()
    {
        loginPage.UserName.SendKeys("valid");
        loginPage.Password.SendKeys("valid");
        loginPage.SubmitButton.Click();

        homePage = new HomePage();
        PageFactory.InitElements(driver, homePage);
        Assert.AreEqual("pattest", homePage.Username.Text);
    }

 }

我为 selenium webdriver 设计模式找到的大多数文章和博客文章都与我发现的以前的文章相矛盾.

Most of the articles and blog posts I find for selenium webdriver Design Patterns give off contradictions to previous posts I find.

那么,正确的方法是什么?

So, what is the right way?

最重要的是,我什至尝试了 PageObject 设计模式.

To top this off, I even gave the PageObject design pattern a try.

    [Test]
    [Description("Login using PageObject Design Pattern")]
    public void Login()
    {
        loginPage = new LoginPage(driver);
        HomePage signIn = loginPage.SignIn("pattest", "pattest");
    }

在我的登录页面中

public LoginPage(IWebDriver driver)
    {
        this.driver = driver;

        if (!driver.Url.Contains("Login.aspx"))
        {
            throw new ElementNotFoundException("This is not the login page");
        }
        PageFactory.InitElements(driver, this);
    }

    public HomePage SignIn(string username, string password)
    {
        UserName.SendKeys(username);
        Password.SendKeys(password);
        SubmitButton.Click();
        return new HomePage(driver);
    }

而且,当然要展示我的主页应该如何使用它的构造函数来启动:

And, of course to show how my HomePage should be initiated with its Constructor:

public HomePage(IWebDriver d)
    {
        webDriver = d;
        // I need to use this as its not freaking waiting for my Page to load when I pass the webdriver in the consturctor.
        var wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(60));

        try
        {
            wait.Until(driver => driver.FindElement(By.Id("ctl00_ctl00_ctl00_insideForm_insideForm_loginStatus")));
        }
        catch(Exception e)
        {
            throw new ElementNotFoundException("This is not the home page.");
        }
        PageFactory.InitElements(webDriver, this);
    }

如何在测试中有效地使用 WebDriver PageObject 设计模式.我想不通.

How do I use WebDriver PageObject design pattern effectively with testing. I can't figure this out.

推荐答案

使用PageFactory.InitElements(_driver, this);在您的基页类的构造函数上:

Use PageFactory.InitElements(_driver, this); on the constructor of your base page class:

public class Page
{
    public IWebDriver _driver;

    public Page(IWebDriver driver)
    {
        this._driver = driver;
        PageFactory.InitElements(_driver, this);
    }
}

请参阅 PageFactory 文档

这篇关于使用 Selenium PageObject 设计模式的最佳方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆