【问题标题】:Selenium C# Don't want to keep creating a new instance of FireFoxDriverSelenium C# 不想继续创建 FireFoxDriver 的新实例
【发布时间】:2016-05-06 08:40:35
【问题描述】:

我目前正在尝试为网站创建一些自动化测试,我遇到了一个问题,即每当我调用我的基类时,它都会创建一个新的 FirefoxDriver 实例。因此,每当我在我的步骤中调用一个继承基类的页面时,它都会加载一个新的驱动程序实例,因此它不再在以前的驱动程序上实现自动化。

namespace RAA_AutomationTests
{
    using OpenQA.Selenium.Firefox;

    public abstract class BasePage
    {
        protected static IWebDriver driver;

        protected BasePage()
        {
            //cant keep creating a new driver need to change this
            driver = new FirefoxDriver();
        }

        public void click(By locator)
        {
            Find(locator).Click();
        }

        public IWebElement Find(By locator)
        {
            //ValidateSelector(locator); will update css selectors, however not to cause any extra delays by checking this programmatically.

            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
            wait.Until(ExpectedConditions.ElementIsVisible(locator));

            return driver.FindElement(locator);
        }
    }
}

这是我的基类中的所有代码,我只需要找到一种使用已经打开的驱动程序而不是创建新驱动程序的方法。 我有一个钩子文件,它可以为我打开浏览器,所以我只需要基类中的驱动程序就可以使用它。

【问题讨论】:

  • “为我打开浏览器的钩子文件”意味着这是另一个通过 selenium 打开 Firefox 的类吗?
  • 是的,我有另一个文件,它使用 [BeforeScenario] 打开浏览器我只使用基类来实现点击和等待功能,但我需要告诉它使用哪个驱动程序才能使其工作。
  • 您在页面上继承基类,因此每次创建 Page 类的对象时都会创建 Firefox 对象。如此好的方法将您的浏览器配置方法与页面分开,它应该在测试类级别而不是页面类级别。
  • 你能给我举个例子吗?

标签: c# selenium selenium-webdriver instance specflow


【解决方案1】:

我不是 Page 对象的忠实拥护者(这严重违反了 SRP),但我认为您的设计可以使用一些不同的方法。看看Selenium的家page examples

 /**
 * Page Object encapsulates the Home         Page
 */
  public class HomePage {

    private WebDriver selenium;

    public HomePage(WebDriver selenium) {
            if (!selenium.getTitle().equals("Home Page of logged in user")) {
                    throw new IllegalStateException("This is not Home Page of logged in user, current page" +
                                    "is: " +selenium.getLocation());
            }
    }

    public HomePage manageProfile() {
            // Page encapsulation to manage profile functionality
            return new HomePage(selenium);
    }

    /*More methods offering the services     represented by Home Page
    of Logged User. These methods in   turn might return more Page Objects
    for example click on Compose mail  button could return ComposeMail class object*/

 }

正如您所见,没有理由在您的页面中保留静态实例,相反,您可以为 WebDriver 对象使用IoCConstructor DI

如果必须这样做,我会通过Factory 创建驱动程序,将操作(单击、键入等)放在 Actions 类中,并尽可能保持 Pages 没有此类逻辑。

【讨论】:

    【解决方案2】:

    最简单的解决方案是在另一个地方创建一个 webdrive 实例,并通过构造函数将它传递给您的基类。

    所以在测试类中你应该创建一个新的驱动程序(可能在 SetUp 夹具中)并将它传递给你的基类的构造函数:

    driver = new FireFoxDriver();
    BasePage base = new BasePage(driver);
    

    在您的基类中,构造函数应该是:

    public class BasePage(IWebDriver driver)
    {
       this.driver = driver;
    }
    

    这会解决你的问题。

    还要考虑更繁重但可能更好的方法 - 创建 WebDriver Factory。此处显示如何使用 C# 进行操作:https://github.com/FriendlyTester/WebDriverFactoryExample/blob/master/WebDriverDriverFactory/WebDriverDriverFactory/WebDriverFactory.cs

    【讨论】:

      【解决方案3】:

      从 Java 的角度来看,假设我有一个可以打开浏览器的类

      public class Hook {
      
      public static WebDriver driver;
      
      @BeforeSuite
      public void startBrowser(){
      
          driver=new FirefoxDriver();
      }
      
      }
      

      要在另一个类中使用这个浏览器,我只需将它继承到其他类,我不会在这些类中启动任何驱动程序。

      公共类 TestClass 扩展 Hook {

      @Test
      public void toNavigate(){
          driver.get("http://www.myurl.com");
      }
      
      }
      

      另一种方法是在 Hook 中创建一个方法,该方法返回驱动程序并需要在另一个类中收集该驱动程序

      Hook 中类似的东西

        public WebDriver startBrowser(){
      
          return driver=new FirefoxDriver();
      }
      

      在其他类中获取此驱动程序

       public class TestClass {
      
      WebDriver driver;
      
      @Test
      public void toNavigate(){
          Hook h=new Hook();
          driver=h.startBrowser();
          driver.get("http://www.myurl.com");
      }
      
      }
      

      谢谢你, 壁画

      【讨论】:

      • 让我有一个简单的测试用例,你是如何调用这些类的。看起来一切都很好,并且可以很好地使用 startBrowser 和 BeforeScenario 不同的类,因为一个是可重用的方法,另一个是在执行之前开始的方法。在 java 中,我们通常将此 BeforeScenario 扩展到其他类
      猜你喜欢
      • 2012-05-29
      • 1970-01-01
      • 2018-05-26
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2014-11-24
      • 2019-07-15
      相关资源
      最近更新 更多