【问题标题】:How to invoke shutdown hooks of a program running in another thread如何调用在另一个线程中运行的程序的关闭挂钩
【发布时间】:2014-05-18 16:37:15
【问题描述】:

我正在使用 Jemmy 框架为 Swing 应用程序编写自动化测试。

我的测试套件通过在新线程中调用其 Main 类的 main 方法来运行此应用程序。

我已经编写了很多与 GUI 相关的测试,但现在我有一个更复杂的任务。

我需要检查被测试的应用程序在关闭时是否对文件夹进行了一些清理。此操作可能作为关闭挂钩执行。是否可以在不调用 System.exit(0) 的情况下调用该应用程序的关闭挂钩?

调用此命令时,两个线程都将终止。但是我希望测试的线程在测试的应用程序关闭后继续运行,这样我就可以检查这些文件夹是否仍然存在。是否可以在不更改测试套件架构的情况下调用关闭挂钩?

【问题讨论】:

    标签: java multithreading shutdown-hook systemexit


    【解决方案1】:

    如果你要写测试,最好写好的。

    你不需要弄乱 JVM 来结束一个线程而不是另一个:你只需要确保当窗口关闭时执行关闭代码,否则会假定非正常关闭。将该代码放入可以单独测试的方法中,就完成了。可能您实际上并不需要向 JVM 添加关闭挂钩。

    您可能希望在引导代码中检查(并可能修复)系统状态。

    【讨论】:

    • 这里的问题是我不是那个应用程序的开发者,所以我不能影响它的实现方式。我只得到 jar 文件并测试它的行为。我使用自己的安全管理器来防止应用程序终止我的测试套件,因此当单击退出按钮时,什么都没有发生。
    • @livthomas 那么你为什么不安排你的测试,使外部 jar 在一个单独的 JVM(我的意思是另一个进程)中启动,而不是你用来启动测试的那个?
    • 我无法在另一个进程中运行它。 Jemmy 测试必须在与被测应用程序相同的 JVM 中执行,因为它们会在内存中搜索 Swing 组件。
    【解决方案2】:

    将关闭挂钩的重要部分放在单独的方法/类中,然后您将能够对此代码进行单元测试,而无需运行整个应用程序。然后,假设您在应用程序启动时注册了钩子,您应该几乎可以依赖 JVM 来调用您的钩子,因此不测试钩子实际执行的事实并不是那么糟糕的 IMO。如果您确实需要测试完整的端到端行为,那么您可能应该在与应用程序测试分开的进程中运行测试代码,无论如何,在这种情况下,您可以测试实际预期的清理行为,而无需“插入”钩子(例如检查某些文件在应用程序启动后确实存在但在应用程序关闭后消失)。

    【讨论】:

      【解决方案3】:

      我发现了这个,但我没有测试它:

      ApplicationShutdownHooks.hook().run(); // JRE 6
      ApplicationShutdownHooks.runHooks();   // JRE 7
      

      如您所见,方法的名称会随着时间而改变,这意味着您真的不应该这样做。但是,我认为这应该可以完成工作,但是课程是私人的。使用一些反射,您可以强制执行它。

      // JRE 7
      try
      {
          Class cl = Class.forName("java.lang.ApplicationShutdownHooks");
          Method m = cl.getDeclaredMethod("runHooks");
          m.setAccessible(true);
          m.invoke(null);
      } catch (Exception e)
      {
          e.printStackTrace(System.out);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-03-28
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多