Java 初始化webdriver实例
嗨,我有一个全球课程,如下所示:Java 初始化webdriver实例,java,selenium-webdriver,testng,Java,Selenium Webdriver,Testng,嗨,我有一个全球课程,如下所示: public class Global { public WebDriver driver=null; public WebDriverWait wait=null; public Global() { BrowserInitializer obj=new BrowserInitializer(); obj.initialize(); } } 我有另一个名为browser initia
public class Global
{
public WebDriver driver=null;
public WebDriverWait wait=null;
public Global()
{
BrowserInitializer obj=new BrowserInitializer();
obj.initialize();
}
}
我有另一个名为browser initializer的类,我想在其中将驱动程序实例初始化为firefox,如下所示:
public class BrowserInitializer extends Global
{
public void initialize()
{
driver=new FirefoxDriver();
driver.manage().window().maximize();
wait=new WebDriverWait(driver, 5000);
}
}
我有一个testNG类,我想在其中运行一些测试,如下所示:
public class TestNG1
{
Global globalObj=new Global();
@Test
public void login()
{
globalObj.driver.get("someURL");
globalObj.driver.findElement(By.id("someid")).sendKeys("someusername");
globalObj.driver.findElement(By.id("someid")).sendKeys("somepassword");
globalObj.driver.findElement(By.id("someid")).submit();
}
}
现在我得到的错误如下:
org.testng.TestNGException:
Cannot instantiate class unitTest.myTest.TestNG1
at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:38)
at org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:387)
at org.testng.internal.ClassHelper.createInstance(ClassHelper.java:299)
at org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:110)
at org.testng.internal.ClassImpl.getInstances(ClassImpl.java:186)
at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:120)
at org.testng.TestRunner.initMethods(TestRunner.java:409)
at org.testng.TestRunner.init(TestRunner.java:235)
at org.testng.TestRunner.init(TestRunner.java:205)
at org.testng.TestRunner.<init>(TestRunner.java:160)
at org.testng.remote.RemoteTestNG$1.newTestRunner(RemoteTestNG.java:141)
at org.testng.remote.RemoteTestNG$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG.java:271)
at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:577)
at org.testng.SuiteRunner.init(SuiteRunner.java:157)
at org.testng.SuiteRunner.<init>(SuiteRunner.java:111)
at org.testng.TestNG.createSuiteRunner(TestNG.java:1299)
at org.testng.TestNG.createSuiteRunners(TestNG.java:1286)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:29)
... 21 more
Caused by: java.lang.StackOverflowError
at unitTest.myTest.Global.<init>(Global.java:12)
at unitTest.myTest.BrowserInitializer.<init>(BrowserInitializer.java:6)
at unitTest.myTest.Global.<init>(Global.java:14)
org.testng.TestNGException:
无法实例化类unitTest.myTest.TestNG1
位于org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:38)
位于org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:387)
位于org.testng.internal.ClassHelper.createInstance(ClassHelper.java:299)
位于org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:110)
位于org.testng.internal.ClassImpl.getInstances(ClassImpl.java:186)
位于org.testng.internal.TestNGClassFinder(TestNGClassFinder.java:120)
位于org.testng.TestRunner.initMethods(TestRunner.java:409)
位于org.testng.TestRunner.init(TestRunner.java:235)
位于org.testng.TestRunner.init(TestRunner.java:205)
位于org.testng.TestRunner.(TestRunner.java:160)
在org.testng.remote.RemoteTestNG$1.newTestRunner(RemoteTestNG.java:141)
位于org.testng.remote.RemoteTestNG$delegatingestrunnerfactory.newTestRunner(RemoteTestNG.java:271)
位于org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:577)
位于org.testng.SuiteRunner.init(SuiteRunner.java:157)
位于org.testng.SuiteRunner(SuiteRunner.java:111)
位于org.testng.testng.createSuiteRunner(testng.java:1299)
位于org.testng.testng.createSuiteRunners(testng.java:1286)
位于org.testng.testng.runSuitesLocally(testng.java:1140)
位于org.testng.testng.run(testng.java:1057)
位于org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
位于org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
位于org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
原因:java.lang.reflect.InvocationTargetException
位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:526)
位于org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:29)
... 还有21个
原因:java.lang.StackOverflower错误
位于unitTest.myTest.Global(Global.java:12)
在unitTest.myTest.BrowserInitializer(BrowserInitializer.java:6)
位于unitTest.myTest.Global(Global.java:14)
但是当我在全局类的构造函数中初始化驱动程序实例时,我能够运行我的测试。有什么问题吗?我在java的概念中有什么地方出错了吗?调用Global的构造函数时有无限递归。您的
initialize()
非常好
public Global()
{
BrowserInitializer obj=new BrowserInitializer();
obj.initialize();
}
BrowserInitializer
是一个全局
所以Global
的构造函数调用BrowserInitializer
的构造函数(它再次调用super
的构造函数,即Global
的构造函数)
使用类似于:
public class BrowserInitializer extends Global
{
BrowserInitializer(){
super();
this.initialize();
}
public void initialize()
{
driver=new FirefoxDriver();
driver.manage().window().maximize();
wait=new WebDriverWait(driver, 5000);
}
}
//In test class
Global globalObj=new BrowserInitializer();
调用Global的构造函数时有无限递归。您的
initialize()
非常好
public Global()
{
BrowserInitializer obj=new BrowserInitializer();
obj.initialize();
}
BrowserInitializer
是一个全局
所以Global
的构造函数调用BrowserInitializer
的构造函数(它再次调用super
的构造函数,即Global
的构造函数)
使用类似于:
public class BrowserInitializer extends Global
{
BrowserInitializer(){
super();
this.initialize();
}
public void initialize()
{
driver=new FirefoxDriver();
driver.manage().window().maximize();
wait=new WebDriverWait(driver, 5000);
}
}
//In test class
Global globalObj=new BrowserInitializer();
我将以另一种方式处理这个问题,并使用@BeforeTes注释 创建一个新的webdriver类,扩展Firefox驱动程序
public class MyFirefoxDriver extends FirefoxDriver {
private WebDriverWait wait;
private WebDriver driver;
public MyFirefoxDriver()
{
super();
this.manage().window().maximize();
wait = new WebDriverWait(this, 5000);
}
public WebDriverWait getWebDriverWait() {
return wait;
}
}
你的测试结果会是这样的
public class TestNG1
{
private MyFirefoxDriver driver;
@BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
@Test
public void login()
{
driver.get("someURL");
driver.findElement(By.id("someid")).sendKeys("someusername");
driver.findElement(By.id("someid")).sendKeys("somepassword");
driver.findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = driver.getWebDriverWait();
}
@AfterTest
public void tearDown() {
driver.quit();
}
}
public class TestNG1 extends TestNGBase
{
@Test
public void login()
{
getDriver().get("someURL");
getDriver().findElement(By.id("someid")).sendKeys("someusername");
getDriver().findElement(By.id("someid")).sendKeys("somepassword");
getDriver().findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = getDriver().getWebDriverWait();
}
}
我很想进一步创建一个基本测试类
public abstract class TestNGBase
{
private MyFirefoxDriver driver;
public MyFirefoxDriver getDriver() {
return driver;
}
@BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
@AfterTest
public void tearDown() {
driver.quit();
}
}
在这种情况下,您的测试将如下所示
public class TestNG1
{
private MyFirefoxDriver driver;
@BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
@Test
public void login()
{
driver.get("someURL");
driver.findElement(By.id("someid")).sendKeys("someusername");
driver.findElement(By.id("someid")).sendKeys("somepassword");
driver.findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = driver.getWebDriverWait();
}
@AfterTest
public void tearDown() {
driver.quit();
}
}
public class TestNG1 extends TestNGBase
{
@Test
public void login()
{
getDriver().get("someURL");
getDriver().findElement(By.id("someid")).sendKeys("someusername");
getDriver().findElement(By.id("someid")).sendKeys("somepassword");
getDriver().findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = getDriver().getWebDriverWait();
}
}
我将以另一种方式处理这个问题,并使用@BeforeTes注释 创建一个新的webdriver类,扩展Firefox驱动程序
public class MyFirefoxDriver extends FirefoxDriver {
private WebDriverWait wait;
private WebDriver driver;
public MyFirefoxDriver()
{
super();
this.manage().window().maximize();
wait = new WebDriverWait(this, 5000);
}
public WebDriverWait getWebDriverWait() {
return wait;
}
}
你的测试结果会是这样的
public class TestNG1
{
private MyFirefoxDriver driver;
@BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
@Test
public void login()
{
driver.get("someURL");
driver.findElement(By.id("someid")).sendKeys("someusername");
driver.findElement(By.id("someid")).sendKeys("somepassword");
driver.findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = driver.getWebDriverWait();
}
@AfterTest
public void tearDown() {
driver.quit();
}
}
public class TestNG1 extends TestNGBase
{
@Test
public void login()
{
getDriver().get("someURL");
getDriver().findElement(By.id("someid")).sendKeys("someusername");
getDriver().findElement(By.id("someid")).sendKeys("somepassword");
getDriver().findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = getDriver().getWebDriverWait();
}
}
我很想进一步创建一个基本测试类
public abstract class TestNGBase
{
private MyFirefoxDriver driver;
public MyFirefoxDriver getDriver() {
return driver;
}
@BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
@AfterTest
public void tearDown() {
driver.quit();
}
}
在这种情况下,您的测试将如下所示
public class TestNG1
{
private MyFirefoxDriver driver;
@BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
@Test
public void login()
{
driver.get("someURL");
driver.findElement(By.id("someid")).sendKeys("someusername");
driver.findElement(By.id("someid")).sendKeys("somepassword");
driver.findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = driver.getWebDriverWait();
}
@AfterTest
public void tearDown() {
driver.quit();
}
}
public class TestNG1 extends TestNGBase
{
@Test
public void login()
{
getDriver().get("someURL");
getDriver().findElement(By.id("someid")).sendKeys("someusername");
getDriver().findElement(By.id("someid")).sendKeys("somepassword");
getDriver().findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = getDriver().getWebDriverWait();
}
}
是否有其他方式我不想在测试类中公开我的浏览器初始化类。另外,在browser initialize类中也有其他方法,这些方法由我的其他类使用,这些类没有在测试类中公开。因此,当不必要地通过browser initialize类的对象调用它们时,构造函数将被调用,它将尝试再次初始化驱动程序实例。此外,在全局类的构造函数中,还需要调用其他方法来一次性全局初始化某些参数。(此方法驻留在不可测试的公开类中)我建议使用一种方法,或者如果您不想因为测试而修改核心代码,可以使用反射。这应该是可以接受的测试。我曾尝试谷歌工厂,并尝试了一些虚拟代码,但仍然是相同的问题。在浏览器中初始化驱动程序实例后,使用工厂方法初始化代码。然后,我无法在其他类中保留该初始化值。在扩展全局类并使用驱动程序实例的其他类中,驱动程序实例被证明为null。为什么会这样?我是否以错误的方式访问它们?是否有其他方式不希望在测试类中公开我的浏览器初始化类。另外,在browser initialize类中也有其他方法,这些方法由我的其他类使用,这些类没有在测试类中公开。因此,当不必要地通过browser initialize类的对象调用它们时,构造函数将被调用,它将尝试再次初始化驱动程序实例。此外,在全局类的构造函数中,还需要调用其他方法来一次性全局初始化某些参数。(此方法驻留在不可测试的公开类中)我建议使用,或者