testframework refactoring: deal with testng output the same way as junit

This commit is contained in:
anna
2010-07-23 12:37:57 +04:00
parent bc5ab28d29
commit abe0fea650
7 changed files with 106 additions and 192 deletions
@@ -22,7 +22,7 @@ import java.util.List;
public class CompositePrintable implements Printable {
public static final String NEW_LINE = "\n";
private final ArrayList<Printable> myNestedPrintables = new ArrayList<Printable>();
protected final ArrayList<Printable> myNestedPrintables = new ArrayList<Printable>();
public void printOn(final Printer printer) {
printAllOn(myNestedPrintables, printer);
@@ -31,9 +31,7 @@ import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.TestFrameworkRunningModel;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.execution.testframework.*;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.openapi.application.PathManager;
@@ -60,10 +58,7 @@ import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.PathUtil;
import com.intellij.util.net.NetUtils;
import com.theoryinpractice.testng.model.IDEARemoteTestRunnerClient;
import com.theoryinpractice.testng.model.TestData;
import com.theoryinpractice.testng.model.TestNGRemoteListener;
import com.theoryinpractice.testng.model.TestType;
import com.theoryinpractice.testng.model.*;
import com.theoryinpractice.testng.ui.TestNGConsoleView;
import com.theoryinpractice.testng.ui.TestNGResults;
import com.theoryinpractice.testng.ui.actions.RerunFailedTestsAction;
@@ -131,7 +126,8 @@ public class TestNGRunnableState extends JavaCommandLineState {
}
throw e;
}
final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings);
final TreeRootNode unboundOutputRoot = new TreeRootNode();
final TestNGConsoleView console = new TestNGConsoleView(config, runnerSettings, myConfigurationPerRunnerSettings, unboundOutputRoot);
console.initUI();
for (RunConfigurationExtension ext : Extensions.getExtensions(RunConfigurationExtension.EP_NAME)) {
ext.handleStartProcess(config, processHandler);
@@ -166,8 +162,9 @@ public class TestNGRunnableState extends JavaCommandLineState {
@Override
public void startNotified(final ProcessEvent event) {
TestNGRemoteListener listener = new TestNGRemoteListener(console);
TestNGRemoteListener listener = new TestNGRemoteListener(console, unboundOutputRoot);
client.startListening(listener, listener, port);
}
@Override
@@ -180,9 +177,20 @@ public class TestNGRunnableState extends JavaCommandLineState {
@Override
public void onTextAvailable(final ProcessEvent event, final Key outputType) {
//we override this since we wrap the underlying console, and proxy the attach call,
//so we never get a chance to intercept the text.
console.print(event.getText(), ConsoleViewContentType.getConsoleViewType(outputType));
final TestProxy currentTest = console.getCurrentTest();
final String text = event.getText();
final ConsoleViewContentType consoleViewType = ConsoleViewContentType.getConsoleViewType(outputType);
final Printable printable = new Printable() {
public void printOn(final Printer printer) {
printer.print(text, consoleViewType);
}
};
if (currentTest != null) {
currentTest.addLast(printable);
}
else {
unboundOutputRoot.addLast(printable);
}
}
});
console.attachToProcess(processHandler);
@@ -27,58 +27,60 @@ import com.theoryinpractice.testng.ui.TestNGResults;
import org.testng.remote.strprotocol.*;
public class TestNGRemoteListener implements IRemoteSuiteListener, IRemoteTestListener {
private final TestNGConsoleView console;
private final TestNGConsoleView console;
private final TreeRootNode unboundOutputRoot;
public TestNGRemoteListener(TestNGConsoleView console) {
this.console = console;
}
public TestNGRemoteListener(TestNGConsoleView console, TreeRootNode unboundOutputRoot) {
this.console = console;
this.unboundOutputRoot = unboundOutputRoot;
}
public void onInitialization(GenericMessage genericMessage) {
}
public void onInitialization(GenericMessage genericMessage) {
}
public void onStart(SuiteMessage suiteMessage) {
console.flushOutput();
final TestNGResults view = console.getResultsView();
if (view != null) {
view.start();
}
public void onStart(SuiteMessage suiteMessage) {
final TestNGResults view = console.getResultsView();
if (view != null) {
view.start();
}
}
public void onFinish(SuiteMessage suiteMessage) {
console.flush();
final TestNGResults view = console.getResultsView();
if (view != null) {
view.finish();
}
public void onFinish(SuiteMessage suiteMessage) {
console.finish();
final TestNGResults view = console.getResultsView();
if (view != null) {
view.finish();
}
}
public void onStart(TestMessage tm) {
final TestNGResults view = console.getResultsView();
if (view != null) {
view.setTotal(tm.getTestMethodCount());
}
public void onStart(TestMessage tm) {
unboundOutputRoot.addChild(console.getResultsView().getRoot());
final TestNGResults view = console.getResultsView();
if (view != null) {
view.setTotal(tm.getTestMethodCount());
}
}
public void onTestStart(TestResultMessage trm) {
console.testStarted(trm);
}
public void onTestStart(TestResultMessage trm) {
console.testStarted(trm);
}
public void onFinish(TestMessage tm) {
console.rebuildTree();
}
public void onFinish(TestMessage tm) {
console.rebuildTree();
}
public void onTestSuccess(TestResultMessage trm) {
console.addTestResult(trm);
}
public void onTestSuccess(TestResultMessage trm) {
console.addTestResult(trm);
}
public void onTestFailure(TestResultMessage trm) {
console.addTestResult(trm);
}
public void onTestFailure(TestResultMessage trm) {
console.addTestResult(trm);
}
public void onTestSkipped(TestResultMessage trm) {
console.addTestResult(trm);
}
public void onTestSkipped(TestResultMessage trm) {
console.addTestResult(trm);
}
public void onTestFailedButWithinSuccessPercentage(TestResultMessage trm) {
}
public void onTestFailedButWithinSuccessPercentage(TestResultMessage trm) {
}
}
@@ -47,7 +47,6 @@ public class TestProxy extends AbstractTestProxy {
private TestResultMessage resultMessage;
private String name;
private TestProxy parent;
private List<Printable> output;
private SmartPsiElementPointer psiElement;
private boolean inProgress;
private int myExceptionMark;
@@ -86,19 +85,6 @@ public class TestProxy extends AbstractTestProxy {
return filter.select(results);
}
public List<Printable> getOutput() {
if (output != null) return output;
List<Printable> total = new ArrayList<Printable>();
for (TestProxy child : results) {
final List<Printable> out = child.getOutput();
if (total.size() > 0 && out.size() > 0) {
total.add(new TestNGConsoleView.Chunk("\n===============================================\n\n", ConsoleViewContentType.NORMAL_OUTPUT));
}
total.addAll(out);
}
return total;
}
public List<TestProxy> getChildren() {
return results;
}
@@ -170,7 +156,7 @@ public class TestProxy extends AbstractTestProxy {
public Navigatable getDescriptor(final Location location) {
if (location == null) return null;
if (isNotPassed() && output != null) {
if (isNotPassed()) {
final PsiLocation<?> psiLocation = location.toPsiLocation();
final PsiClass containingClass = psiLocation.getParentElement(PsiClass.class);
if (containingClass != null) {
@@ -181,7 +167,7 @@ public class TestProxy extends AbstractTestProxy {
}
if (containingMethod != null) {
final String qualifiedName = containingClass.getQualifiedName();
for (Printable aStackTrace : output) {
for (Printable aStackTrace : myNestedPrintables) {
if (aStackTrace instanceof TestNGConsoleView.Chunk) {
final String[] stackTrace = new LineTokenizer(((TestNGConsoleView.Chunk)aStackTrace).text).execute();
for (String line : stackTrace) {
@@ -203,9 +189,10 @@ public class TestProxy extends AbstractTestProxy {
return name + ' ' + results;
}
public void addResult(TestProxy proxy) {
public void addChild(TestProxy proxy) {
results.add(proxy);
proxy.setParent(this);
addLast(proxy);
}
public void setParent(TestProxy parent) {
@@ -216,10 +203,6 @@ public class TestProxy extends AbstractTestProxy {
return parent;
}
public void setOutput(List<Printable> output) {
this.output = output;
}
public boolean isNotPassed() {
if (resultNotPassed()) return true;
//we just added the node, so we don't know if it has passes or fails
@@ -260,9 +243,9 @@ public class TestProxy extends AbstractTestProxy {
return null;
}
public int getExceptionMark() {
public int getExceptionMark() {//todo
if (myExceptionMark == 0 && getChildCount() > 0) {
return (output != null ? output.size() : 0) + getChildAt(0).getExceptionMark();
return getChildAt(0).getExceptionMark();
}
return myExceptionMark;
}
@@ -50,7 +50,7 @@ public class TestTreeBuilder extends AbstractTestTreeBuilder
}
public void addItem(TestProxy parent, TestProxy proxy) {
parent.addResult(proxy);
parent.addChild(proxy);
DefaultMutableTreeNode parentNode = getNodeForElement(parent);
if (parentNode != null)
updateSubtree(parentNode);
@@ -28,6 +28,7 @@ import com.intellij.execution.filters.HyperlinkInfo;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.testframework.Printable;
import com.intellij.execution.testframework.Printer;
import com.intellij.execution.testframework.TestTreeView;
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView;
import com.intellij.execution.testframework.ui.TestResultsPanel;
@@ -37,10 +38,13 @@ import com.intellij.openapi.application.ApplicationManager;
import com.theoryinpractice.testng.configuration.TestNGConfiguration;
import com.theoryinpractice.testng.model.TestNGConsoleProperties;
import com.theoryinpractice.testng.model.TestProxy;
import com.theoryinpractice.testng.model.TreeRootNode;
import org.jetbrains.annotations.NonNls;
import org.testng.remote.strprotocol.TestResultMessage;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@@ -54,8 +58,7 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView {
@NonNls private static final Pattern EXPECTED_NOT_SAME_BUT_WAS_PATTERN =
Pattern.compile("(.*)expected not same with:\\<(.*)\\> but was:\\<(.*)\\>.*", Pattern.DOTALL);
private TestNGResults testNGResults;
private final List<Printable> currentTestOutput = new ArrayList<Printable>();
private final List<Printable> nonTestOutput = new ArrayList<Printable>();
private TestProxy currentTest;
private int myExceptionalMark = -1;
private final TestNGConfiguration myConfiguration;
@@ -64,8 +67,9 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView {
public TestNGConsoleView(TestNGConfiguration config,
final RunnerSettings runnerSettings,
final ConfigurationPerRunnerSettings configurationPerRunnerSettings) {
super(new TestNGConsoleProperties(config), null);
final ConfigurationPerRunnerSettings configurationPerRunnerSettings,
final TreeRootNode unboundOutputRoot) {
super(new TestNGConsoleProperties(config), unboundOutputRoot);
myConfiguration = config;
myRunnerSettings = runnerSettings;
myConfigurationPerRunnerSettings = configurationPerRunnerSettings;
@@ -76,6 +80,16 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView {
return testNGResults;
}
@Override
public void initUI() {
super.initUI();
final TestTreeView testTreeView = testNGResults.getTreeView();
testTreeView.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
getPrinter().updateOnTestSelected(testTreeView.getSelectedTest());
}
});
}
@Override
public void dispose() {
@@ -96,50 +110,30 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView {
public void addTestResult(TestResultMessage result) {
if (testNGResults != null) {
int exceptionMark = myExceptionalMark == -1 ? 0 : myExceptionalMark;
final String stackTrace = result.getStackTrace();
if (stackTrace != null && stackTrace.length() > 10) {
//trim useless crud from stacktrace
String trimmed = trimStackTrace(stackTrace);
List<Printable> printables = getPrintables(result, trimmed);
for (Printable printable : printables) {
printable.printOn(wrapConsoleView(getConsole())); //enable for root element
}
synchronized (currentTestOutput) {
exceptionMark = currentTestOutput.size();
currentTestOutput.addAll(printables);
currentTest.addLast(printable);
}
exceptionMark = printables.size();
}
testNGResults.addTestResult(result, new ArrayList<Printable>(currentTestOutput), exceptionMark);
final TestProxy failedToStart = testNGResults.getFailedToStart();
if (failedToStart != null) {
currentTest.addChild(failedToStart);
exceptionMark += failedToStart.getExceptionMark();
}
testNGResults.addTestResult(result, exceptionMark);
myExceptionalMark = -1;
synchronized (currentTestOutput) {
currentTestOutput.clear();
}
}
}
public void testStarted(TestResultMessage result) {
if (testNGResults != null) {
testNGResults.testStarted(result);
}
}
public void flushOutput() {
synchronized (currentTestOutput) {
if (!currentTestOutput.isEmpty()) { //non empty for first test only
nonTestOutput.addAll(currentTestOutput);
currentTestOutput.clear();
}
}
}
public void flush() {
final TestProxy failedToStart = testNGResults.getFailedToStart();
if (failedToStart != null) {
final List<Printable> output = failedToStart.getOutput();
if (output != null) {
nonTestOutput.addAll(output);
}
currentTest = testNGResults.testStarted(result);
}
}
@@ -204,66 +198,15 @@ public class TestNGConsoleView extends BaseTestsOutputConsoleView {
return printables;
}
public void print(String s, ConsoleViewContentType contentType) {
if (myExceptionalMark == -1 && contentType == ConsoleViewContentType.ERROR_OUTPUT) {
myExceptionalMark = currentTestOutput.size();
}
Chunk chunk = new Chunk(s, contentType);
synchronized (currentTestOutput) {
currentTestOutput.add(chunk);
}
}
public void reset() {
final List<Printable> printables = new ArrayList<Printable>();
printables.addAll(nonTestOutput);
printables.addAll(testNGResults.getRoot().getOutput());
printables.addAll(currentTestOutput);
setView(printables, 0);
}
public void attachToProcess(ProcessHandler processHandler) {
getConsole().attachToProcess(processHandler);
}
public void setView(final List<Printable> output, final int i) {
if (!ApplicationManager.getApplication().isDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setView(output, i);
}
});
}
else {
final ConsoleView consoleView = getConsole();
consoleView.clear();
int idx = 0;
int offset = 0;
for (Printable chunk : new ArrayList<Printable>(output)) {
chunk.printOn(wrapConsoleView(consoleView));
if (idx++ < i) {
offset = consoleView.getContentSize();
}
}
consoleView.scrollTo(offset);
}
}
private static Printer wrapConsoleView(final ConsoleView consoleView) {
return new Printer() {
public void print(String text, ConsoleViewContentType contentType) {
consoleView.print(text, contentType);
}
public TestProxy getCurrentTest() {
return currentTest;
}
public void onNewAvailable(Printable printable) {}
public void printHyperlink(String text, HyperlinkInfo info) {
consoleView.printHyperlink(text, info);
}
public void mark() {
}
};
public void finish() {
currentTest = null;
}
public static class Chunk implements Printable {
@@ -81,7 +81,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
private final TreeRootNode rootNode;
private static final String NO_PACKAGE = "No Package";
private TestNGResults.OpenSourceSelectionListener openSourceListener;
private final TestNGConsoleView myConsole;
private int myStatus = MessageHelper.PASSED_TEST;
private Set<String> startedMethods = new HashSet<String>();
@@ -92,7 +91,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
final ConfigurationPerRunnerSettings configurationSettings) {
super(component, console.createConsoleActions(), console.getProperties(),
runnerSettings, configurationSettings, TESTNG_SPLITTER_PROPERTY, 0.5f);
myConsole = console;
this.project = configuration.getProject();
model = new TestNGResultsTableModel();
@@ -132,7 +130,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
animator = new Animator(this, treeBuilder);
openSourceListener = new OpenSourceSelectionListener(structure, myConsole);
openSourceListener = new OpenSourceSelectionListener();
tree.getSelectionModel().addTreeSelectionListener(openSourceListener);
return tree;
@@ -218,11 +216,8 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
return proxy;
}
public void addTestResult(final TestResultMessage result, List<Printable> output, int exceptionMark) {
if (failedToStart != null) {
output.addAll(failedToStart.getOutput());
exceptionMark += failedToStart.getExceptionMark();
}
public void addTestResult(final TestResultMessage result, int exceptionMark) {
TestProxy testCase;
synchronized (started) {
@@ -261,7 +256,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
failedToStart = testCase;
}
testCase.setOutput(output);
testCase.setExceptionMark(exceptionMark);
if (result.getResult() == MessageHelper.FAILED_TEST) {
@@ -415,8 +409,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
public void dispose() {
super.dispose();
openSourceListener.structure = null;
openSourceListener.console = null;
tree.getSelectionModel().removeTreeSelectionListener(openSourceListener);
}
@@ -425,13 +417,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
}
private class OpenSourceSelectionListener implements TreeSelectionListener {
private TestTreeStructure structure;
private TestNGConsoleView console;
public OpenSourceSelectionListener(TestTreeStructure structure, TestNGConsoleView console) {
this.structure = structure;
this.console = console;
}
public void valueChanged(TreeSelectionEvent e) {
TreePath path = e.getPath();
@@ -441,13 +426,6 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
if (ScrollToTestSourceAction.isScrollEnabled(TestNGResults.this)) {
OpenSourceUtil.openSourcesFrom(tree, false);
}
if (proxy == structure.getRootElement()) {
console.reset();
}
else {
console
.setView(proxy.getOutput(), TestNGConsoleProperties.SCROLL_TO_STACK_TRACE.value(getProperties()) ? proxy.getExceptionMark() : 0);
}
}
}
}