2017-03-09 170 views
0

我想在一臺機器上使用TestNG並行運行Selenium Webdriver測試。我有3個@Test方法,3個不同的用戶登錄到同一個應用程序併到達主頁。我需要@Test方法並行運行,並寫入ExtentReports報告。Selenium Webdriver TestNG測試是「覆蓋」對方

我的問題是,儘管在不同的類中有3種完全不同的方法,其中一個用戶將被登錄到3個瀏覽器中的2個,從而使用戶不在。

登錄方法位於PageFactory頁面對象類中。

這裏是我的3個測試方法:

@Test(enabled = true, priority = 0) 
public void JohnLogin() throws Exception { 
    ExtentTest t = ClientReportFactory.getTest(); 
    try {  
     Login objLogin = new Login(getDriver()); 
     String username = "John"; 
     String password = "Password"; 
     objLogin.SignIn(username, password); 
     HomePage objHomePage = new HomePage(getDriver()); 
     assertTrue(objHomePage.clientName.getText().c‌​ontains("John")); 
    } catch (Exception e) { 
    } 
} 

@Test(enabled = true, priority = 1) 
public void BobLogin() throws Exception { 
    ExtentTest t = ClientReportFactory.getTest(); 
    try {  
     Login objLogin = new Login(getDriver()); 
     String username = "Bob"; 
     String password = "Password"; 
     objLogin.SignIn(username, password); 
     HomePage objHomePage = new HomePage(getDriver());  
     assertTrue(objHomePage.clientName.getText().c‌​ontains("Bob")); 
    } catch (Exception e) { 
    } 
} 

@Test(enabled = true, priority = 2) 
public void SamLogin() throws Exception { 
    ExtentTest t = ClientReportFactory.getTest(); 
    try {  
     Login objLogin = new Login(getDriver()); 
     String username = "Sam"; 
     String password = "Password"; 
     objLogin.SignIn(username, password); 
     HomePage objHomePage = new HomePage(getDriver());  
     assertTrue(objHomePage.clientName.getText().c‌​ontains("Sam")); 
    } catch (Exception e) { 
    } 
} 

所以,如果我停下首頁上的測試。我將打開2個瀏覽器窗口作爲「John」,一個「Bob」和「Sam」......導致失敗。

這是PageFactory對象的登錄方法。

public void SignIn(String strUsername, String strPassword) throws InterruptedException { 
    WebDriverWait wait = new WebDriverWait(driver, 15); 
    username.clear(); 
    username.sendKeys(strUsername); 
    password.clear(); 
    password.sendKeys(strPassword); 
    submit.click(); 
    wait.until(ExpectedConditions.visibilityOf(homePagePanel)); 
} 

起初我相信這個問題是在@BeforeMethod線程(如,測試是在不同的線程比@Before和@After)。但我不明白這是怎麼回事。基本測試方法成功打開並關閉3個瀏覽器。它看起來像@Test方法使用彼此的數據!但爲了以防萬一,這裏是我的@Before和@After,以及我的Threading代碼。

public class BaseTest { 
    public String browser; 
    private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>(); 

@BeforeMethod(alwaysRun = true) 
@Parameters({ "browser"}) 
public void setup(String browser)throws MalformedURLException, 
InterruptedException { 

     WebDriver driver = null; 
     if (browser.equalsIgnoreCase("Internet Explorer")) { 
      System.setProperty("webdriver.ie.driver", "C:\\Selenium\\IEDriverServer.exe"); 
      driver = new InternetExplorerDriver(); 
     } else if (browser.equalsIgnoreCase("Firefox")) { 
      System.setProperty("webdriver.gecko.driver", "C:\\Selenium\\geckodriver.exe"); 
      driver = new FirefoxDriver(); 
     } else if (browser.equalsIgnoreCase("chrome")) { 
      System.setProperty("webdriver.chrome.driver", "C:\\Selenium\\chromedriver.exe"); 
      driver = new ChromeDriver(); 
     } else if (browser.equalsIgnoreCase("MicrosoftEdge")) { 
      System.setProperty("webdriver.edge.driver", "C:\\Selenium\\MicrosoftWebDriver.exe"); 
      driver = new EdgeDriver(); 
     } 
     setWebDriver(driver); 
     this.browser = browser; 
     ClientReportFactory.getTest(ExtentTestName, ExtentTestDescription); 

baseURL = "testApp.com"; 
driver.get(baseURL); 
     driver.manage().window().maximize(); 
     } 

public WebDriver getDriver(){ 
    return threadedDriver.get(); 
} 
public void setWebDriver(WebDriver driver) { 
    threadedDriver.set(driver); 
} 

@AfterMethod 
public void afterMethod() { 
    ClientReportFactory.closeTest(ExtentTestName, ExtentTestDescription); 
    getDriver().quit(); 
    threadedDriver.set(null); 
} 

@AfterSuite 
public void afterSuite() { 
    ClientReportFactory.closeReport(); 
    if (getDriver() != null) { 
     getDriver().quit(); 
    } else { 
     System.out.println("Drivers already closed"); 
    } 
} 

回答

2

假設所有的@Test方法在不同的班級,我猜測,這個問題可能是由於你的ThreadLocal變量是不是靜態不過是一個實例變量。這導致每個線程每個實例的行爲爲,而不是所有實例上每個線程的期望行爲,即。你可以參考this StackOverFlow線程來獲得更好的解釋。

你會訴諸使用的ThreadLocal實例變型,當且僅當所有@Test方法屬於同一測試類(因​​爲你現在只是想確保一流水平的數據成員WebDriver在共享線程在所有的測試方法安全的方式是屬於同一個測試類)

所以,如果您的每一個@Test方法駐留在自己的測試類,那麼請嘗試改變:

private ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>(); 

private static ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>(); 
+0

克里希南,下面我的答案有什麼問題?我樂意去學。 – Dineshmohan

+0

@Dineshmohan - 我已經修復了反對票的一部分。另一方面,我認爲您的解決方案可能會受到Java嘗試使用ThreadLocals時出現的奇怪行爲的困擾,其中initialValue()在方法範圍內定義,並且該值取決於封閉範圍。你可以在我的博客文章https://rationaleemotions.wordpress.com/2016/05/16/a-date-with-threadlocal/閱讀更多關於它的信息(我不確定你的代碼是否也會顯示相同的問題,但它確實有可能導致問題的相同類型的代碼) –

0

你可以試試這個。

public class DriverFactory(){ 

private static ThreadLocal<WebDriver> driverThread; 
public WebDriver driver; 

@Parameters("browser") 
public WebDriver instantiateDriverObject(String browser) { 
DriverFactory factory = new DriverFactory(); 
driver = factory.createInstance(browser); //Driver instantiation goes here 
driverThread = new ThreadLocal<WebDriver>() { 
    @Override 
    protected WebDriver initialValue() { 
    webDriverPool.add(driver); 
    return driver; 
    } 
}; 
return driver; 
} 

public WebDriver getDriver() { 
return driverThread.get(); 
} 

}

+0

我錯誤地結束了點擊。我很抱歉。自從昨天以來,我一直在努力修復它,但運氣不大。我現在修復了它。對困惑感到抱歉。 –

相關問題