使用 ExtentReports 的并行 TestNG 测试使用了错误的 @BeforeMethod

Parallel TestNG tests with ExtentReports are using the wrong @BeforeMethod

我是运行单机ThreadLocal测试。我使用@BeforeMethod 中的代码启动网页。我也尝试在我的基础测试 class 中将其作为方法单独编写,并在 @BeforeMethod 中调用它。

一切似乎都运行良好,除了错误的用户使用错误的测试登录。这很奇怪,因为登录方法不在 BaseTest class 中,它是从页面对象调用的(而且它工作正常,除了为测试登录错误的用户)。

在这个例子中,我在@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.

看起来您的测试遇到了驾驶员身份危机,当 运行 在本地并行时,WebDriver 属于他们。

ThreadLocal<WebDriver> threadedDrivergetDriver()setDriver() 设置为 而不是 static 应该可以解决问题。