【问题标题】:TestNG fails to shutdown Selenium Browser in AfterClass methodTestNG 无法在 AfterClass 方法中关闭 Selenium 浏览器
【发布时间】:2014-06-26 23:15:38
【问题描述】:

场景是这样的: 运行我的 Cucumber 功能的 TestNG 测试运行程序。 有一个包含 WebBrowsers 的静态共享 Selenium WebDriver 池。 在 TestNG 测试结束时,我想关闭我的浏览器,所以我使用了 @AfterClass 注释。 进行了调用,代码运行以关闭浏览器,但实际上它们从未这样做。

如果我在调用后添加 Thread.sleep 一秒钟,浏览器会正常关闭。

JUnit 测试运行器每次都成功地关闭浏览器。 TestNG 有什么特别(错误)?


有问题的测试运行器的链接在这里:

https://github.com/OliverCulleyDeLange/Cucumber_Selenium_Hamcrest/blob/master/src/test/java/uk/co/oliverdelange/testrunners/testng/TestNGCucumberRunner.java

随意克隆并亲自查看结果。


违规测试运行代码:

package uk.co.oliverdelange.testrunners.testng;

import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import uk.co.oliverdelange.webbrowser.BrowserPool;

@CucumberOptions(tags = "~@Ignore",
        features = "src/test/resources/uk/co/oliverdelange/cucumber/",
        glue = "uk.co.oliverdelange.cucumber.tests",
        format = {"pretty","html:CucumberReports/html/","json:CucumberReports/cucumber.json"},
        monochrome = true
)
public class TestNGCucumberRunner extends AbstractTestNGCucumberTests {
    @BeforeClass
    public static void beforeClass() {
        System.out.println("Do stuff here before the cucumber tests happen");
    }

    @AfterClass
    public static void afterClass() { //FIXME why is this not being called?
        System.out.println("Do stuff here after the cucumber tests happen");
        System.out.println("Like shutting down all the web browsers...");
        BrowserPool.closeAll();
        //FIXME: JUnit manages to close the browser before closing the tests, but somehow TestNG doesn't - what!?
    }
}

【问题讨论】:

  • 我知道很多人喜欢 TestNG,但根据我的经验,它充满了 bug,而且很少被修复。很久以前,我自己的生命周期注释有问题(github.com/cbeust/testng/issues/425),甚至提出了一个从未合并的补丁。不幸的是,我只能建议不要使用 TestNG。 JUnit 有一个更干净的代码库,而 TestNG 是一个充满错误的烂摊子。我不知道您是否偶然发现了这样的错误。

标签: java junit selenium-webdriver cucumber testng


【解决方案1】:

我从未见过有人在 AfterClass 方法中的一次调用中调用关闭一组/池的 webdriver 实例。通常,人们所做的是在 BeforeTest 中实例化浏览器,然后在 AfterTest 方法中使用 .quit 调用关闭单个非静态类 webdriver 成员。所以,看你的代码,我的第一印象是你在做一些非标准和实验性的事情。 TestNG 很棒,它为您分叉进程,并且在这种情况下很容易跟踪 webdriver 实例。我永远不会使用 JUnit……在我了解了 TestNG 之后,我确信它要好得多。

例如:

  1. 您可以将可选的 Object[] 参数传递给使用 BeforeMethod 注释的方法,然后您可以从中检索参数 即将传递给测试方法,例如调用 obj.start 后打开浏览器的 WebDriver 辅助对象(在数据提供者方法中生成)。天才。

  2. 您可以将 ITestResult 传递给 AfterTest 方法,然后从结果中获取内容并使用该信息对内容进行后期处理,例如 完成测试后发送 SauceLabs REST 请求以将测试作业标记为通过。

【讨论】:

  • 但是每次测试都需要打开一个新的浏览器,这很慢。这样我们就有了一个浏​​览器池,测试可以在需要时打开这些浏览器。完全同意它的非标准和实验性:D
  • 是的,它每次测试打开一个浏览器线程,但是,例如,这就是 Selenium Grid 的工作方式,所以是的,为每个单独的测试打开一个新的浏览器是一个标准。如果您想使用本地浏览器池,那么您将自己排除在使用 Selenium Grid 之外,这也是非常不标准的。 Selenium Grid 是一个浏览器池,您正在重新发明轮子。如果我是你,我会不再担心启动浏览器会有点慢,而是更多地关注你从测试中得到什么。
  • 我不是为任何特定的项目或要求这样做,只是为了尝试改进当前流程并加快速度。我在我的工作 Ubuntu 机器上尝试了这个,它在没有 Thread.sleep 的情况下工作正常。所以我现在更加困惑。可能是一些奇怪的边缘案例/环境问题。无论如何干杯!
猜你喜欢
  • 1970-01-01
  • 2018-02-01
  • 2012-04-18
  • 2014-04-15
  • 1970-01-01
  • 2014-01-27
  • 1970-01-01
  • 2020-10-10
相关资源
最近更新 更多