Selenium -最佳实践-页面对象模式&页面工厂

本文关键字:模式 工厂 对象 面对 最佳 -页 Selenium | 更新日期: 2023-09-27 18:13:05

我已经从0开始开发我的项目1年了。我已经达到了一定程度的框架和测试的"维护"。然而,每天我都有更多的怀疑我是否在我的项目中使用了良好的实践。如果有经验的人能回答我的一些问题,那就太好了。大多数情况下,我对页面对象模式和页面工厂有疑问。

简短描述:

My Project是一个用c#、angular.js、javascript编写的单页应用程序。驱动程序是一个静态实例,它有一堆额外的方法(在下面的代码我只显示2)。每个页面是一个静态实例初始化的页面类。由于以上原因,我不需要初始化测试类中的对象。

问题列表:

  1. 在Pages.cs中初始化静态实例是好方法吗?在我看来,当我这样做的时候,[测试]更可赎回。

  2. 使用PageObject库的"真正"优势是什么?只是变量的命名?"[FindsBy (= How.Id)]"?

  3. 使用PageFactory的"真正"优势是什么?

在我真正的项目中,我有一个基类,其中子类继承和所有子类的通用方法都写在PageBase.cs中。所以我没有重复代码的问题。

现在我已经在每个页面中实现了Singleton,所以它类似于下面代码中使用的方法(不同的只是初始化PageObject的方式)

#region Signleton
private static StartPage instance;
private StartPage()
{
}
public static StartPage Instance
{
    get
    {
        if (instance == null)
        {
            instance = new StartPage();
        }
        return instance;
    }
}
#endregion
  • 然而,在[测试]我必须使用变量名"实例",它不是那么可读的方法与初始化pagescs中的PageObject。你同意吗?
  • 单例实例
    StartPage.Instance.Search();
    

    方法概念:

    Browser.cs

    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    namespace SeleniumTestFramework
    {
        public static class Browser
        {
            public static IWebDriver Driver { get; set; }
            public static bool Initialised { get; set; }
            public static void Initialize()
            {
                string chromeDriverDirectory = @"C:'chromedriver_win32";
                Driver = new ChromeDriver(chromeDriverDirectory);
                Initialised = true;
            }
            public static void Quit()
            {
                Driver.Quit();
                Initialised = false;
            }
        }
    }
    

    LoginPage.cs

    using OpenQA.Selenium;
    namespace SeleniumTestFramework.Pages
    {
        public class LoginPage
        {
            private IWebElement screenLogin = Browser.Driver.FindElement(By.Id("onScreenLogin"));
            public void OpenLoginModal()
            {
                screenLogin.Click();
            }
        }
    }
    

    LoginModal.cs

    using OpenQA.Selenium;
    namespace SeleniumTestFramework.Pages
    {
        public class LoginPage
        {
            private IWebElement screenLogin = Browser.Driver.FindElement(By.Id("onScreenLogin"));
            public void OpenLoginModal()
            {
                screenLogin.Click();
            }
        }
    }
    

    StartPage.cs

    using OpenQA.Selenium;
    namespace SeleniumTestFramework.Pages
    {
        public class StartPage
        {
            private IWebElement surenameInput = Browser.Driver.FindElement(By.CssSelector(".id_surname_startpage_testId + input"));
            private IWebElement searchButton = Browser.Driver.FindElement(By.CssSelector(".search-button.search-customer"));
    
            public void Search()
            {
                surenameInput.SendKeys("1");
                searchButton.Click();
            }
        }
    }
    

    Pages.cs

    namespace SeleniumTestFramework.Pages
    {
        public static class Pages
        {
            public static LoginPage LoginPage
            {
                get
                {
                    var loginPage = new LoginPage();
                    return loginPage;
                }
            }
            public static LoginModal LoginModal
            {
                get
                {
                    var loginModal = new LoginModal();
                    return loginModal;
                }
            }
            public static StartPage StartPage
            {
                get
                {
                    var startPage = new StartPage();
                    return startPage;
                }
            }
        }
    }
    

    Tests.cs

    using NUnit.Framework;
    using SeleniumTestFramework;
    using SeleniumTestFramework.Pages;
    using OpenQA.Selenium.Support.PageObjects;
    using System.Threading;
    namespace SeleniumTest
    {
        [TestFixture]
        public class Tests
        {
            [SetUp]
            public void Before()
            {
                if (!Browser.Initialised) Browser.Initialize();
                Browser.Driver.Navigate().GoToUrl("http://localhost:8080/client/");
            }
            [TearDown]
            public void After()
            {
                Browser.Quit(); 
            }
            [Test]
            public void Test_without_static()
            {
                LoginPage loginPage = new LoginPage();
                loginPage.OpenLoginModal();
                LoginModal loginModal = new LoginModal();
                loginModal.Login();
                StartPage startPage = new StartPage();
                startPage.Search();
            }
            [Test]
            public void Test_with_static()
            {
                Pages.LoginPage.OpenLoginModal();
                Pages.LoginModal.Login();
                Pages.StartPage.Search();
            }
        }
    }
    

    Selenium -最佳实践-页面对象模式&页面工厂

    有很多要讨论的。我们开始吧。

    1. Page Object框架的真正优点是将特定于页面的信息隔离在一个地方。这使得查找和维护这些信息变得更加简单。跨页面通用的代码可以放在帮助器或模块文件中。这段通用代码没有绑定到任何页面的细节,所以当WebElement的finelement (By)发生变化时,这段通用代码不会受到影响。

    2. 如果你不这样做,那就太疯狂了。
    3. PageFactory有三个部分。前两个在特定于页面的类中定义。它们是@FindBy实例,定义了如何访问页面上定义的有用的web元素。这使得它们更容易被发现和维护。接下来是定义为方法的受支持的测试人员操作。这些方法使用@FindBy实例,这使得它们不受FindBy实例更改的影响。

      public class HomePage { 
        final WebDriver driver;
        @FindBy(how = How.NAME, using = "text") private WebElement helloText;
        @FindBy(how = How.NAME, using = "exit") private WebElement exitButton;
      public HomePage(WebDriver driver) {
        this.driver = driver;
      }
      public void clickExitButton() {
        exitButton.click();
      }
      

      }

    3(续)。现在,在实际的测试脚本(Cucumber中的步骤定义文件)中,您通过首先使用PageFactory初始化页面实例,然后调用针对该页面实例定义的测试操作方法来调用这些操作。所以

    public class HomePageExitTest extends TestCase {
      WebDriver driver;
      @Before public void setUp() throws Exception {
        driver = new FirefoxDriver();
      }
      @Test public void testHomeExit() throws Exception {
        driver.get("yoursite.com");
        HomePage homePage = PageFactory.initElements(driver, HomePage.class);
        homePage.clickExitButton();
      }
      @After public void tearDown() throws Exception {
        driver.quit();
      }
    }
    

    参见本教程http://www.intexsoft.com/blog/item/34-selenium-webdriver-page-object-pattern-and-pagefactory.html