show execution times
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/IXMLTags.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/IXMLTags.java
index 36749e8..63c8fc8 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/IXMLTags.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/IXMLTags.java
@@ -72,7 +72,8 @@
*/
public static final String ATTR_INCOMPLETE= "incomplete"; //$NON-NLS-1$
-// public static final String ATTR_TIME= "time"; //$NON-NLS-1$
-// public static final String ATTR_MESSAGE= "message"; //$NON-NLS-1$
-// public static final String ATTR_TYPE= "type"; //$NON-NLS-1$
+ /**
+ * value: Double
+ */
+ public static final String ATTR_TIME= "time"; //$NON-NLS-1$
}
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestContainerElement.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestContainerElement.java
index 09a325c..3cfb5e0 100644
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestContainerElement.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestContainerElement.java
@@ -139,6 +139,20 @@
private void internalSetChildrenStatus(Status status) {
if (fChildrenStatus == status)
return;
+
+ if (status == Status.RUNNING) {
+ if (fTime >= 0.0d) {
+ // re-running child: ignore change
+ } else {
+ fTime = -System.currentTimeMillis() / 1000d;
+ }
+ } else if (status.convertToProgressState() == ProgressState.COMPLETED) {
+ if (fTime < 0) { // assert ! Double.isNaN(fTime)
+ double endTime = System.currentTimeMillis() / 1000d;
+ fTime = endTime + fTime;
+ }
+ }
+
fChildrenStatus = status;
TestContainerElement parent = getParent();
if (parent != null)
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestElement.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestElement.java
index 9abeafb..7b5c940 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestElement.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestElement.java
@@ -17,6 +17,7 @@
import org.eclipse.dltk.testing.model.ITestElementContainer;
import org.eclipse.dltk.testing.model.ITestRunSession;
+
public abstract class TestElement implements ITestElement {
public final static class Status {
public static final Status RUNNING_ERROR = new Status(
@@ -217,6 +218,16 @@
private String fTrace;
private String fExpected;
private String fActual;
+
+ /**
+ * Running time in seconds. Contents depend on the current {@link #getProgressState()}:
+ * <ul>
+ * <li>{@link org.eclipse.dltk.testing.model.ITestElement.ProgressState#NOT_STARTED}: {@link Double#NaN}</li>
+ * <li>{@link org.eclipse.dltk.testing.model.ITestElement.ProgressState#RUNNING}: negated start time</li>
+ * <li>{@link org.eclipse.dltk.testing.model.ITestElement.ProgressState#STOPPED}: elapsed time</li>
+ * <li>{@link org.eclipse.dltk.testing.model.ITestElement.ProgressState#COMPLETED}: elapsed time</li>
+ * </ul>
+ *//* default */ double fTime= Double.NaN;
/**
* @param parent
@@ -235,6 +246,7 @@
fStatus = Status.NOT_RUN;
if (parent != null)
parent.addChild(this);
+
}
/*
@@ -308,7 +320,14 @@
// TODO: notify about change?
// TODO: multiple errors/failures per test
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=125296
-
+ if (status == Status.RUNNING) {
+ fTime= - System.currentTimeMillis() / 1000d ;
+ } else if (status.convertToProgressState() == ProgressState.COMPLETED) {
+ if (fTime < 0) { // assert ! Double.isNaN(fTime)
+ double endTime= System.currentTimeMillis() / 1000.0d;
+ fTime= endTime + fTime;
+ }
+ }
fStatus = status;
TestContainerElement parent = getParent();
if (parent != null)
@@ -325,6 +344,18 @@
fActual = actual;
setStatus(status);
}
+
+ public void setElapsedTimeInSeconds(double time) {
+ fTime= time;
+ }
+
+ public double getElapsedTimeInSeconds() {
+ if (Double.isNaN(fTime) || fTime < 0.0d) {
+ return Double.NaN;
+ }
+
+ return fTime;
+ }
public Status getStatus() {
return fStatus;
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunHandler.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunHandler.java
index 4961aac..fd75f28 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunHandler.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunHandler.java
@@ -101,6 +101,7 @@
String pack= attributes.getValue(IXMLTags.ATTR_PACKAGE);
String suiteName= pack == null ? name : pack + "." + name; //$NON-NLS-1$
fTestSuite= (TestSuiteElement) fTestRunSession.createTestElement(fTestSuite, getNextId(), suiteName, true, 0);
+ readTime(fTestSuite, attributes);
fNotRun.push(Boolean.valueOf(attributes.getValue(IXMLTags.ATTR_INCOMPLETE)));
} else if (qName.equals(IXMLTags.NODE_PROPERTIES) || qName.equals(IXMLTags.NODE_PROPERTY)) {
@@ -112,6 +113,7 @@
fTestCase= (TestCaseElement) fTestRunSession.createTestElement(fTestSuite, getNextId(), name, false, 0);
fNotRun.push(Boolean.valueOf(attributes.getValue(IXMLTags.ATTR_INCOMPLETE)));
fTestCase.setIgnored(Boolean.valueOf(attributes.getValue(IXMLTags.ATTR_IGNORED)).booleanValue());
+ readTime(fTestCase, attributes);
} else if (qName.equals(IXMLTags.NODE_ERROR)) {
//TODO: multiple failures: https://bugs.eclipse.org/bugs/show_bug.cgi?id=125296
@@ -138,7 +140,15 @@
throw new SAXParseException("unknown node '" + qName + "'", fLocator); //$NON-NLS-1$//$NON-NLS-2$
}
}
-
+ private void readTime(TestElement testElement, Attributes attributes) {
+ String timeString= attributes.getValue(IXMLTags.ATTR_TIME);
+ if (timeString != null) {
+ try {
+ testElement.setElapsedTimeInSeconds(Double.parseDouble(timeString));
+ } catch (NumberFormatException e) {
+ }
+ }
+ }
public void characters(char[] ch, int start, int length) throws SAXException {
if (fInExpected) {
fExpectedBuffer.append(ch, start, length);
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
index 79027a6..a2906cb 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
@@ -975,4 +975,14 @@
public final ITestRunnerUI getTestRunnerUI() {
return testRunnerUI;
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.junit.model.ITestElement#getElapsedTimeInSeconds()
+ */
+ public double getElapsedTimeInSeconds() {
+ if (fTestRoot == null)
+ return Double.NaN;
+
+ return fTestRoot.getElapsedTimeInSeconds();
+ }
}
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSessionSerializer.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSessionSerializer.java
index 6904d59..921b91b 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSessionSerializer.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSessionSerializer.java
@@ -30,6 +30,8 @@
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
public class TestRunSessionSerializer implements XMLReader {
@@ -42,6 +44,8 @@
private ContentHandler fHandler;
private ErrorHandler fErrorHandler;
+ private final NumberFormat timeFormat= new DecimalFormat("0.0##"); //$NON-NLS-1$ // not localized, parseable by Double.parseDouble(..)
+
/**
* @param testRunSession the test run session to serialize
*/
@@ -72,6 +76,7 @@
addCDATA(atts, IXMLTags.ATTR_IGNORED, fTestRunSession.getIgnoredCount());
startElement(IXMLTags.NODE_TESTRUN, atts);
+
TestRoot testRoot= fTestRunSession.getTestRoot();
ITestElement[] topSuites= testRoot.getChildren();
for (int i= 0; i < topSuites.length; i++) {
@@ -99,7 +104,8 @@
AttributesImpl atts= new AttributesImpl();
addCDATA(atts, IXMLTags.ATTR_NAME, testSuiteElement.getSuiteTypeName());
-// addCDATA(atts, IXMLTags.ATTR_TIME, Integer.toString(testCaseElement.getTime()));
+ if (! Double.isNaN(testSuiteElement.getElapsedTimeInSeconds()))
+ addCDATA(atts, IXMLTags.ATTR_TIME, timeFormat.format(testSuiteElement.getElapsedTimeInSeconds()));
if (testElement.getProgressState() != ProgressState.COMPLETED || testElement.getTestResult(false) != Result.UNDEFINED)
addCDATA(atts, IXMLTags.ATTR_INCOMPLETE, Boolean.TRUE.toString());
@@ -117,10 +123,9 @@
AttributesImpl atts= new AttributesImpl();
addCDATA(atts, IXMLTags.ATTR_NAME, testCaseElement.getTestName());
- // addCDATA(atts, IXMLTags.ATTR_CLASSNAME,
- // testCaseElement.getClassName());
- // addCDATA(atts, IXMLTags.ATTR_TIME,
- // Integer.toString(testCaseElement.getTime()));
+ if (! Double.isNaN(testCaseElement.getElapsedTimeInSeconds()))
+ addCDATA(atts, IXMLTags.ATTR_TIME, timeFormat.format(testCaseElement.getElapsedTimeInSeconds()));
+
if (testElement.getProgressState() != ProgressState.COMPLETED)
addCDATA(atts, IXMLTags.ATTR_INCOMPLETE, Boolean.TRUE.toString());
if (testCaseElement.isIgnored())
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestRunnerViewPart.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestRunnerViewPart.java
index b105309..7c13fba 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestRunnerViewPart.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestRunnerViewPart.java
@@ -185,6 +185,7 @@
private ScrollLockAction fScrollLockAction;
private ToggleOrientationAction[] fToggleOrientationActions;
private ShowTestHierarchyAction fShowTestHierarchyAction;
+ private ShowTimeAction fShowTimeAction;
private ActivateOnErrorAction fActivateOnErrorAction;
private IMenuListener fViewMenuListener;
@@ -284,6 +285,8 @@
* @since 3.2
*/
static final String TAG_FAILURES_ONLY = "failuresOnly"; //$NON-NLS-1$
+
+ static final String TAG_SHOW_TIME= "time";
// orientations
static final int VIEW_ORIENTATION_VERTICAL = 0;
@@ -942,6 +945,16 @@
setShowFailuresOnly(isChecked());
}
}
+ private class ShowTimeAction extends Action {
+
+ public ShowTimeAction() {
+ super(DLTKTestingMessages.TestRunnerViewPart_show_execution_time, IAction.AS_CHECK_BOX);
+ }
+
+ public void run() {
+ setShowExecutionTime(isChecked());
+ }
+ }
private class ShowTestHierarchyAction extends Action {
@@ -1018,6 +1031,7 @@
memento.putString(TAG_FAILURES_ONLY, fFailuresOnlyFilterAction
.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
memento.putInteger(TAG_LAYOUT, fLayout);
+ memento.putString(TAG_SHOW_TIME, fShowTimeAction.isChecked() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
}
private void restoreLayoutState(IMemento memento) {
@@ -1054,7 +1068,13 @@
if (failuresOnly != null)
showFailuresOnly = failuresOnly.equals("true"); //$NON-NLS-1$
- setFilterAndLayout(showFailuresOnly, layoutValue);
+ String time= memento.getString(TAG_SHOW_TIME);
+ boolean showTime= true;
+ if (time != null)
+ showTime= time.equals("true"); //$NON-NLS-1$
+
+ setFilterAndLayout(showFailuresOnly, layoutValue);
+ setShowExecutionTime(showTime);
}
/**
@@ -1653,6 +1673,7 @@
getViewSite().getPage().addPartListener(fPartListener);
setFilterAndLayout(false, LAYOUT_HIERARCHICAL);
+ setShowExecutionTime(true);
if (fMemento != null) {
restoreLayoutState(fMemento);
}
@@ -1736,7 +1757,8 @@
new ToggleOrientationAction(VIEW_ORIENTATION_AUTOMATIC) };
fShowTestHierarchyAction = new ShowTestHierarchyAction();
-
+ fShowTimeAction= new ShowTimeAction();
+
toolBar.add(fNextAction);
toolBar.add(fPreviousAction);
toolBar.add(fFailuresOnlyFilterAction);
@@ -1748,6 +1770,7 @@
toolBar.add(fViewHistory.createHistoryDropDownAction());
viewMenu.add(fShowTestHierarchyAction);
+ viewMenu.add(fShowTimeAction);
viewMenu.add(new Separator());
MenuManager layoutSubMenu = new MenuManager(
@@ -1974,6 +1997,12 @@
void setShowFailuresOnly(boolean failuresOnly) {
setFilterAndLayout(failuresOnly, fLayout);
}
+
+ private void setShowExecutionTime(boolean showTime) {
+ fTestViewer.setShowTime(showTime);
+ fShowTimeAction.setChecked(showTime);
+
+ }
private void setLayoutMode(int mode) {
setFilterAndLayout(fFailuresOnlyFilterAction.isChecked(), mode);
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestSessionLabelProvider.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestSessionLabelProvider.java
index fa014c5..8edfc0c 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestSessionLabelProvider.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestSessionLabelProvider.java
@@ -24,18 +24,32 @@
import org.eclipse.dltk.testing.model.ITestElement;
import org.eclipse.dltk.testing.model.ITestRunSession;
import org.eclipse.dltk.testing.model.ITestSuiteElement;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StyledCellLabelProvider;
+import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Image;
+import java.text.NumberFormat;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
-public class TestSessionLabelProvider extends LabelProvider {
+public class TestSessionLabelProvider extends LabelProvider implements IStyledLabelProvider {
private final TestRunnerViewPart fTestRunnerPart;
private final int fLayoutMode;
-
+ private final NumberFormat timeFormat;
+ private boolean fShowTime;
+
public TestSessionLabelProvider(TestRunnerViewPart testRunnerPart,
int layoutMode) {
fTestRunnerPart = testRunnerPart;
fLayoutMode = layoutMode;
+ fShowTime= true;
+
+ timeFormat= NumberFormat.getNumberInstance();
+ timeFormat.setGroupingUsed(true);
+ timeFormat.setMinimumFractionDigits(3);
+ timeFormat.setMaximumFractionDigits(3);
+ timeFormat.setMinimumIntegerDigits(1);
}
private String getSimpleLabel(Object element) {
@@ -49,6 +63,51 @@
}
return element.toString();
}
+
+ private String addElapsedTime(String string, double time) {
+ if (!fShowTime || Double.isNaN(time)) {
+ return string;
+ }
+ String formattedTime= timeFormat.format(time);
+ return Messages.format(DLTKTestingMessages.TestSessionLabelProvider_testName_elapsedTimeInSeconds, new String[] { string, formattedTime});
+ }
+
+ private StyledString addElapsedTime(StyledString styledString, double time) {
+ String string= styledString.getString();
+ String decorated= addElapsedTime(string, time);
+ return StyledCellLabelProvider.styleDecoratedString(decorated, StyledString.COUNTER_STYLER, styledString);
+ }
+
+
+ public StyledString getStyledText(Object element) {
+
+ String label= getSimpleLabel(element);
+ StyledString text= new StyledString(label);
+ if ( element instanceof ITestCaseElement) {
+ text = StyledCellLabelProvider.styleDecoratedString(label, StyledString.QUALIFIER_STYLER, text);
+ }
+
+ ITestElement testElement= (ITestElement) element;
+ if (fLayoutMode == TestRunnerViewPart.LAYOUT_HIERARCHICAL
+ && element instanceof ITestElement
+ && !(element instanceof ITestCategoryElement)) {
+ final ITestElement parent = ((ITestElement) element)
+ .getParentContainer();
+ if (parent instanceof ITestRunSession
+ || parent instanceof ITestCategoryElement) {
+ final String runnerDisplayName = getTestRunnerUI()
+ .getDisplayName();
+ if (runnerDisplayName != null) {
+ String decorated = Messages
+ .format(
+ DLTKTestingMessages.TestSessionLabelProvider_testName_JUnitVersion,
+ new Object[] { label, runnerDisplayName });
+ text= StyledCellLabelProvider.styleDecoratedString(decorated, StyledString.QUALIFIER_STYLER, text);
+ }
+ }
+ }
+ return addElapsedTime(text, testElement.getElapsedTimeInSeconds());
+ }
public String getText(Object element) {
if (fLayoutMode == TestRunnerViewPart.LAYOUT_FLAT
@@ -168,5 +227,10 @@
throw new IllegalArgumentException(String.valueOf(element));
}
}
+
+ public void setShowTime(boolean showTime) {
+ fShowTime= showTime;
+ fireLabelProviderChanged(new LabelProviderChangedEvent(this));
+ }
}
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestViewer.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestViewer.java
index be35376..a95b16f 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestViewer.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/ui/TestViewer.java
@@ -39,6 +39,7 @@
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
@@ -179,7 +180,7 @@
fTreeViewer.setContentProvider(fTreeContentProvider);
fTreeLabelProvider = new TestSessionLabelProvider(fTestRunnerPart,
TestRunnerViewPart.LAYOUT_HIERARCHICAL);
- fTreeViewer.setLabelProvider(fTreeLabelProvider);
+ fTreeViewer.setLabelProvider(new DecoratingStyledCellLabelProvider(fTreeLabelProvider,null,null));
fTreeViewer.setComparator(new TestTreeComparator());
fTableViewer = new TableViewer(fViewerbook, SWT.V_SCROLL | SWT.H_SCROLL
@@ -190,7 +191,7 @@
fTableViewer.setContentProvider(fTableContentProvider);
fTableLabelProvider = new TestSessionLabelProvider(fTestRunnerPart,
TestRunnerViewPart.LAYOUT_FLAT);
- fTableViewer.setLabelProvider(fTableLabelProvider);
+ fTableViewer.setLabelProvider(new DecoratingStyledCellLabelProvider(fTableLabelProvider,null,null));
fSelectionProvider = new SelectionProviderMediator(
new StructuredViewer[] { fTreeViewer, fTableViewer },
@@ -330,6 +331,16 @@
fHierarchyIcon.dispose();
}
+ public synchronized void setShowTime(boolean showTime) {
+ try {
+ fViewerbook.setRedraw(false);
+ fTreeLabelProvider.setShowTime(showTime);
+ fTableLabelProvider.setShowTime(showTime);
+ } finally {
+ fViewerbook.setRedraw(true);
+ }
+ }
+
public synchronized void setShowFailuresOnly(boolean failuresOnly,
int layoutMode) {
/*
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/DLTKTestingMessages.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/DLTKTestingMessages.java
index e853f7c..a6beafd 100644
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/DLTKTestingMessages.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/DLTKTestingMessages.java
@@ -259,6 +259,7 @@
public static String TestRunnerViewPart_cannotrerurn_message;
public static String TestRunnerViewPart_configName;
public static String TestRunnerViewPart_error_cannotrerun;
+ public static String TestRunnerViewPart_show_execution_time;
public static String TestRunnerViewPart_ExportTestRunSessionAction_error_title;
@@ -306,7 +307,7 @@
public static String TestSearchEngine_message_searching;
public static String TestSessionLabelProvider_testName_JUnitVersion;
-
+ public static String TestSessionLabelProvider_testName_elapsedTimeInSeconds;
public static String TypeRenameParticipant_change_name;
public static String TypeRenameParticipant_name;
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/TestingMessages.properties b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/TestingMessages.properties
index 4f51926..48f6aad 100644
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/TestingMessages.properties
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/TestingMessages.properties
@@ -77,6 +77,7 @@
TestRunnerViewPart_select_test_run=&Select a test run:
TestRunnerViewPart_stopaction_tooltip=Stop Unit Test Run
TestRunnerViewPart_show_failures_only=Show Failures Only
+TestRunnerViewPart_show_execution_time=Show Execution &Time
TestRunnerViewPart_rerunaction_label=Rerun Test
TestRunnerViewPart_rerunaction_tooltip=Rerun Test
TestRunnerViewPart_hierarchical_layout=Show Tests in &Hierarchy
@@ -117,7 +118,7 @@
# The first parameter is the test name and the second is the JUnit version
TestRunnerViewPart_titleToolTip={0} - {1}
TestSessionLabelProvider_testName_JUnitVersion={0} [Runner: {1}]
-
+TestSessionLabelProvider_testName_elapsedTimeInSeconds = {0} ({1} s)
TestSessionLabelProvider_testMethodName_className={0} - {1}
JUnitLaunchConfigurationDelegate_dialog_title=Problems Launching Unit Tests
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/model/ITestElement.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/model/ITestElement.java
index 89beee4..0e887b8 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/model/ITestElement.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/testing/model/ITestElement.java
@@ -168,4 +168,18 @@
*/
public ITestRunSession getTestRunSession();
+ /**
+ * Returns the estimated total time elapsed in seconds while executing this test element.
+ * The total time for a test suite includes the time used for all tests in that suite.
+ * The total time for a test session includes the time used for all tests in that session.
+ * <p>
+ * <strong>NOTE</strong>: The elapsed time is only valid for {@link ITestElement.ProgressState#COMPLETED}
+ * test elements.
+ * </p>
+ *
+ * @return total execution time for the test element in seconds, or {@link Double#NaN}</code>
+ * if the state of the element is not {@link ITestElement.ProgressState#COMPLETED}
+ */
+ public double getElapsedTimeInSeconds();
+
}