我通过以下代码开始通过apache commons executor libarary执行testng.xml:
DefaultExecuteResultHandler resultHandler;
ExecuteWatchdog watchdog;
final Executor executor;
resultHandler = new DefaultExecuteResultHandler();
watchdog = new ExecuteWatchdog(-1L);
executor = new DefaultExecutor();
executor.setStreamHandler(new PumpStreamHandler(new LogOutputStream() {
@Override
protected void processLine(final String line, @SuppressWarnings("unused") int level) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
if (line.toLowerCase().indexOf("error") > -1) {
textArea.append(line+"\n");
} else if (line.toLowerCase().indexOf("warn") > -1) {
textArea.append(line+"\n");
} else {
textArea.append(line+"\n");
}
}
});
}
}));
executor.setExitValue(1);
executor.setWatchdog(watchdog);
executor.execute(cl, resultHandler);
但我想给一个停止按钮来停止这个过程。我试过了:
executor.getWatchdog().destroyProcess();
但这只会破坏看门狗。但是我开始的testng.xml继续在后台运行。我想破坏我在命令中给出的过程。 这可能吗?
答案 0 :(得分:0)
为什么你的解决方案没有杀死生成的JVM的原因可能是因为你正在调用cmd.exe
并且从那里你可能正在生成JVM。因此,当您调用destroyProcess()
时,我认为其cmd.exe
已被杀死,但未被java.exe
。
您应该尝试将命令行更改为以下内容:
java -cp D:\MyProject\Utilities*;D:\MyProject\bin org.testng.TestNG D:\MyProject\testng.xml
这是一个不使用Apache commons executor执行此操作的解决方案,但是管理单个JVM中的所有内容,并提供了一种从TestNG检索输出和错误输出的方法。
此解决方案使用TestNG API。
使用TestNG运行测试的主要测试运行器在不同的线程中如下所示
import org.testng.TestNG;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class SimpleTestRunner {
public static void main(String[] args) throws InterruptedException, ExecutionException {
System.err.println("***Main Thread running in Thread [" + Thread.currentThread().getId() + "]***");
ExecutorService service = Executors.newCachedThreadPool();
WorkerThread thread = new WorkerThread(SampleTestClass.class);
List<Future<ExecutionResults>> allResults = service.invokeAll(Collections.singletonList(thread));
service.shutdown();
ExecutionResults result = allResults.get(0).get();
System.err.println("******Printing the TestNG output******");
System.err.println(result);
System.err.println("**************************************");
}
public static class WorkerThread implements Callable<ExecutionResults> {
private Class<?>[] classes;
WorkerThread(Class<?>... classes) {
this.classes = classes;
}
@Override
public ExecutionResults call() throws Exception {
System.err.println("***Worker Thread running in Thread [" + Thread.currentThread().getId() + "]***");
TestNG testNG = new TestNG();
ExecutionResults results;
testNG.setVerbose(2);
ConsoleCapturer capturer = new ConsoleCapturer();
testNG.setTestClasses(classes);
try {
capturer.start();
testNG.run();
} finally {
ConsoleCapturer.CapturedData data = capturer.stop();
results = new ExecutionResults(data, testNG.getStatus());
}
return results;
}
}
public static class ExecutionResults {
private ConsoleCapturer.CapturedData data;
private int status;
public ExecutionResults(ConsoleCapturer.CapturedData data, int status) {
this.data = data;
this.status = status;
}
public ConsoleCapturer.CapturedData getData() {
return data;
}
public int getStatus() {
return status;
}
@Override
public String toString() {
return "ExecutionResults{" +
"data=" + getData() +
", status=" + getStatus() +
'}';
}
}
}
将所有输出和错误内容重定向到线程的实用程序类,以便可以将它们重定向到任何位置,如下所示:
这个类主要是来自解决方案Redirect console output to string in java的借用代码,有一些即兴创作。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
/**
* This class is an improvisation of the solution provided in https://stackoverflow.com/a/30665299/679824
*/
public class ConsoleCapturer {
private ByteArrayOutputStream baosOutput, baosError;
private PrintStream previousOut, previousError;
private boolean capturing;
public void start() {
if (capturing) {
return;
}
capturing = true;
previousOut = System.out;
previousError = System.err;
baosOutput = new ByteArrayOutputStream();
baosError = new ByteArrayOutputStream();
System.setOut(new PrintStream(new OutputStreamCombiner(previousOut, baosOutput)));
System.setErr(new PrintStream(new OutputStreamCombiner(previousError, baosError)));
}
public CapturedData stop() {
if (!capturing) {
return new CapturedData();
}
System.setOut(previousOut);
System.setErr(previousError);
String output = baosOutput.toString();
String error = baosError.toString();
try {
baosOutput.close();
baosError.close();
} catch (IOException e) {
e.printStackTrace();
}
baosOutput = null;
previousOut = null;
capturing = false;
return new CapturedData(output, error);
}
private static class OutputStreamCombiner extends OutputStream {
private OutputStream[] outputStreams;
OutputStreamCombiner(OutputStream... outputStreams) {
this.outputStreams = outputStreams;
}
public void write(int b) throws IOException {
for (OutputStream os : outputStreams) {
os.write(b);
}
}
public void flush() throws IOException {
for (OutputStream os : outputStreams) {
os.flush();
}
}
public void close() throws IOException {
for (OutputStream os : outputStreams) {
os.close();
}
}
}
public static class CapturedData {
private String output;
private String error;
CapturedData() {
this("", "");
}
public CapturedData(String output, String error) {
this.output = output;
this.error = error;
}
public String getError() {
return error;
}
public String getOutput() {
return output;
}
@Override
public String toString() {
return "CapturedData{" +
"output='" + getOutput() + '\'' +
", error='" + getError() + '\'' +
'}';
}
}
}
使用的测试类如下所示
import org.testng.annotations.Test;
public class SampleTestClass {
@Test
public void testMethod() {
System.err.println("This goes into the error console");
System.out.println("This goes into the console");
}
}
输出如下所示
***Main Thread running in Thread [1]***
***Worker Thread running in Thread [11]***
This goes into the console
This goes into the error console
PASSED: testMethod
===============================================
Command line test
Tests run: 1, Failures: 0, Skips: 0
===============================================
===============================================
Command line suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
******Printing the TestNG output******
ExecutionResults{data=CapturedData{output='This goes into the console
PASSED: testMethod
===============================================
Command line test
Tests run: 1, Failures: 0, Skips: 0
===============================================
===============================================
Command line suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
', error='This goes into the error console
'}, status=0}
**************************************
Process finished with exit code 0