我在一台机器上运行ThreadLocal测试。我使用@BeforeMethod中的代码来启动网页。我也试过在我的Base Test类中单独编写这个方法,并在@BeforeMethod中调用它。
一切似乎都运行良好,除了错误的用户使用错误的测试登录。这很奇怪,因为Login方法不在BaseTest类中,它是从Page Object调用的(除了为测试登录错误的用户之外,它工作正常)。
在这个例子中,我将问题代码包含在@BeforeMethod中,并且还注释掉了单独的“initialize”方法和方法调用,因此您可以看到我尝试过的两种方法。
public class StackExample {
protected String baseURL;
public String browser;
private static ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
@BeforeMethod(alwaysRun = true)
@Parameters({ "browser", "loginType" })
public void setup(String browser, String loginType, Method caller)
throws MalformedURLException, InterruptedException {
WebDriver driver = null;
// Browsers
if (browser.equalsIgnoreCase("Internet Explorer")) {
System.setProperty("webdriver.ie.driver", "C:\\Users\\automation\\Selenium\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
} else if (browser.equalsIgnoreCase("Firefox")) {
System.setProperty("webdriver.gecko.driver", "C:\\Users\\automation\\Selenium\\geckodriver.exe");
ProfilesIni firProfiles = new ProfilesIni();
FirefoxProfile wbdrverprofile = firProfiles.getProfile("Webdriver2");
driver = new FirefoxDriver(wbdrverprofile);
} else if (browser.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\automation\\Selenium\\chromedriver.exe");
driver = new ChromeDriver();
} else if (browser.equalsIgnoreCase("MicrosoftEdge")) {
System.setProperty("webdriver.edge.driver", "C:\\Users\\automation\\Selenium\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
}
setWebDriver(driver);
this.browser = browser;
System.out.println(browser);
// initialize(loginType);
System.out.println(loginType);
if (loginType.equalsIgnoreCase("client"))
ClientReportFactory
.getTest(StringUtils.join("Client Test"), ' ') + " ("
+ browser + ")", "This test is located in class: " + getClass().getName());
else if (loginType.equalsIgnoreCase("advisor"))
AdvisorReportFactory
.getTest(StringUtils.join("Advisor Test"), ' ') + " ("
+ browser + ")", "This test is located in class: " + getClass().getName());
if (loginType.equalsIgnoreCase("client"))
baseURL = "ClientWebsite.example";
else if (loginType.equalsIgnoreCase("advisor"))
baseURL = "AdvisorWebsite.example";
else {
System.out.println("Client or Advisor must be specified in TestNG XML");
}
driver.get(baseURL);
driver.manage().window().maximize();
}
// public void initialize(String loginType) throws InterruptedException {
// if (loginType.equalsIgnoreCase("client"))
// baseURL = "ClientWebsite.example";
// else if (loginType.equalsIgnoreCase("advisor"))
// baseURL = "AdvisorWebsite.example";
// else{
// System.out.println("Client or Advisor must be specified in TestNG XML");
// }
// driver.get(baseURL);
// driver.manage().window().maximize();
//
// }
public static WebDriver getDriver() {
return threadedDriver.get();
}
static void setWebDriver(WebDriver driver) {
threadedDriver.set(driver);
}
@AfterMethod // (alwaysRun = true)
@Parameters({ "loginType" })
public void afterMethod(Method caller, String loginType) {
// Here we are making sure we close the same test we opened.
System.out.println(loginType);
if (loginType.equalsIgnoreCase("client"))
ClientReportFactory
.closeTest(StringUtils.join("Client Test"), ' ') + " ("
+ browser + ")");
else if (loginType.equalsIgnoreCase("advisor"))
AdvisorReportFactory
.closeTest(StringUtils.join("Advisor Test"), ' ') + " ("
+ browser + ")");
getDriver().quit();
threadedDriver.set(null);
}
@AfterSuite
@Parameters({ "loginType" })
public void afterSuite(String loginType) {
if (loginType.equalsIgnoreCase("client"))
ClientReportFactory.closeReport();
else if (loginType.equalsIgnoreCase("advisor"))
AdvisorReportFactory.closeReport();
if (getDriver() != null) {
getDriver().quit();
} else {
System.out.println("Drivers already closed");
}
}
}
这是我的测试方法。他们从页面对象中调用实际的SignIn方法。我知道这不是问题,因为从页面对象调用的所有其他方法在正确的测试中都能正常工作。
public class StackExampleTests extends StackExample {
@Test(enabled = true, priority = 0)
public void ClientTest1() throws Exception {
ExtentTest t = ClientReportFactory.getTest();
t.log(LogStatus.INFO, "Client 1 Login for " + browser);
try {
Login objLogin = new Login(getDriver());
String username = "username1";
String password = "password1";
t.log(LogStatus.INFO, "Logging in as user: " + username);
objLogin.SignIn(username, password);
// perform First Client's tests here
} catch (Exception e) {
t.log(LogStatus.WARNING, "Exception found: " + e.getMessage().substring(0, 400)
+ t.addBase64ScreenShot(ClientReportFactory.CaptureScreen(getDriver())));
}
}
@Test(enabled = true, priority = 1)
public void ClientTest2 throws Exception{
ExtentTest t = ClientReportFactory.getTest();
t.log(LogStatus.INFO, "Client 2 Login for " + browser);
try {
Login objLogin = new Login(getDriver());
String username = "username2";
String password = "password2";
t.log(LogStatus.INFO, "Logging in as user: " + username);
objLogin.SignIn(username, password);
// perform Second Client's tests here
} catch (Exception e) {
t.log(LogStatus.WARNING, "Exception found: " + e.getMessage().substring(0, 400)
+ t.addBase64ScreenShot(ClientReportFactory.CaptureScreen(getDriver())));
}
}
}
我认为这个跟踪意味着它在同一个线程中启动了所有3个测试。但我不是完全
Starting ChromeDriver 2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9) on port 44694
Only local connections are allowed.
Starting ChromeDriver 2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9) on port 12513
Only local connections are allowed.
Starting ChromeDriver 2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9) on port 32651
Only local connections are allowed.
答案 0 :(得分:1)
看起来您的测试存在驱动程序身份危机,在本地并行运行时WebDriver
属于它们。
将ThreadLocal<WebDriver> threadedDriver
,getDriver()
和setDriver()
设置为不 static
可以解决问题。