【问题标题】:Page object Model discussion页面对象模型讨论
【发布时间】:2016-12-21 17:54:35
【问题描述】:

我正在使用 Selenium 为我的网站构建一个测试框架,我真的想要您在使用页面对象模型时对良好实践的想法: 假设我有一个欢迎页面,其中包含一个存在注销按钮的标题,并且这个标题可以在我的大多数页面中看到 我认为最好为标题编写一个单独的类 像这样:

public class Header
    {
        [FindsBy(How = How.Name, Using = "user_profile")]
        public IWebElement BtnUserProfile{ get; set; }

        [FindsBy(How = How.ClassName, Using = "logout_button")]
        public IWebElement BtnLogout { get; set; }

        public void Logout()
         {
            BtnLogout.Click();
         }
    }

 public class LoginPage
    {
        [FindsBy(How = How.Name, Using = "username")]
        public IWebElement TxtbxUserName { get; set; }

        [FindsBy(How = How.Name, Using = "password")]
        public IWebElement TxtbxPassword { get; set; }

        [FindsBy(How = How.ClassName, Using = "button")]
        public IWebElement BtnSignIn { get; set; }


        public string GoTO()
       {
           Driver.Navigate().GoToUrl(LoginURL);
       }
        public void Login(string username, string password)
         {
            TxtbxUserName.SendKeys(username);
            TxtbxPassword.SendKeys(password);
            BtnSignIn.Click();
         }
        public bool IsAt()
         {
             return Driver.Url == LoginURL;
         }
    }

公开课WelcomePage

{
    [FindsBy(How = How.Name, Using = "welcome-message")]
    public IWebElement LblWelcomeMessage { get; set; }
}

我的问题是,您认为将标题作为属性包含在欢迎页面中更好还是应该将它们分开?

我们以 Logout 测试方法的代码为例:

案例一:

public void LogoutTest() {
    LoginPage loginpage = new LoginPage();
    loginpage.GoTo();
    loginpage.login("user", "pass");
    Header header = new Header();
    header.Logout();
    Assert.IsTrue(loginpage.IsAt());
}

案例 2:

public void LogoutTest() {
    LoginPage loginpage = new LoginPage();
    loginpage.GoTo();
    loginpage.login("user", "pass");
    WelcomePage wlcmPage = new WelcomePage();
    WelcomePage.Logout();
    Assert.IsTrue(loginpage.IsAt());
}

第二个问题是,您如何看待为驱动程序编写一个静态类而不是为每个页面编写一个单独的驱动程序。

第三个是你建议如何使用等待? 我正在考虑将此方法添加到我的驱动程序静态类中

public static void Wait(int seconds)
{
 Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(seconds));
}

任何想法都将受到高度赞赏

【问题讨论】:

    标签: c# selenium-webdriver


    【解决方案1】:

    这是我在开发框架时遵循的概念:

    • 为页眉和页脚创建单独的文件(因为它们对所有页面都是通用的,将它们作为单个页面的一部分是没有意义的)
    • 将常用元素(如搜索/返回/下一个等)保存在单独的文件中(这样做的目的是删除任何类型的重复并保持隔离逻辑)
    • 对于 Driver,最好创建一个单独的 Driver 类并将 Driver 保持为静态,以便可以跨所有页面访问它! (我的所有网页都扩展了 DriverClass)
    • PageObjects 中使用的函数被分解成尽可能小的块,记住调用它们的频率和方式(登录的方式 - 虽然登录可以分解为 enterUsername 和 enterPassword 函数,但仍然保留它作为 Login 函数更合乎逻辑,因为在大多数情况下,会调用 Login 函数而不是单独调用 enterUsername 和 enterPassword 函数)
    • 使用 PageObjects 本身将测试脚本与 elementLocators 隔离
    • 在单独的 utils 文件夹中有实用功能(如 DateUtil、excelUtils 等)
    • 在单独的 conf 文件夹中进行配置(例如设置需要运行测试的环境,配置输出和输入文件夹)
    • 在失败时合并 screenCapture
    • 在 DriverClass 中有一个静态等待变量,其中包含一些隐式等待时间
    • 始终尝试使用条件等待而不是静态等待,例如:wait.until(ExpectedConditions)。这样可以确保等待不会不必要地减慢执行速度。

    希望有帮助!

    【讨论】:

    • 非常感谢,您有更深入的建议吗?
    • 如果您编辑您的答案,以便对我在问题中添加的第三点有所了解
    • 希望这能回答你的问题
    • 隐式等待是否会减慢测试速度?据我所知,只要元素尚未加载,它就会导致驱动程序等待,并且当我使用隐式等待 5 秒时,例如,如果所有元素都被快速加载,整个测试只需要 2 秒
    • 不..我说的是,在显式等待中,条件显式等待比静态显式等待更好,这意味着使用 wait(timeout) 代替 wait.until(condition)
    【解决方案2】:
    • 根据 Sakshi Singla 的建议,页眉和页脚可以是
      分隔页面类。
    • 驱动程序类应单独定义,获取驱动程序方法必须设为 STATIC。这 原因是,如果您为驱动程序创建不同的实例,则 当 Flow 从 1 Page Class 变为 2nd 时,测试将失败 Page Class ,每次都会打开一个新的实例。
    • 将返回WebDriver实例的Driver方法设为静态。
    • 在页面类中,您可以选择在页面类的构造函数中调用这个静态驱动方法,并将其赋值给页面类的驱动变量。

    下面的代码只是一个表示代码,您可能需要再添加几行,例如页面工厂等。

    public class driverConfig{
    
    Static WebDriver driver;
    
    public Static WebDriver getDriver{
    
    driver = new WebDriver();
    //Navigate to the URL here
    return driver;
       }
    }
    
    public Class PageClass{
    
    public WebDriver driver;
    
    public PageClass(){
    driver = driverConfig.getDriver();
       }
    }
    

    【讨论】:

    • 谢谢 你不觉得使用静态类会好很多吗!这样您就不必将驱动程序传递给每个页面对象
    • 即使您将 Class 定义为 static ,您仍然必须在每个 Class 中调用驱动程序。类可以设为静态,或者返回驱动程序的方法可以是静态的。没有区别。
    猜你喜欢
    • 2019-03-09
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2019-06-16
    • 1970-01-01
    相关资源
    最近更新 更多