Der Grund, warum Ihre Lösung die JVM, die erzeugt wurde, nicht zum Absturz bringt, liegt vielleicht daran, dass Sie cmd.exe
aufrufen und von wo aus Sie wahrscheinlich die JVM generieren. Also, wenn Sie destroyProcess()
aufrufen, glaube ich, dass cmd.exe
getötet wird, aber nicht java.exe
.
Sie versuchen sollen, wie unter der Befehlszeile, um etwas zu ändern:
java -cp D:\MyProject\Utilities*;D:\MyProject\bin org.testng.TestNG D:\MyProject\testng.xml
Hier ist eine Lösung, die für das Handeln dies nicht die Verwendung von Apache commons Testamentsvollstrecker machen, aber alles in einer einzigen JVM verwaltet und bieten auch für eine Möglichkeit, die Ausgabe und die Fehlerausgabe von TestNG abzurufen.
Diese Lösung verwendet die TestNG-APIs.
Der Haupttestläufer, die TestNG verwendet Tests auszuführen, in einem anderen Thread sieht wie unten
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() +
'}';
}
}
}
Die Utility-Klasse, die alle Ausgabe- und Fehler Inhalt in einen Thread neu leitet, so dass sie umgeleitet werden, sieht wie folgt aus:
Diese Klasse ist meist geliehen Code aus der Lösung mit einigen Improvisationen.
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() + '\'' +
'}';
}
}
}
Die Testklasse verwendet sieht aus wie unten
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");
}
}
Die Ausgabe wie folgt aussieht unten
***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
Warum brauchen Sie Apache Testamentsvollstrecker verwenden, um eine 'TestNG' Suite Ausführung ausgliedern? Sie sind besser dran mit dem TestNG Apis direkt in Ihrem Java-Code Nein? Bitte zeigen Sie uns auch, wie 'cl' a.k.a Ihre' CommandLine' aussieht. –
@KrishnanMahadevan Ich möchte die Konsolenausgabe direkt an ein Jframe-Textfeld senden, von dem ich nicht sicher bin, ob es über TestNG-APIs möglich ist. Außerdem möchte ich es als einen anderen Thread ausführen, damit die Hauptanwendung nicht hängt. Der Befehl c1 lautet: cmd.exe/k cd "D: \ MeinProjekt" && D: && java -cp D: \ MeinProjekt \ Dienstprogramme \ *; D: \ MeinProjekt \ bin org.testng.TestNG D: \ MeinProjekt \ testng .xml –