代码之家  ›  专栏  ›  技术社区  ›  tetienne

TestNG监听器,如何让测试使用单例

  •  0
  • tetienne  · 技术社区  · 6 年前

    我们使用TestNG监听器特性在外部工具中报告测试结果。它工作得很好。

    但现在,我们想添加一个由singleton(threadlocalwebdriver)包含的信息。我们的测试活动是并行运行的,所以我们有多个singleton实例。

    例如,我们如何在onSuccess方法中获得正确的单例并报告正确的信息?

    编辑:代码示例

    public class QTestWrapper implements ISuiteListener, ITestListener {
    ...
        @Override
      public void onTestSuccess(ITestResult result) {
        String sessionId = MyDriver.getSessionId();
        // do my job with this session id
      }
    ...
    }
    
    
    public final class MyDriver {
    
    
      private static final ThreadLocal<MyDriver> MY_DRIVER =
          ThreadLocal.withInitial(MyDriver::buildDriver);
    
      private WebDriver driver;
    
      private MyDriver(WebDriver driver) {
        this.driver = driver;
      }
    
      public static MyDriver getDriver() {
        return MY_DRIVER.get();
      }
    
      private static MyDriver buildDriver() {
        URL remoteAddress = getHubAddress();
        DesiredCapabilities caps = buildCapabilities();
        WebDriver driver = new RemoteWebDriver(remoteAddress, caps);
        return new MyDriver(driver);
      }
    
      public static String getSessionId() {
        String sessionId = null;
        MyDriver driver = MY_DRIVER.get();
        if (driver != null && driver.getWrappedDriver() != null) {
          WebDriver wrappedDriver = driver.getWrappedDriver();
          sessionId = ((RemoteWebDriver) wrappedDriver).getSessionId().toString();
        }
        return sessionId;
      }
    
      public WebDriver getWrappedDriver() {
        return driver;
      }
    
    
    }
    
    public class TestLogin {
    
      @AfterMethod(alwaysRun = true)
      public void die() {
        StickyDriver.quit();
      }
    
      @Test(description = "Check that a user can login with a Manager profile.")
      public void loginAsManager() {
        Actor actor = new Actor("foo");
        String userName = actor.openBrowserAndLogin().getUserName();
        assertThat(userName).isEqualTo("foo");
      }
    
    }
    
    
    public class Actor {
    
      private static final Logger LOGGER = LogManager.getLogger();
    
      private final MyDriver driver;
      private User user;
    
      public Actor(String userName) {
        user = User.getUser(userName);
        driver = MyDriver.getDriver();
      }
    
    
      public Actor(User user) {
        this.user = Objects.requireNonNull(user);
        driver = MyDriver.getDriver();
      }
    
      public HomePage openBrowserAndLogin() {
        openBrowser();
        return login();
      }
    
      public HomePage login() {
        LoginPage loginPage = new LoginPage(driver);
        loginPage.getUserNameField().setValue(user.getUsername());
        loginPage.getPasswordField().setValue(user.getPassword());
        return loginPage.login();
      }
    
      private void openBrowser() {
        String url = EnvironmentHelper.getUrl();
        WebDriver webDriver = driver.getWrappedDriver();
        webDriver.get(url);
        try {
          new WebDriverWait(webDriver, 60).until(AjaxExpectedConditions.callsHaveCompleted());
        } catch (TimeoutException ex) {
          closeBrowser();
          throw ex;
        }
      }
    
      public void closeBrowser() {
        MyDriver.quit();
      }
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Krishnan Mahadevan    6 年前

    TestNG不保证 @Test onSuccess() 将在同一线程中执行。

    只有在您与 org.testng.IInvokedMethodListener 实施

    因此,请更改您的实现以执行以下操作:

    • 上课吧 QTestWrapper 使生效 组织。测试NG。IInvokedMethodListener
    • afterInvocation() 属于 组织。测试NG。IInvokedMethodListener 检查执行的方法是否为 @测试 方法,如果其状态为通过,并且如果通过,则在 onSuccess() 进入其中。