几个月来,我一直在一个开发 Selenium WebDriver 基础架构的团队中工作,而我们从测试用例和页面对象访问驱动程序对象的方式让我很烦恼。
我们的测试用例创建一个新的 WebDriver 实例并打开浏览器。这个新实例存储在测试用例类中。
然后,测试用例实例化一个页面对象。与Selenium 的 Page Object Pattern一起,这些页面对象将 WebDriver 作为其构造函数中的参数(尽管我注意到在我们的版本中它不是最终的)。各种页面对象方法使用在页面对象的构造函数中设置的驱动程序来完成它们的工作。如果页面对象方法导航到新页面对象,则将 WebDriver 传递给它。就像在 Selenium 的例子中一样:
public class LoginPage {
private final WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
// Check that we're on the right page.
if (!"Login".equals(driver.getTitle())) {
// Alternatively, we could navigate to the login page, perhaps logging out first
throw new IllegalStateException("This is not the login page");
}
}
// Conceptually, the login page offers the user the service of being able to "log into"
// the application using a user name and password.
public HomePage loginAs(String username, String password) {
// This is the only place in the test code that "knows" how to enter these details
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("passwd")).sendKeys(password);
driver.findElement(By.id("login")).submit();
// Return a new page object representing the destination. Should the login page ever
// go somewhere else (for example, a legal disclaimer) then changing the method signature
// for this method will mean that all tests that rely on this behaviour won't compile.
return new HomePage(driver);
}
}
这使得 WebDriver 实例看起来是唯一且重要的,就像必须从页面对象传递到页面对象的火炬一样。代码的风格让我认为我总是必须确保我使用的驱动程序实例与上次操作中使用的驱动程序实例相同。
但是,如果页面上有多个页面对象,并且页面对象方法不会返回您计划接下来使用的页面对象,这种“火炬传递”会变得复杂或不可能。当屏幕上有两个页面对象并且需要在它们之间交替时,如何在同一个 WebDriver 实例上进行操作,而无需切换到新页面或创建新页面对象?
所有这些困惑让我相信实际上没有必要传递火炬,甚至可能发生(所有这些页面对象都存储对同一个 WebDriver 实例的引用吗?),但是我不知道为什么在Selenium 给出的描述。
那么,我需要担心“传递火炬”吗?或者,任何页面对象在使用其 WebDriver 实例化后是否会正常运行,即使其他页面对象在此期间使用它们自己版本的同一 WebDriver 执行操作?
因为我们不会在任何给定时间为每个 JVM 使用多个 WebDriver,所以将 WebDriver 设置为一个可供所有人访问的单例会更容易/更好吗?然后我们根本不需要在构造函数中传递 WebDriver。提前感谢您的任何意见。