Merge branch 'master' of git://github.com/cbeust/testng
diff --git a/CHANGES.txt b/CHANGES.txt
index a8b0f1d..7630064 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -18,6 +18,11 @@
Fixed: Invoke IInvokedMethodListener.afterInvocation after fixing results for tests expecting exceptions (Nalin Makar)
Eclipse:
+Added: Excluded methods are now listed in the Summary tab
+Added: Double clicking on an excluded method in the Summary tab will take you to its definition
+Added: If you select a package before invoking the "New TestNG class" wizard, the source and package text boxes will be auto-filled
+Added: When an item is selected in a tab, the same item will be selected when switching tabs
+Added: A new "Summary" tab that allows the user to see a summary of the tests, sort them by time, name, etc...
Added: It's now possible "Run/Debug As" with a right click from pretty much any element that makes sense in the tree.
Added: The conversion of a JUnit test to TestNG now replaces @Test(timeout) with @Test(timeOut) (5.14.2.4)
Added: The conversion of a JUnit test to TestNG now replaces @Test(expected) with @Test(expectedExceptions) (5.14.2.4)
@@ -26,6 +31,8 @@
Added: The progress bar is now orange if the suite contained skipped tests and no failures
Added: Skipped test and suite icons are now orange (previously: blue)
Added: New method shortcuts: "Alt+Shift+X N", "Alt+Shift+D N" (Sven Johansson)
+Fixed: NPE when you select a passed test and click on the Compare Result icon (Mohamed Mansour)
+Fixed: When the run is over, the plug-in will no longer force the focus back to the Console view
Fixed: The counter in the progress bar sometimes went over the total number of test methods (5.14.2.9)
Fixed: org.eclipse.ui.internal.ErrorViewPart cannot be cast to org.testng.eclipse.ui.TestRunnerViewPart (5.14.2.9)
Fixed: Workspace preferences now offer the "XML template" option as well as the project specific preferences (Asiel Brumfield)
diff --git a/src/main/java/org/testng/TestNG.java b/src/main/java/org/testng/TestNG.java
index cd88b2d..56bc4a2 100644
--- a/src/main/java/org/testng/TestNG.java
+++ b/src/main/java/org/testng/TestNG.java
@@ -689,8 +689,8 @@
return m_suiteListeners;
}
- /** The verbosity level. TODO why not a simple int? */
- private int m_verbose = 1;
+ /** If m_verbose gets set, it will override the verbose setting in testng.xml */
+ private Integer m_verbose = null;
private IAnnotationTransformer m_annotationTransformer = new DefaultAnnotationTransformer();
@@ -869,31 +869,25 @@
public List<ISuite> runSuitesLocally() {
Map<XmlSuite, ISuite> suiteRunnerMap = Maps.newHashMap();
if (m_suites.size() > 0) {
- /*
- * first initialize the suite runners to ensure there are no configuration issues.
- * Create a map with XmlSuite as key and corresponding SuiteRunner as value
- */
+ // First initialize the suite runners to ensure there are no configuration issues.
+ // Create a map with XmlSuite as key and corresponding SuiteRunner as value
for (XmlSuite xmlSuite : m_suites) {
createSuiteRunners(suiteRunnerMap, xmlSuite);
}
- /*
- * Run suites
- */
+ //
+ // Run suites
+ //
if (m_suiteThreadPoolSize == 1 && !m_randomizeSuites) {
- /*
- * Only of we want suites to run in order specified in XML and the suite thread pool
- * size is 1, we run this block
- */
+ // Single threaded and not randomized: run the suites in order
for (XmlSuite xmlSuite : m_suites) {
- runSuitesSequentially(xmlSuite, suiteRunnerMap, m_verbose, getDefaultSuiteName());
+ runSuitesSequentially(xmlSuite, suiteRunnerMap, xmlSuite.getVerbose(),
+ getDefaultSuiteName());
}
} else {
- /*
- * Generate a dynamic graph that stores the suite hierarchy. This is then
- * used to run related suites in specific order. Parent suites are run only
- * once all the child suites have completed execution
- */
+ // Multithreaded: generate a dynamic graph that stores the suite hierarchy. This is then
+ // used to run related suites in specific order. Parent suites are run only
+ // once all the child suites have completed execution
DynamicGraph<ISuite> suiteGraph = new DynamicGraph<ISuite>();
for (XmlSuite xmlSuite : m_suites) {
populateSuiteGraph(suiteGraph, suiteRunnerMap, xmlSuite);
@@ -907,10 +901,9 @@
new LinkedBlockingQueue<Runnable>());
Utils.log("TestNG", 2, "Starting executor for all suites");
- //run all suites in parallel
+ // Run all suites in parallel
pooledExecutor.run();
try {
- //TODO: Setting timeout to Long.MAX_VALUE. Is it correct/ok?
pooledExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
pooledExecutor.shutdownNow();
}
@@ -1011,7 +1004,8 @@
xmlSuite.setSkipFailedInvocationCounts(m_skipFailedInvocationCounts);
}
- if (xmlSuite.getVerbose() == null) {
+ // Override the XmlSuite verbose value with the one from TestNG
+ if (m_verbose != null) {
xmlSuite.setVerbose(m_verbose);
}
diff --git a/src/main/java/org/testng/internal/Utils.java b/src/main/java/org/testng/internal/Utils.java
index 786cfd6..f4a71c1 100644
--- a/src/main/java/org/testng/internal/Utils.java
+++ b/src/main/java/org/testng/internal/Utils.java
@@ -14,9 +14,12 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
@@ -713,4 +716,31 @@
return sb.toString();
}
+
+ public static void copyFile(File from, File to) {
+ try{
+ InputStream in = new FileInputStream(from);
+
+ //For Append the file.
+// OutputStream out = new FileOutputStream(f2,true);
+
+ //For Overwrite the file.
+ to.getParentFile().mkdirs();
+ OutputStream out = new FileOutputStream(to);
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0){
+ out.write(buf, 0, len);
+ }
+ in.close();
+ out.close();
+ }
+ catch(FileNotFoundException ex){
+ ex.printStackTrace();
+ }
+ catch(IOException e){
+ e.printStackTrace();
+ }
+ }
}
diff --git a/src/main/java/org/testng/remote/RemoteTestNG.java b/src/main/java/org/testng/remote/RemoteTestNG.java
index 9c98203..a97c68f 100644
--- a/src/main/java/org/testng/remote/RemoteTestNG.java
+++ b/src/main/java/org/testng/remote/RemoteTestNG.java
@@ -27,11 +27,8 @@
/**
* Extension of TestNG registering a remote TestListener.
- * <p>
- * <i>Developer note</i>: be aware that a copy of this source is distributed along with the
- * Eclipse plugin to assure backward compatibility.
- * </p>
- * @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a>
+ *
+ * @author Cedric Beust <cedric@beust.com>
*/
public class RemoteTestNG extends TestNG {
private static final String LOCALHOST = "127.0.0.1";
@@ -166,6 +163,9 @@
sb.append(s).append(" ");
}
p(sb.toString());
+ testNG.setVerbose(2);
+ } else {
+ testNG.setVerbose(0);
}
validateCommandLineParameters(cla);
if (m_debug) {
@@ -173,6 +173,7 @@
// without having to relauch RemoteTestNG.
while(true) {
testNG.run();
+ testNG.configure(cla);
}
} else {
testNG.run();
diff --git a/src/main/java/org/testng/remote/strprotocol/MessageHelper.java b/src/main/java/org/testng/remote/strprotocol/MessageHelper.java
index 18a9eb0..4fb871a 100755
--- a/src/main/java/org/testng/remote/strprotocol/MessageHelper.java
+++ b/src/main/java/org/testng/remote/strprotocol/MessageHelper.java
@@ -67,9 +67,23 @@
int type = getMessageType(message);
String[] messageParts = parseMessage(message);
- return new SuiteMessage(messageParts[1],
+ SuiteMessage result = new SuiteMessage(messageParts[1],
MessageHelper.SUITE_START == type,
Integer.parseInt(messageParts[2]));
+ // Any excluded methods?
+ if (messageParts.length > 3) {
+ int count = Integer.parseInt(messageParts[3]);
+ if (count > 0) {
+ List<String> methods = Lists.newArrayList();
+ int i = 4;
+ while (count-- > 0) {
+ methods.add(messageParts[i++]);
+ }
+ result.setExcludedMethods(methods);
+ }
+ }
+
+ return result;
}
public static TestMessage createTestMessage(final String message) {
diff --git a/src/main/java/org/testng/remote/strprotocol/SuiteMessage.java b/src/main/java/org/testng/remote/strprotocol/SuiteMessage.java
index 034a038..9383222 100755
--- a/src/main/java/org/testng/remote/strprotocol/SuiteMessage.java
+++ b/src/main/java/org/testng/remote/strprotocol/SuiteMessage.java
@@ -1,6 +1,11 @@
package org.testng.remote.strprotocol;
import org.testng.ISuite;
+import org.testng.ITestNGMethod;
+import org.testng.collections.Lists;
+
+import java.util.Collection;
+import java.util.List;
/**
@@ -12,6 +17,7 @@
protected final String m_suiteName;
protected final int m_testMethodCount;
protected final boolean m_startSuite;
+ private List<String> m_excludedMethods = null;
SuiteMessage(final String suiteName, final boolean startSuiteRun, final int methodCount) {
m_suiteName = suiteName;
@@ -23,6 +29,22 @@
m_suiteName = suite.getName();
m_testMethodCount =suite.getInvokedMethods().size();
m_startSuite = startSuiteRun;
+ Collection<ITestNGMethod> excludedMethods = suite.getExcludedMethods();
+ if (excludedMethods != null && excludedMethods.size() > 0) {
+ m_excludedMethods = Lists.newArrayList();
+ for (ITestNGMethod m : excludedMethods) {
+ m_excludedMethods.add(m.getTestClass().getName() + "." + m.getMethodName());
+ }
+ }
+ }
+
+ public void setExcludedMethods(List<String> methods) {
+ m_excludedMethods = Lists.newArrayList();
+ m_excludedMethods.addAll(methods);
+ }
+
+ public List<String> getExcludedMethods() {
+ return m_excludedMethods;
}
public boolean isMessageOnStart() {
@@ -51,6 +73,14 @@
.append(m_testMethodCount)
;
+ if (m_excludedMethods != null && m_excludedMethods.size() > 0) {
+ buf.append(MessageHelper.DELIMITER);
+ buf.append(m_excludedMethods.size());
+ for (String method : m_excludedMethods) {
+ buf.append(MessageHelper.DELIMITER);
+ buf.append(method);
+ }
+ }
return buf.toString();
}
}
diff --git a/src/main/java/org/testng/reporters/TextReporter.java b/src/main/java/org/testng/reporters/TextReporter.java
index 6fe77af..805cc7f 100644
--- a/src/main/java/org/testng/reporters/TextReporter.java
+++ b/src/main/java/org/testng/reporters/TextReporter.java
@@ -9,7 +9,7 @@
import java.util.List;
/**
- * A simple reporter that collects the results and does nothing else.
+ * A simple reporter that collects the results and prints them on standard out.
*
* @author <a href="mailto:cedric@beust.com">Cedric Beust</a>
* @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a>
@@ -31,7 +31,6 @@
}
}
-
private ITestNGMethod[] resultsToMethods(List<ITestResult> results) {
ITestNGMethod[] result = new ITestNGMethod[results.size()];
int i = 0;
@@ -42,7 +41,6 @@
return result;
}
-
private void logResults() {
//
// Log Text
diff --git a/src/main/java/org/testng/xml/LaunchSuite.java b/src/main/java/org/testng/xml/LaunchSuite.java
index b684762..19c2795 100755
--- a/src/main/java/org/testng/xml/LaunchSuite.java
+++ b/src/main/java/org/testng/xml/LaunchSuite.java
@@ -3,7 +3,9 @@
import org.testng.collections.Lists;
import org.testng.internal.AnnotationTypeEnum;
+import org.testng.internal.Utils;
import org.testng.log4testng.Logger;
+import org.testng.remote.RemoteTestNG;
import org.testng.reporters.XMLStringBuffer;
import java.io.File;
@@ -75,12 +77,14 @@
}
/**
- * {@inheritDoc} This implementation saves nothing because the suite file already
- * exists.
+ * Trying to run an existing XML file: copy its content to where the plug-in
+ * expects it.
*/
@Override
public File save(File directory) {
- return m_suitePath;
+ File result = new File(directory, RemoteTestNG.DEBUG_SUITE_FILE);
+ Utils.copyFile(m_suitePath, result);
+ return result;
}
}