我完全赞成有人为这个特定问题推荐一个更好的标题。我也非常愿意努力简化我描述问题的方式。
上下文:我有一个自动化设置,允许通过属性文件配置浏览器。因此,如果有人在该文件中有“browser=chrome”,那么WebDriver
应该实例化的特定实例是ChromeDriver
.
我还在使用WebDriverManager,您可以在其中下载特定WebDriver
类型的二进制文件。所以在这种情况下,我只想下载该属性文件中的任何浏览器驱动程序。因此,如果那是 Chrome,我想使用ChromeDriverManager
.
当然,这里的关键是我必须概括所有这些,因为我不知道有人会使用什么。但出于我的问题的目的,为了说明问题,让我们坚持使用这些移动部件:“chrome” ChromeDriver
,,,ChromeDriverManager
。
代码:
我有一个driverMap
包含WebDriver
与浏览器名称关联的类的实例。
private static final Map<String, Class<?>> driverMap = new HashMap<String, Class<?>>() {
{
put("chrome", ChromeDriver.class);
put("firefox", FirefoxDriver.class);
}
};
我也有一个将类与特定类driverManager
相关联的方法。BrowserManager
WebDriver
private static final Map<Class<?>, Class<?>> driverManager = new HashMap<Class<?>, Class<?>>() {
{
put(ChromeDriver.class, ChromeDriverManager.class);
put(FirefoxDriver.class, FirefoxDriverManager.class);
}
};
只是为了更多的上下文,所有这些都在一个名为的类中Driver
,它的开头是这样的:
public final class Driver {
private static WebDriver driver;
private static BrowserManager manager;
....
}
这两个变量在这里与下一位相关。调用一个add
方法来将特定的浏览器配置添加到测试中。所以这里是那个方法,它显示了当浏览器添加到混合中时如何使用上述方法:
public static void add(String browser, Capabilities capabilities) throws Exception {
Class<?> driverClass = driverMap.get(browser);
Class<?> driverBinary = driverManager.get(driverClass);
manager = (BrowserManager) driverBinary.getConstructor().newInstance(); /// <<--- PROBLEM
driver = (WebDriver) driverClass.getConstructor(Capabilities.class).newInstance(capabilities);
}
你可以看到我使用
driverClass
,这将是这样的org.openqa.selenium.chrome.ChromeDriver
:你可以看到我使用
driverBinary
,这将是这样的io.github.bonigarcia.wdm.ChromeDriverManager
:
但我评论了上面我有问题的那一行。
问题:你可以看到我使用一个driver
变量来存储WebDriver
实例和一个manager
变量来存储BrowserManager
实例。
以下是我在以下情况下这样做的方式和原因driver
:
所以这样做是让我得到ChromeDriver
更一般的( )的适当类型( WebDriver
)。因此,在我的driver
变量上,我能够将反射调用投射到WebDriver
并因此引用driver
,就好像它是那个实例一样。
我不能做同样的事情manager
。
而且我不知道这是否是因为那个特定的 Java 库是如何工作的。具体来说:
所以我不能调用方法,manager
就好像它是特定类型的BrowserManager
(like ChromeDriverManager
) 一样driver
(这是特定类型的WebDriver
, like ChromeDriver
)。
这似乎是因为最终WebDriver
是一个接口,但却BrowserManager
是抽象的。
所以我不知道如何达到我想要的效果。具体来说,我想要的效果是调用相当于这个:
ChromeDriverManager.getInstance().setup();
但是我必须使用反射来做到这一点,因为我不知道我将使用哪个经理。所以理想情况下我想要它,这样我就可以做到这一点:
manager.getInstance().setup();
我不知道我可以为了manager
工作而放弃什么。或者我不知道一旦我确定了那个类是什么,我是否可以转换到一个特定的类。
我可以完全放弃使用 WebDriverManager,但它是一个很好的解决方案,我希望找到一些方法来做我需要的事情。