Java 如何将 selenium webdriver 实例传递给另一个类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42331659/
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 00:03:45  来源:igfitidea点击:

How to pass selenium webdriver instance to another class

javaseleniumselenium-webdriver

提问by Ashwin

I browsed through the site but did not find the answer I am looking.

我浏览了该网站,但没有找到我正在寻找的答案。

I have

我有

  1. Superbase class- here I just create object of a webdriver
  2. Baseclass- In this class I extend Superbase class, invoke the driver, and open the URL.
  3. Clicklink class- In this class, I again extend the Superbase Class but only to find a null pointer exception. I think I am getting the exception as the driver object is not initialized.
  1. 超级基类 - 在这里我只是创建一个 webdriver 的对象
  2. Baseclass - 在这个类中,我扩展了 Superbase 类,调用驱动程序,并打开 URL。
  3. Clicklink 类 - 在这个类中,我再次扩展了 Superbase 类,但只是发现了一个空指针异常。我想我收到了异常,因为驱动程序对象没有初始化。

I am just a beginner, and have not tried the browserfactory and other options, as I want to start with simple flow.

我只是一个初学者,还没有尝试过browserfactory和其他选项,因为我想从简单的流程开始。

Superclass

超类

    Public class Superclass
    {
public webdriver Driver;
}

Baseclass

基类

public class Baseclass extends Superclass
{
setting capabilities and launching the browser
}

ClickLink

点击链接

public class Clicklink extends Superclass
{
here I want to click on a link
driver.findelement(by.xpath("xpath").click());
// after this statement I get a null pointer exception
}

Can you please guide me here? how can I achieve the same.

你能在这里指导我吗?我怎样才能达到同样的目标。

Thanks much!

非常感谢!

采纳答案by Pavel Janicek

This is lot of guesswork done from my side, but please make sure, that your Superclass actually sets the driver and returns it. You can actually make it in both methods:

这是我的很多猜测,但请确保您的超类实际上设置了驱动程序并返回它。您实际上可以通过两种方法实现:

public class Superclass
{
  public WebDriver driver;
  public Superclass(){
    driver = new FirefoxDriver();
  }
  public WebDriver getdriver(){
    if (driver == null){
      driver = new FirefoxDriver();
      return driver;
    }else{
      return driver;
    }
  }
}

And later in methods you call it by:

稍后在您通过以下方式调用它的方法中:

public class Clicklink extends Superclass
{

getdriver().findelement(by.xpath("xpath").click());

}

回答by Martin Spamer

SuperClassand BaseClassare very poor names. Do not use the language of coding to name your classes use the language of the problem In this case, web site application testing, us LoginPage, CartPage, ProfilePage, etc. Use the Page Object Pattern. A BrowserFactory can provide the instance of WebDriver for each test. Since all these fit the idea is a page, use class extension from a standard PageObject to provide this capability. When navigating, have the current page construct an instance of the new page and pass it the current webDriverinstance. You can also use a PageFactoryto provide an instance of the page object.

SuperClass并且BaseClass是非常可怜的名字。不要使用编码语言来命名您的类使用问题语言在这种情况下,网站应用程序测试,我们 LoginPage、CartPage、ProfilePage 等。使用Page Object Pattern。BrowserFactory 可以为每个测试提供 WebDriver 的实例。由于所有这些都符合页面的想法,因此使用标准 PageObject 的类扩展来提供此功能。导航时,让当前页面构造新页面的webDriver实例并将当前实例传递给它。您还可以使用PageFactory来提供页面对象的实例。

public abstract class PageObject {
    public WebDriver driver;
    PageObject() {
        // Page can initialise its self
        this.driver = BrowserFactory.webDriver();
    }
    PageObject(final WebDriver webDriver) {
        this.driver = webDriver;
        }
    }

回答by Anton Savostytskyi

If you doesn't want pass driver instance to Page Objects constructor you could create some container class for driver and put it before test and remove it after run. For example:

如果您不想将驱动程序实例传递给页面对象构造函数,您可以为驱动程序创建一些容器类并将其放在测试之前并在运行后将其删除。例如:

class Driver {
    public static ThreadLocal<IWebDriver> driverInstance = new ThreadLocal<IWebDriver>();

    public static IWebDriver GetDriver() {
        return driverInstance.Value;
    }

    public static void SetDriver(IWebDriver driver) {
        driverInstance.Value = driver;
    }
}

and make this container field ThreadLocalto avoid problems with parallel run.

并将此容器字段设为ThreadLocal以避免并行运行出现问题。

回答by dev

I did use below code in utility class like below
  public static WebDriver setup(WebDriver driver)
   {
       if(driver == null) {
           driver = new FirefoxDriver();
           driver.manage().window().maximize();
           driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
           return driver;
       }else
          return driver;

         //System.out.println("in method "+ driver.getTitle() );

   }

回答by hfontanez

I have taken a slightly different approach than most on this thread. When I start a test session, I pass the browser name as an argument (i.e. -Dbrowser=chrome) in order to be able to test my web application with different browsers. Then I used the "browser" system property to obtain the browser name when setup()is called by my test framework. In my case, I use JUnit annotations in order to JUnit to setup all needed dependencies prior to running any tests.

我采取了与此线程上的大多数方法略有不同的方法。当我开始测试会话时,我将浏览器名称作为参数传递(即 -Dbrowser=chrome),以便能够使用不同的浏览器测试我的 Web 应用程序。然后我使用“浏览器”系统属性来获取setup()我的测试框架调用时的浏览器名称。就我而言,我使用 JUnit 注释以便 JUnit 在运行任何测试之前设置所有需要的依赖项。

@BeforeClass
public static void setup() throws Exception {
    // Set up other stuff
    String browser = System.getProperty("browser");
    try {
        SessionDataProvider.driver = TestUtils.createDriver(browser);
    } catch (Exception e) {
        ...
    }
}

The createDriver(String)is a factory method that instantiates the correct driver.

createDriver(String)是,实例化了正确的驱动程序的工厂方法。

public static WebDriver createDriver(String browserName) throws Exception {
    WebDriver driver = null;
    try {
        switch(browserName) {
        case "firefox":
            // code to system props and instantiate the driver
            break;
        case "chrome":
            // code to system props and instantiate the driver
            break;
        case "ibrowser":
            // code to system props and instantiate the driver
            break;
        case "edge":
            // code to system props and instantiate the driver
            break;
        case "safari":
            // code to system props and instantiate the driver
            break;
        default:
            throw new Exception("Unsupported browser: " + browserName);
        }
    return driver;
}

Then, when I execute a step definition, I simply obtain the driver from the data provider class:

然后,当我执行步骤定义时,我只需从数据提供程序类中获取驱动程序:

@And("(I click)/Click on {string}")
public void click(String arg) {

    // Parse String arg and create web element locator...
    try {
        By locator = ...;
        WebElement element = new WebDriverWait(SessionDataProvider.driver, 2)
            .until(ExpectedConditions.elementToBeClickable(locator));
        element.click();
    } catch (Exception e) {
        // handle exception
    }
}