使用Selenium PageObject设计模式的最佳方法是什么

Pat*_*gee 29 c# design-patterns webdriver pageobjects selenium-webdriver

我正在使用Selenium 2 Web Driver和C#.Net创建测试.在阅读了很多Selenium文档之后,我仍然不确定如何使用PageObject设计模式进行测试.

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

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

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

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

目前这就是我目前正在使用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);
    }

 }
Run Code Online (Sandbox Code Playgroud)

我找到的关于selenium webdriver设计模式的大多数文章和博客文章都给我发现的先前帖子带来了矛盾.

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

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

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

在我的LoginPage里面

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);
    }
Run Code Online (Sandbox Code Playgroud)

并且,当然要显示我的HomePage应该如何使用其构造函数启动:

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);
    }
Run Code Online (Sandbox Code Playgroud)

如何有效地使用WebDriver PageObject设计模式进行测试.我无法弄清楚这一点.

Bol*_*ler 18

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

public class Page
{
    public IWebDriver _driver;

    public Page(IWebDriver driver)
    {
        this._driver = driver;
        PageFactory.InitElements(_driver, this);
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅PageFactory文档

  • 问题,如果元素是页面对象中的"选择"(下拉列表),你会怎么做?我被告知你不能使用pageobject for select(dropdownlist)是真的吗? (4认同)