【问题标题】:Selenium WebDriver Factory picking same driverSelenium WebDriver Factory 选择相同的驱动程序
【发布时间】:2025-12-02 22:00:01
【问题描述】:

我正在使用带有 Selenium webdriver 的 Visual Studio 制作一个 WinForms 应用程序。我正在为每个测试使用不同的浏览器运行一些测试,这些测试是在单击不同的 winforms 按钮时启动的。

我创建了一个 Webdriver Factory 类,如下所示:

class BrowserFactory
    {
        private static readonly IDictionary<string, IWebDriver> Drivers = new Dictionary<string, IWebDriver>();
        private static IWebDriver driver;

        public static IWebDriver Driver
        {
            get
            {
                if (driver == null)
                    throw new NullReferenceException("The WebDriver browser instance was not initialized. You should first call the method InitBrowser.");
                return driver;
            }
            private set
            {
                driver = value;
            }
        }

        public static void InitBrowser(string browserName)
        {
            switch (browserName)
            {
                case "Firefox":
                    if (driver == null)
                    {
                        FirefoxProfile profile = new FirefoxProfile();
                        FirefoxOptions options = new FirefoxOptions();
                        options.Profile = profile;
                        options.BrowserExecutableLocation = $@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}\Internet JS4\App\firefox64\firefox.exe";
                        FirefoxDriverService service = FirefoxDriverService.CreateDefaultService($@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}");
                        driver = new FirefoxDriver(service, options);
                        Drivers.Add("Firefox", driver);
                    }
                    break;

                case "Chrome":
                    if (driver == null)
                    {
                        var service = ChromeDriverService.CreateDefaultService($@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}\ChromeDriver");
                        var options = new ChromeOptions();
                        service.HideCommandPromptWindow = true;
                        options.BinaryLocation = $@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}\GoogleChromePortable\App\Chrome-bin\chrome.exe";

                        options.AddUserProfilePreference("disable-popup-blocking", "true");
                      driver = new ChromeDriver(service, options);

                      Drivers.Add("ChromeAscuns", driver);
                    }
                    break;
            }
        }

第一个按钮的代码:

BrowserFactory.InitBrowser("Firefox");
BrowserFactory.Driver.Navigate().GoToUrl("http://www.google.com");

第二个按钮的代码:

BrowserFactory.InitBrowser("Chrome");
BrowserFactory.driver.Navigate().GoToUrl("http://www.bing.com");

当我单击任何按钮时,它会启动正确的网络驱动程序(第一个按钮为 Firefox,第二个按钮为 Chrome)。但是,当我单击另一个按钮时,它使用与第一次出现相同的 webdriver 浏览器。

我在代码中遗漏了什么?

【问题讨论】:

  • 你告诉它 if (driver == null) 怎么办,但是 if (driver != null) 怎么办?
  • @Somber,你的意思是在public static IWebDriver Driver?如果它不为 null,则跳过 throwexception 行。我试过把这条线放在括号里,但这并没有什么不同。我实际上是从toolsqa.com/selenium-webdriver/c-sharp/…得到代码。
  • 我的意思是这种情况下 "Firefox": if (driver == null) 所以如果你在测试运行期间尝试切换驱动程序并且驱动程序不为空,它会跳过新驱动程序的创建并使用旧驱动程序,不?
  • @Somber,是的。这就是逻辑。我假设它使用已经设置的驱动程序的值。我不完全理解代码,也找不到更多参考资料。
  • 所以如果你想切换驱动,你必须用新的驱动替换激活的驱动,所以你在创建新驱动的时候不能检查它是否为空

标签: c# selenium selenium-webdriver


【解决方案1】:

您似乎想要缓存 Web 驱动程序并重用它们。问题是您正在检查是否已经创建了“驱动程序”,如果没有创建,则将该实例缓存在字典中。

您需要在输入switch 语句之前先查阅字典,如果该名称的Web 驱动程序已经存在,则提前退出该方法。您还需要假设当您陷入switch 语句时,您将总是创建一个新的网络驱动程序。

public static void InitBrowser(string browserName)
{
    if (Drivers.ContainsKey(browserName))
    {
        // Switch to existing web driver
        driver = Drivers[browserName];

        return;
    }

    // Initialize new web driver
    switch (browserName)
    {
        case "Firefox":
            FirefoxProfile profile = new FirefoxProfile();
            FirefoxOptions options = new FirefoxOptions();
            options.Profile = profile;
            options.BrowserExecutableLocation = $@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}\Internet JS4\App\firefox64\firefox.exe";
            FirefoxDriverService service = FirefoxDriverService.CreateDefaultService($@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}");
            driver = new FirefoxDriver(service, options);
            Drivers.Add("Firefox", driver);
            break;

        case "Chrome":
            var service = ChromeDriverService.CreateDefaultService($@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}\ChromeDriver");
            var options = new ChromeOptions();
            service.HideCommandPromptWindow = true;
            options.BinaryLocation = $@"{EcrisAdreseFrameW.Properties.Settings.Default["caleAppData"]}\GoogleChromePortable\App\Chrome-bin\chrome.exe";
            options.AddUserProfilePreference("disable-popup-blocking", "true");
            driver = new ChromeDriver(service, options);
            Drivers.Add("ChromeAscuns", driver);
            break;
    }
}

【讨论】: