【问题标题】:Can we have static variable for initilizing driver in selenium web driver我们可以在 selenium webdriver 中有用于初始化 webdriver 的静态变量吗
【发布时间】:2014-07-07 07:17:01
【问题描述】:

我们有一个静态变量来初始化 Selenium WebDriver 中的驱动程序。

public static WebDriver driver;

这个变量在一个类(DriverInit)中声明,并在各种测试计划(Test Classes)的“@BeforeClass”中初始化。初始化的变量(驱动程序)将在整个项目中用于各种可重用的函数和@test 方法。驱动程序将在@QAfterClass 关闭/退出

这适用于脚本的非并行执行。使用静态变量来初始化驱动程序是否会以任何方式影响并行执行?

例如:

public class DriverInit { (using remote webdriver, browser name will be read from XML)
  public static WebDriver driver;    
  public DriverInit() {
    switch (browser) {
    case "IE" : driver = ....
    case "Firefox" : driver = ....
    }
  }
}

public class TestClass {
  @BeforeClass
  public void BeforeClass() {
   DriverInit driver = new DriverInit();
  }

  @Test
  public void Test1() {
   DriverInit.driver.findElementBy();
   Reusable.func1();
  }
}

Public class Reusable {

  public WebElement r1;
  public Reusable() {
    r1 = DriverInit.driver.findElementBy(..);
  }
  public void func1() {
     r1.findElementBy(..);
  }
}

【问题讨论】:

    标签: java selenium webdriver


    【解决方案1】:

    正如您所说,您可以使用静态驱动程序,但是,是的,如果您直接在测试代码级别进行任何并行化,您将面临共享内存问题的风险。

    出于这个原因,我避免使用静态驱动程序,对于可能会发展为并行化的测试套件来说,这是一个糟糕的设计。在 selenium 网格中的多台服务器上运行单个进程启动测试是行不通的。

    我针对这种情况设计的方法是在初始化它们时将驱动程序(在@Before 中创建)传递给每个页面对象。

    如果套件不会增长,您仍然可以使用静态驱动程序,并将多个测试作为单独的作业启动(即单独的 Jenkins 作业,或从命令行单独运行等)

    【讨论】:

    • 为避免并行执行问题,静态驱动实例能否以线程安全的方式使用?
    【解决方案2】:

    将静态用于驱动程序实例是不正确的。 最好创建 get_method 以将驱动程序返回到另一个类。

    public class DriverInit { (using remote webdriver, browser name will be read from XML)
    private WebDriver driver;
    
    public WebDriver getDriver() {
    switch (browser) {
    case "IE" : driver = ....
    case "Firefox" : driver = ....
    return driver;
    }
    }
    
    public class TestClass {
    private Webdriver driver;
    @BeforeClass
    public void BeforeClass() {
    DriverInit driveInit= new DriverInit();
    driver=driveInit.getDriver();
    }
    
    @Test
    public void Test1() {
    Reusable reusable = new Reusable();
    reusable.func1Click(driver);
    }
    }
    
    public class Reusable {
    
    public void func1Click(WebDriver driver) {
    driver.findElementBy(..).click();
    }
    }
    

    【讨论】:

      【解决方案3】:

      使用您在其中定义 webDriver 的 Singleton 类, 然后在其他类中使用相同的实例

      【讨论】:

        【解决方案4】:

        当您将字段定义为static 时,每个线程都可以访问它并且每个线程都可以修改该内存空间。这就是为什么我怀疑使用定义为static 的webdriver 实例的可能性。但是您可以考虑使用Selenium Grid 以便在不同的浏览器上运行多个测试。

        【讨论】:

          【解决方案5】:

          我使用了静态 Webdriver 对象。我在测试的每个部分都使用了它(@Before、@Test、@After 以及元素定位/页面对象建模)。我检查了 JVM。性能看起来相当不错。因为你可以杀死,所以在每个测试用例之后销毁这个对象。

          但是当并行测试有问题时。如果您使用的是 testNg,则可以使用 xml 文件对其进行管理。 但是,如果您使用的是 Junit(junit-platform.properties 文件或 @Execution(ExecutionMode.CONCURRENT)),我遇到了上面提到的一些问题。 Java 用户必须远离静态。

          要解决这个问题,您需要静态和 ThreadLocal 实例。

          private final static ThreadLocal<DriverFactorySingleton> driverFactorySingleton = new ThreadLocal<>();
          private final static ThreadLocal<WebDriver> webDriver = new ThreadLocal<>();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-05-02
            • 1970-01-01
            • 2011-01-21
            • 1970-01-01
            • 1970-01-01
            • 2017-04-24
            • 2018-02-28
            • 2021-03-21
            相关资源
            最近更新 更多