首页 文章

Selenium Webdriver TestNG测试相互“覆盖”

提问于
浏览
0

我正在尝试使用TestNG在一台机器上并行运行Selenium Webdriver测试 . 我有3个@Test方法,其中3个不同的用户登录到同一个应用程序并到达主页 . 我需要@Test方法并行运行,并写入ExtentReports报告 .

我的问题是,尽管在不同的类中有3种完全不同的方法,但其中一个用户将登录到3个浏览器中的2个,从而使用户离开 .

login方法位于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 Object的登录方法 .

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不同) . 但我不明白这是怎么回事 . Base Test方法成功打开和关闭3个浏览器 . 看起来@Test方法似乎使用了彼此的数据!但为了以防万一,这是我的@Before和@After,我的线程代码 .

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 回答

  • 2

    假设你的所有 @Test 方法都在不同的类中,我猜这个问题可能是因为你的 ThreadLocal 变量是 NOT STATIC 但是是一个实例变量 . 这会导致行为 per thread per instance 而不是所需的行为,即 per thread across all instances . 您可以参考this StackOverFlow线程以获得更好的解释 .

    您将使用 ThreadLocal if and only if 的实例变体,所有 @Test 方法都属于同一个测试类(因为现在您只是尝试确保在所有测试方法中以线程安全的方式共享类级别数据成员 WebDriver 属于同一个测试类)

    因此,如果您的每个 @Test 方法都驻留在自己的Test类中,请尝试更改:

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

    private static ThreadLocal<WebDriver> threadedDriver = new ThreadLocal<WebDriver>();
    
  • 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();
    }
    

    }

相关问题