我完全赞成有人为这个特定问题推荐一个更好的标题。我也非常愿意努力简化我描述问题的方式。
上下文:我有一个自动化设置,允许通过属性文件配置浏览器。因此,如果有人在该文件中有“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相关联的方法。BrowserManagerWebDriver
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,但它是一个很好的解决方案,我希望找到一些方法来做我需要的事情。