【发布时间】:2015-09-17 10:53:25
【问题描述】:
从 0 年开始,我一直在开发我的项目。我的框架和测试已经达到了一定的“维护”水平。 但是,每天我都会怀疑我是否在我的项目中使用了良好的实践。如果有经验的人可以回答我的几个问题,那就太好了。主要是我对页面对象模式和页面工厂有疑问。
简短说明:
My Project 是一个基于单页的应用程序,用 C#、angular.js、javascript 编写。驱动程序是一个静态实例,它有一堆额外的方法(在下面的代码中,我只显示了 2)。每个页面都是在 Pages 类中初始化的静态实例。 由于上述原因,我不必初始化 Tests 类中的对象。
问题列表:
在 Pages.cs 中初始化静态实例是一种好方法吗?在我看来,当我以这种方式进行时,[Test] 更容易重复。
使用 PageObject 库的“真正”优势是什么?只有变量的命名? “[FindsBy(How=How.Id)]”?
使用 PageFactory 的“真正”优势是什么?因为我没有找到任何东西,或者对我的项目没有用。
在我的真实项目中,我有一个基类,子类从中继承,所有子类的通用方法都写在 PageBase.cs 中。所以我没有重复代码的问题。
现在我已经在每个Page中实现了Singleton,所以它与下面代码中使用的方法类似(不同之处只是初始化PageObject的方式)
#region Signleton
private static StartPage instance;
private StartPage()
{
}
public static StartPage Instance
{
get
{
if (instance == null)
{
instance = new StartPage();
}
return instance;
}
}
#endregion
- 但是在 [Test] 中,我必须使用变量名称“Instance”,而且它的可读性不如在 Pages.cs 中初始化 PageObject 的方法。 你同意吗?
单例实例
StartPage.Instance.Search();
方法的概念:
浏览器.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();
}
}
}
【问题讨论】:
-
我投票结束这个问题,因为它应该被迁移到 corereview.stackexchange.com
-
这是一个很好的问题......它只是不适合 Stack Overflow 网站。
-
问你一个问题..如果明天你需要并行化你的测试,你将如何实现你的浏览器实例是静态引用? (眨眼).. 建议总是使用组合而不是继承给你更多的灵活性而不是可读性
标签: c# selenium-webdriver automated-tests pageobjects