Java 初始化一个 webdriver 实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18693002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 10:14:22  来源:igfitidea点击:

initialize a webdriver instance

javaselenium-webdrivertestng

提问by Mrunal Gosar

Hi i have a global class as belows:

嗨,我有一个全局类,如下所示:

public class Global 
{
    public WebDriver driver=null;
    public WebDriverWait wait=null;

    public Global()
    {
        BrowserInitializer obj=new BrowserInitializer();
        obj.initialize();
    }
}

I have another class called browser initializer where i want to initialize the driver instance to firefox as below:

我有另一个名为浏览器初始化程序的类,我想在其中将驱动程序实例初始化为 firefox,如下所示:

public class BrowserInitializer extends Global 
{
    public void initialize()
    {
        driver=new FirefoxDriver();
        driver.manage().window().maximize();
        wait=new WebDriverWait(driver, 5000);
    }
}

I have testNG class where i want to run some test as belows :

我有 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();
    }
}

Now i am getting error like :

现在我收到如下错误:

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.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)

but when i am initializing the driver instance in the constructor of the Global class i am able to run my test. what seems to be the problem? am i going wrong somewhere in the concepts of java?

但是当我在 Global 类的构造函数中初始化驱动程序实例时,我能够运行我的测试。似乎是什么问题?我在java概念中的某个地方出错了吗?

采纳答案by rocketboy

You have infinite recursion when calling Global's constructor. Your initialize()is perfectly fine.

调用 Global 的构造函数时,您有无限递归。你initialize()的完全没问题。

 public Global()
    {
        BrowserInitializer obj=new BrowserInitializer();
        obj.initialize();
    }

BrowserInitializeris aGlobal.

BrowserInitializer是一个Global

So Global's contructor calls BrowserInitializer's constructor (which calls super's i.e Global's constructor again)

SoGlobal的构造BrowserInitializer函数调用了的构造函数(它再次调用了superie Global的构造函数)

Use something like:

使用类似的东西:

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();

回答by Robbie Wareham

I woudl approach this in a different way, and use a @BeforeTes annotation;

我会以不同的方式处理这个问题,并使用@BeforeTes 注释;

Create a new webdriver class which extends Firefox driver;

创建一个新的 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;
    }
}

Your test would then look like this;

您的测试将如下所示;

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();
    }
}

I would be tempted to then further create a base test class;

然后我很想进一步创建一个基础测试类;

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();
    }
}

In which case you test would then look like this;

在这种情况下,您的测试将如下所示;

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();
    }
}