在java

时间:2015-11-13 16:01:10

标签: java user-interface testng terminate

我有一个执行TestNG自动化脚本的GUI程序。这意味着用户可以轻松配置一些设置并启动他们想要的自动化脚本。

我需要补充的一点是能够立即停止正在运行的TestNG流程。就像在Eclipse中一样,“终止”按钮会立即停止正在运行的任何内容。

这是启动TestNG测试的代码:

public class ScriptRunner implements Runnable {

    public void runScript() {
        Thread testRun = new Thread(this);
        testRun.start();
    }

    @Override
    public void run() {
        //various other things are configured for this, 
        //but they're not relevant so I left them out
        TestNG tng = new TestNG();

        //While this runs, various browser windows are open, 
        //and it could take several minutes for it all to finish
        tng.run();
    }
}

根据评论,tng.run()可能需要几分钟才能完成,它正在执行多项操作,打开/关闭浏览器窗口等。

如何立即终止流程,就像从IDE运行应用程序一样?

编辑:

根据评论,我正在尝试使用ServiceExecutor和shutDownNow()代码看起来像这样:

ExecutorService executorService = Executors.newFixedThreadPool(10);

public void runScript() {
    executorService.execute(this);
}

//this method gets called when I click the "stop" button
public void stopRun() {
    executorService.shutdownNow();
}

@Override
public void run() {
    //same stuff as from earlier code
}

7 个答案:

答案 0 :(得分:3)

使用ProcessBuilder或Runtime生成子JVM进程,当用户请求脚本停止运行时,您将能够终止该进程。

答案 1 :(得分:2)

您可以使用ExecutorService将测试执行开始到另一个线程中。通过选择所需的执行服务,您可以选择在并行或juste一个线程中为所有测试顺序选择多个线程。

之后,通过调用submit()方法在同一个执行器服务实例中开始执行所有测试。您可以通过调用shutdownNow()方法停止执行所有提交的runnable。

使用相同的ExecutorService实例非常重要,否则您将在另一个线程中启动每个测试,并且您不会启用中断执行链(或通过在所有测试中调用shutdownNow())。

答案 2 :(得分:1)

保存所有已创建的进程,并在程序结束时将其终止:

public class ProcessFactory {
  private static Set<Process> processes = new HashSet<>();
  private static boolean isRunning = true;

  public static synchronized Process createProcess(...) throws ... {
    if (!isRunning)
      throw ...
    ... // create your spawned process
    processes.add(process);
    return process;
  }

  public static synchronized void killAll() {
    isRunning = false;
    for (Process p : processes)
        p.destroy();
    processes.clear();
  }

  public static void registerShutdownHook() {
      Runtime.getRuntime().addShutdownHook(new Thread() {
         void run() {
             killAll();
         }
      });
  }
}

这可以通过添加一个删除已经死的进程的机制来改进,但是你可以得到一般的想法。

答案 3 :(得分:1)

这个怎么样, 添加一个volatile静态布尔值并使线程代码看起来像......

if(ScriptRunner.runThread){
    //Do some stuff here
}
if(ScriptRunner.runThread){
    //Do some other stuff here
}
if(ScriptRunner.runThread){
    //Do some other stuff here
}
if(ScriptRunner.runThread){
    //Do rest of the stuff here
}

现在您可以在主GUI中添加一个按钮,只需将runThread设置为false,这样线程几乎会立即终止,当您按下Stop按钮时,所有剩余的代码都不会被触及。

public class ScriptRunner implements Runnable {

    volatile static Boolean runThread = true;

    public void runScript() {
        Thread testRun = new Thread(this);
        testRun.start();
    }

    public void terminate(){
        runThread = false;
    }

    @Override
    public void run() {
        //various other things are configured for this, 
        //but they're not relevant so I left them out
        TestNG tng = new TestNG();

        //While this runs, various browser windows are open, 
        //and it could take several minutes for it all to finish
        tng.run();
    }
}

答案 4 :(得分:1)

新线程怎么样?您必须在gui中添加private Thread thread;,然后何时开始

thread = new thread(){
    @Override
    public void run(){
       //start process here
    }
};
thread.start();

并停止&#34;终止&#34;

thread.stop();(已删除)或thread.setDeamon(true);

每次我必须停止使用gui的过程。

希望我能提供帮助;)

答案 5 :(得分:1)

在您的GUI中,您可以使用

ScriptRunner scriptRunner = new ScriptRunner();
scriptRunner.runScript();

当你想停止它时,请致电

scriptRunner.interrupt();

更改ScriptRunner中的代码

private Thread testRun;
public void runScript() {
    testRun = new Thread(this);
    testRun.start();
}

public void interrupt() {
    testRun.interrupt();
}

答案 6 :(得分:1)

我最近在处理执行程序框架。我在这里列出了我的问题 http://programtalk.com/java/executorservice-not-shutting-down/

如果您正在执行某些IO操作,请小心执行程序服务可能不会立即关闭。如果你看到下面的代码stopThread很重要,因为它告诉你的程序已经要求线程停止。你可以停止一些迭代你正在做什么。 我将修改你的代码:

public class MyClass {

private ExecutorService executorService;

private boolean stopThread = false;

public void start() {
   // gives name to threads
    BasicThreadFactory factory = new BasicThreadFactory.Builder()
             .namingPattern("thread-%d").build();
    executorService =  Executors.newSingleThreadExecutor(factory);
    executorService.execute(new Runnable() {
        @Override
        public void run() {
            try {
                doTask();
            } catch (Exception e) {
                logger.error("indexing failed", e);
            }

        }
    });
    executorService.shutdown();
}

private void doTask()  {
    logger.info("start reindexing of my objects");
    List<MyObjects> listOfMyObjects = new MyClass().getMyObjects();
    for (MyObjects myObject : listOfMyObjects) {
        if(stopThread){ // this is important to stop further indexing
            return;
        }
        DbObject dbObjects = getDataFromDB();
        // do some task
    }
}



public void stop() {
    this.stopThread = true;
    if(executorService != null){
        try {
            // wait 1 second for closing all threads
            executorService.awaitTermination(1, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

}