我一直在研究一个几个月来一直在开发Selenium WebDriver基础架构的团队,而且我们从测试用例和页面对象访问驱动程序对象的方式让我烦恼。
我们的测试用例创建一个新的WebDriver实例并打开浏览器。这个新实例存储在测试用例类中。
然后,测试用例实例化页面对象。跟随Selenium's 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执行操作?
让WebDriver成为一个可供所有人访问的单例是否更容易/更好,因为我们在任何给定时间都不会为每个JVM使用多个WebDriver?然后我们根本不需要在构造函数中传递WebDriver。提前感谢任何意见。
答案 0 :(得分:4)
最好将webdriver标记为整个框架的单例。我一直在使用这种模式,它工作正常。
注意:处理并行执行时应小心。
@CodeEnthusiastic
例如,参加课程GeneralLibrary
,创建一个WebDriver
。
使用GeneralLibrary
作为超类