2017-03-09 6 views
0

Ich versuche, Selenium Webdriver-Tests parallel auf einem einzigen Computer mit TestNG auszuführen. Ich habe 3 @ Test-Methoden, bei denen sich 3 verschiedene Benutzer bei der gleichen Anwendung anmelden und die Homepage erreichen. Ich brauche @ Test-Methoden, um parallel zu laufen, und schreibe in einen ExtentReports-Bericht.Selenium Webdriver TestNG Tests "überschreiben" sich gegenseitig

Mein Problem ist, trotz 3 völlig verschiedenen Methoden in verschiedenen Klassen, wird einer der Benutzer in 2 von 3 der Browser angemeldet sein, so dass ein Benutzer aus.

Die Anmeldemethode befindet sich in einer PageFactory-Seitenobjektklasse.

Hier sind meine 3 Prüfverfahren:

@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) { 
    } 
} 

Also, wenn ich die Tests auf der Homepage pausieren. Ich werde 2 Browserfenster als "John" geöffnet haben, ein "Bob" und kein "Sam" ... Fehler verursachen.

Hier ist die Anmeldemethode des PageFactory-Objekts.

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)); 
} 

Zuerst war ich sicher, dass das Problem in der @BeforeMethod Threading war (wie in den Tests waren in einem anderen Thread als die @Before und @After). Aber ich sehe nicht, wie das sein könnte. Die Basistestmethode öffnet und schließt 3 Browser erfolgreich. Es scheint nur so, als ob die @ Test-Methoden die Daten der jeweils anderen benutzen! Aber nur für den Fall, hier ist mein @Before und @After, mit meinem Threading-Code.

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"); 
    } 
} 

Antwort

2

Unter der Annahme, dass alle Ihre @Test Methoden in verschiedenen Klassen sind, ich vermute, dass das Problem auf die Tatsache vielleicht zurückzuführen ist, dass Ihre ThreadLocal Variable ist NICHT STATIC aber ist eine Instanzvariable . Dies führt dazu, dass das Verhalten pro Thread pro Instanz und nicht das gewünschte Verhalten ist, nämlich pro Thread über alle Instanzen. Sie können sich auf this StackOverFlow-Thread für eine bessere Erklärung zu diesem Thema beziehen.

Sie greifen würde eine Instanz Variante ThreadLocal, wenn und nur wenn alle @Test Methoden gehören zur selben Testklasse zu verwenden (Denn jetzt sind Sie nur darauf bedacht, dass die Klassenstufe Daten Mitglied WebDriver in einem gemeinsam genutzt wird fädelt sichere Art und Weise über alle Testmethoden, die auf die gleiche Testklasse gehören)

Also, wenn jeder Ihrer @Test Methoden in ihrer eigenen Test-Klasse befindet, dann versuchen Sie es zu ändern:

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

bis

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

Krishnan, was ist falsch in meiner Antwort unten? Ich würde gerne lernen. – Dineshmohan

+0

@Dineshmohan - Ich habe den Down-Vote-Teil repariert.Nebenbei bemerkt, Ihre Lösung wird möglicherweise von einem seltsamen Verhalten geplagt, das Java aufweist, wenn Sie versuchen, mit ThreadLocals zu arbeiten, wobei initialValue() innerhalb eines Methodenbereichs definiert wird und wenn dieser Wert von einem umschließenden Bereich abhängt. Sie können mehr darüber in meinem Blogpost lesen https://rationalemotions.wordpress.com/2016/05/16/a-date-with-threadlocal/ (Ich weiß nicht sicher, ob Ihr Code auch das gleiche zeigen wird Problem, aber es hat die gleiche Art von Code, der Probleme verursachen könnte) –

0

Sie könnten dies versuchen.

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

Ich versehentlich durch Klicken auf das. Entschuldigen Sie. Seit gestern habe ich versucht, es zu beheben, aber mit wenig Glück. Ich habe es jetzt behoben. Entschuldigung für die Verwirrung. –

Verwandte Themen