当前位置: 首页 > 面试题库 >

Java中的静态Webdriver实例同步

袁建木
2023-03-14
问题内容

GlobalVariables类包含在我的框架中使用的不同变量,其中之一是WebDriver实例:

  public class GlobalVariables
        {
        public static WebDriver driver;
    //Some other static global variables required across my framework
        public GlobalVariables(String propertiesFile)
        {
        initializeVariables(propertiesFile);
        }
        public void initializeVariables(String propertiesFile)
        {
        GlobalInitializer obj=new GlobalInitializer();
        obj.initialize(String propertiesFile);
        }
   }

GlobalInitializer包含用于初始化所有GlobalVariable的方法:

public class GlobalInitializer extends GlobalVariables
{
public void initialize(String propertiesFile)
{
  //Some logic to read properties file and based on the properties set in it, call other initialization methods to set the global variables.
}
public void initializeDriverInstance(String Browser)
{
driver=new FireFoxDriver();
}

//一些其他方法来初始化其他全局变量。}

我有许多GetElement类,它们使用驱动程序实例获取UI控件元素,例如:

public class GetLabelElement extends GlobaleVariables
{
public static WebElement getLabel(String someID)
{
return driver.findElement(By.id(someId));
}
//Similar methods to get other types of label elements.
}

public class GetTextBoxElement extends GlobaleVariables
{
public static WebElement getTextBox(String someXpath)
{
return driver.findElement(By.xpath(someXpath));
}
//Similar methods to get other types of text box elements.
}

我还有其他类在UI控件上执行一些操作(此类也使用全局变量),例如:

public class GetLabelProperties extends GlobalVariables
{
public static String getLabelText(WebElement element)
{
return element.getText();
}
}

public class PerformAction extends GlobalVariables
{
public static void setText(String textBoxName,String someText)
{
driver.findElement(someLocator(textBoxName)).setText("someText");
}
    //Some other methods which may or may not use the global variables to perform some action
}

我在testng中的测试类如下所示:

public class TestClass
{
GlobalVariables globalObj=new GlobalVariables(String propertiesFile);
@Test(priority=0)
{
GlobalVariables.driver.get(someURL);
//Some assertion.
}
@Test(priority=1)
{
WebElement element=GetLabelElement.getLabel(someID);
String labelName=GetLabelProperties.getLabelText(element);
//Some assertion.
}
@Test(priority=2)
{
WebElement element=GetTextBoxElement.getTextBox(someXpath);
PerformAction.setText(element.getText(),someText);
//Some assertion.
}
}

根据场景,我有多个类似的测试类。现在,如果我单独运行它们,则此测试运行良好。但是,当我尝试并行运行它们时,则该测试以某种奇怪的方式失败了。通过分析,我发现每个测试都初始化了它的静态全局变量,从而使其他测试失败了。现在,我应该如何实现我的目标,以最小的框架设计更改并行运行多个测试?我尝试搜索选项,并且遇到了一些选项,即1)使用同步。2)创建ThreadLocal实例(注意:我已经尝试过此解决方案,但仍然是同样的问题。测试相互混合会导致失败。我已将WebDriver实例标记为ThreadLocal,并重写了ThreadLocal的initialValue方法来初始化驱动程序实例。我仍然不确定我是否正确实施了它。)。现在,我不确定在给定场景下如何最好地实现此解决方案中的任何一个。任何帮助表示赞赏。TIA!


问题答案:

我已经找到了解决方案:使用ThreadLocal是在大型多线程环境中运行测试的最佳解决方案。在多线程环境中使用WebDriver的代码段:

public static ThreadLocal<WebDriver> driver;
driver=new ThreadLocal<WebDriver>()
                {
                    @Override
                    protected WebDriver initialValue()
                    {
                        return new FirefoxDriver(); //You can use other driver based on your requirement.
                    }
                };

现在,每次创建测试线程时,都会打开一个新的浏览器。ThreadLocal将确保每个线程只有一个静态webdriver实例副本。[注意:请确保您的其他全局变量也是ThreadLocals。在我的情况下,这不是我为什么要遇到测试傻瓜问题的原因]。我想分享一些额外的知识,以便其他人可以从中获得启发。在ThreadLocal中,每当调用ThreadLocal.get()方法时,您都必须确保有一项规定可以初始化线程本地,如上在initialValue()方法中所示,否则您可能会遇到空指针异常。感谢大家。



 类似资料:
  • 所以我的编码器朋友讨厌使用编码。然而我的Java程序中却充满了类之间的链接,而且我有很多! 是否值得重写整个代码来移除静态方法? 用一个比用另一个有什么好处吗?

  • 我正在尝试使用Servlets(resteasy+Hibernate)实现一个约会队列。我的约会控制器如下(当然是简化的)。 目前这种方法工作良好。但我读过关于BlockingQueue实现的文章,哪种方法似乎是正确的? 工作细节的定义: 如果不使用同步静态并同时发送多个请求,则多个约会具有相同的约会编号 但如果使用同步静态,则以正确顺序创建的约会 我需要澄清的是; -这是正确的方法吗? -在我的

  • 本文向大家介绍java synchronized同步静态方法和同步非静态方法的异同,包括了java synchronized同步静态方法和同步非静态方法的异同的使用技巧和注意事项,需要的朋友参考一下 java synchronized 详解 synchronized关键字有两种用法,一种是只用于方法的定义中,另外一种是synchronized块,我们不仅可以使用synchronized来同步一个对

  • 问题内容: 我知道不可能在一个类中重写一个方法。但是,有没有办法使用非静态方法作为静态方法呢?例如,我有一个加数字的方法。我希望此方法在没有对象的情况下有用。是否可以在不创建其他方法的情况下执行类似的操作? 编辑:我的意思是,如果我将一个方法设为静态,我将需要它接受参数,如果我创建了一个已经设置了变量的对象,那么再次对具有相同参数的对象调用函数将非常不舒服。 我知道代码不正确,但是我想展示自己想做

  • 问题内容: 我知道在方法带来同步到该对象之前使用关键字。也就是说,运行对象的同一实例的2个线程将被同步。 但是,由于同步是在对象级别进行的,因此运行对象的不同实例的2个线程将不会同步。如果我们在Java类中有一个由该方法调用的静态变量,则希望它在该类的实例之间同步。这两个实例在2个不同的线程中运行。 我们可以通过以下方式实现同​​步吗? 确实是因为我们定义了一个静态对象,并且正在使用该锁的关键字,

  • 主要内容:1 什么是Java静态同步方法,2 没有静态同步方法的问题,3 静态同步方法的例子1,4 静态同步方法的例子21 什么是Java静态同步方法 如果将任何静态方法设置为synchronized(同步),则锁定的是类而不是对象。 2 没有静态同步方法的问题 假设有两个共享类(例如:Table类)的对象,分别名为object1和object2。在使用同步方法和同步代码块的情况下,t1和t2或t3和t4之间不会存在干扰,因为t1和t2都引用了一个具有单个锁,但是t1和t3或t2和t4之间可能存