本文介绍了Selenium-最佳做法-Page Object Patter&页面工厂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从0开始的1年以来,我一直在开发自己的项目.我已经达到了对框架和测试的一定程度的维护".但是,每天我都会怀疑我是否在自己的项目中使用了良好的做法.如果有经验的人可以回答我的几个问题,那就太好了.通常,我对页面对象模式和页面工厂有疑问.

I've been developing my Project since 1 year from 0. I've reached certain level of 'maintenance' of my Framework and tests.However, each day i have more doubts if i'm using good practices in my Project. Would be great if someone experienced could answer for few my questions. Mostly i have questions for Page Object Patter and Page Factory.

简短说明:

我的项目是一个用C#,angular.js和javascript编写的基于一页的应用程序.驱动程序是一个静态实例,它具有许多其他方法(在下面的代码中,我仅显示2).每个页面都是在Pages类中初始化的静态实例.由于上述原因,我不必初始化Tests类中的对象.

My Project is a one-page based application written in C#, angular.js, javascript. Driver is a static instance and it has bunch of additional mehtods(in below code i've only show 2). Each page is a static instance initialized in Pages class.Due to above i don't have to initialize the objects in Tests class.

问题列表:

  1. 在Pages.cs中初始化静态实例是一种好方法吗?我认为[Test]以这种方式更易于重用.

  1. Is it good approach to Initialize static instance in Pages.cs ? In my opinion the [Test] are more redeable when i'm doing it in such way.

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

What are the "real" advanteges of using PageObject library? Only the naming of variables? "[FindsBy(How=How.Id)]" ?

使用PageFactory的真正"优势是什么?因为我没有找到任何东西,也没有找到我的项目,所以没用.

What are the "real" advanteges of using PageFactory? Because i didn't find any or for my project it's useless.

在我的真实项目中,我有一个基类,子类从该基类继承而来,所有子类的通用方法都写在PageBase.cs中.所以我对重复的代码没有问题.

In my real Project i have a Base class from which child classes are inheriting and common methods for all child classes are written in PageBase.cs. So i have not problem with duplicated code.

现在我已经在每个Page中实现了Singleton,因此它与下面的代码中使用的方法类似(区别只是初始化PageObject的方式)

Right now i've implemented Singleton in each Page, so it's similiar to the appraoch used in code below (the difference is only the way of initialization the PageObject)

#region Signleton
private static StartPage instance;

private StartPage()
{
}

public static StartPage Instance
{
    get
    {
        if (instance == null)
        {
            instance = new StartPage();
        }

        return instance;
    }
}
#endregion
  1. 但是,在[Test]中,我必须使用变量名"Instance",它不像在Pages.cs中初始化PageObject的方法那样易读.你同意吗?
  1. However in [Test] i have to use the variable name "Instance" and it's not so readable as the approach with initializing the PageObject in Pages.cs.Do you agree?

单个实例

StartPage.Instance.Search();

方法的概念:

Browser.cs

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

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

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

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();
        }
    }
}

推荐答案

有点讨论.让我们开始吧.

Quite a bit to discuss. Lets make a start.

  1. 我想这是一个品味问题.

  1. I suppose that it is a matter of taste.

页面对象框架的真正优势在于,您可以将页面特定信息隔离在一个地方.这样可以直接查找和维护此信息.跨页面通用的代码可以放在帮助程序或模块文件中.该通用代码不依赖于任何页面的细节,因此,当WebElement的findElement(By)更改时,该通用代码不会受到影响.如果您考虑一下,不这样做就太疯狂了.

The real advantages of Page Object frameworks is that you isolate page specific information in one place. This makes finding and maintaining this information straight forward. Code that is common across pages can be placed in helper or module files. This common code is not tied to the specifics of any page so this common code is not impacted when a WebElement's findElement(By) changes. If you think about it, it would be crazy not to do it this way.

PageFactory包含三个部分.前两个在页面特定的类中定义.它们是@FindBy实例,它们定义如何访问该页面上定义的有用的WebElement.这些是第一位的,这使它们易于查找和维护.接下来是定义为方法的受支持的测试人员操作.这些方法使用@FindBy实例,这使它们不受FindBy实例更改的影响.

PageFactory has three parts. The first two are defined in the page specific class. They are the @FindBy instances that define how to access the useful WebElements defined on that page. These come first which makes them easy to find and maintain. Next come the supported tester actions defined as methods. These methods use the @FindBy instances which makes them unaffected by changes to the FindBy instances.

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初始化页面实例,然后调用针对该页面实例定义的测试操作方法来调用这些动作.所以

3 (cont). Now in the actual test script (step definition file in Cucumber) you invoke those actions by first using PageFactory to initialize a page instance and then invoking the test action methods that you defined against that page instance. So

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

这篇关于Selenium-最佳做法-Page Object Patter&页面工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 07:12