java中的静态Webdriver实例同步 [英] static Webdriver instance synchronization in java
问题描述
GlobalVariables类包含在我的框架中使用的不同变量,其中一个是WebDriver实例:
GlobalVariables class holds different variables which are used across my framework one of them is WebDriver instance:
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包含初始化所有GlobalVariables的方法:
GlobalInitializer contains methods to initialize all the GlobalVariables:
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();
}
//初始化其他全局变量的其他一些方法。
}
//Some other methods to initialize other global variables. }
我有很多GetElement类,它们使用驱动程序实例来获取UI控件元素例如:
I have many GetElement classes which use the driver instance to get UI control elements E.g:
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控件上执行某些操作(这个类也是使用全局变量)例如:
I have other classes which perform some actions on the UI Control(This classes too use the global variables) E.g:
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中的测试类看起来像这样:
My test class in testng looks like this:
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)使用synchronized。 2)创建ThreadLocal实例(注意:我已尝试过这个解决方案,但仍然存在同样的问题。测试相互混淆导致失败。我将WebDriver实例标记为ThreadLocal并覆盖ThreadLocal的initialValue方法以初始化驱动程序实例。我仍然不确定我是否正确实施了它。)现在我不确定在给定方案中如何最好地实现此解决方案中的任何一个。任何帮助表示赞赏。 TIA!
I have similar multiple test classes based on scenarios. Now this tests are running fine if i am running them individually. But when i try to run them in parallel, then this tests are failing in some weird fashion. On analyzing i found out that its the static global variables which are getting initialized by each tests thus leaving the other tests to fail. Now how should i go about achieving my objective to run multiple tests parallely with minimal changes in my framework design? i have tried searching for options, and i have come across some option i.e 1) use of synchronized. 2) Create ThreadLocal instance(Note : I have tried this solution but still same issue. tests are mixing up with each other resulting in failure. I had marked the WebDriver instance as ThreadLocal and overriden the initialValue method of ThreadLocal to initialize the driver instance. Still i am not sure whether i had implemented it correctly or not.). Now i am not sure how best to implement any one of this solution in the given scenario. Any help is appreciated. TIA!
推荐答案
我找到了解决方案:使用ThreadLocal是在巨大的多线程环境中运行测试的最佳解决方案。
在多线程环境中使用WebDriver的代码片段:
I have found out the solution : Use of ThreadLocal is the best solution to run tests in a huge multithreaded environment. Code snippet to use WebDriver in multithreaded environment:
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()方法中,或者您可能遇到空指针异常。谢谢大家。
Now every time a test thread is created a new browser will open. ThreadLocal will make sure that there's only one copy of static webdriver instance per thread. [NOTE: Make sure your other global variables are too ThreadLocals. In my case they were not thats why i was running into test goof up issue]. Some extra knowledge which i would like to share so that others may find it informative. In ThreadLocal whenever the ThreadLocal.get() method is called you have to make sure that there is a provision to initialize the thread local as shown above in initialValue() method or you may run into null pointer exception. Thanks everyone.
这篇关于java中的静态Webdriver实例同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!