Made invoked listeners a list instead of a single.
Updated the doc.
diff --git a/CHANGES.txt b/CHANGES.txt
index e041dc7..18feaec 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -7,7 +7,8 @@
Fixed: TESTNG-231: NullPointerException thrown converting a suite to XML (Mark)
Doc:
-Added -testjar
+Added: 5.20: Invoked method listener
+Added: -testjar
===========================================================================
5.8
diff --git a/doc/documentation-main.html b/doc/documentation-main.html
index ce1712b..def7cc8 100644
--- a/doc/documentation-main.html
+++ b/doc/documentation-main.html
@@ -108,6 +108,8 @@
<a class="summary" href="#dependency-injection">5.19 - Dependency injection</a></br>
+ <a class="summary" href="#invokedmethodlistener">5.20 - Invoked method listeners</a></br>
+
<a class="summary" href="#test-results">6 - Test results</a>
<br>
@@ -1799,13 +1801,14 @@
<a name="testng-listeners">5.18 - TestNG Listeners</a>
</h4>
-There are several interfaces that allow you to modify TestNG's behavior. These interfaces are broadly called "TestNG Listeners", and as of the current version, they are:
+There are several interfaces that allow you to modify TestNG's behavior. These interfaces are broadly called "TestNG Listeners". Here is a list of the supported listeners:
<ul>
<li><tt>IAnnotationTransformer</tt> (<a href="#annotationtransformers">doc</a>, <a href="../javadocs/org/testng/IAnnotationTransformer.html">javadoc</a>)
<li><tt>IReporter</tt> (<a href="#logging-reporters">doc</a>, <a href="../javadocs/org/testng/IReporter.html">javadoc</a>)
<li><tt>ITestListener</tt> (<a href="#logging-listeners">doc</a>, <a href="../javadocs/org/testng/ITestListener.html">javadoc</a>)
<li><tt>IMethodInterceptor</tt> (<a href="#methodinterceptors">doc</a>, <a href="../javadocs/org/testng/IMethodInterceptor.html">javadoc</a>)
+ <li><tt>IInvokedMethodListener</tt> (<a href="#invokedmethodlistener">doc</a>, <a href="../javadocs/org/testng/IInvokedMethodListener.html">javadoc</a>)
</ul>
When you implement one of these interfaces, you can let TestNG know about it with either of the following ways:
@@ -1816,7 +1819,7 @@
<li>Using <listeners> in your <tt>testng.xml</tt> file.
</ul>
-Here is how you can define listenersin your <tt>testng.xml</tt> file:
+Here is how you can define listeners in your <tt>testng.xml</tt> file:
<pre class="prettyprint">
<suite>
@@ -1852,6 +1855,29 @@
</ul>
+<!-------------------------------------
+ INVOKED METHOD LISTENERS
+ ------------------------------------>
+
+<h4>
+<a name="invokedmethodlistener">5.20 - Listening to method invocations</a>
+</h4>
+
+The listener <tt><a href="../javadocs/org/testng/IInvokedMethodListener.html">IInvokedMethodListener</a></tt> allows you to be notified whenever TestNG is about to invoke a test (annotated with <tt>@Test</tt>) or configuration (annotated with any of the <tt>@Before</tt> or <tt>@After</tt> annotation) method. You need to implement the following interface:
+
+<pre class="prettyprint">
+public interface IInvokedMethodListener extends ITestNGListener {
+ void beforeInvocation(IInvokedMethod method, ITestResult testResult);
+ void afterInvocation(IInvokedMethod method, ITestResult testResult);
+}
+</pre>
+
+and declare it as a listener, as explained in <a href="#testng-listeners">the section about TestNG listeners</a>.
+
+<p>
+
+
+
<!------------------------------------
diff --git a/src/main/org/testng/IInvokedMethodListener.java b/src/main/org/testng/IInvokedMethodListener.java
index 2ab3a1c..c042228 100644
--- a/src/main/org/testng/IInvokedMethodListener.java
+++ b/src/main/org/testng/IInvokedMethodListener.java
@@ -2,7 +2,7 @@
/**
* A listener that gets invoked before and after a method is invoked by TestNG.
- * This listener will only be invoked for configuration or test methods.
+ * This listener will only be invoked for configuration and test methods.
*/
public interface IInvokedMethodListener extends ITestNGListener {
diff --git a/src/main/org/testng/SuiteRunner.java b/src/main/org/testng/SuiteRunner.java
index f8e816b..f3cd046 100644
--- a/src/main/org/testng/SuiteRunner.java
+++ b/src/main/org/testng/SuiteRunner.java
@@ -62,7 +62,7 @@
transient private Boolean m_skipFailedInvocationCounts = Boolean.FALSE;
private IMethodInterceptor m_methodInterceptor;
- private IInvokedMethodListener m_invokedMethodListener;
+ private List<IInvokedMethodListener> m_invokedMethodListener;
// transient private IAnnotationTransformer m_annotationTransformer = null;
@@ -94,7 +94,7 @@
IAnnotationFinder[] finders,
IObjectFactory factory,
IMethodInterceptor methodInterceptor,
- IInvokedMethodListener invokedMethodListener)
+ List<IInvokedMethodListener> invokedMethodListener)
{
init(suite, outputDir, runnerFactory, useDefaultListeners, finders, factory,
methodInterceptor, invokedMethodListener);
@@ -107,7 +107,7 @@
IAnnotationFinder[] finders,
IObjectFactory factory,
IMethodInterceptor methodInterceptor,
- IInvokedMethodListener invokedMethodListener)
+ List<IInvokedMethodListener> invokedMethodListener)
{
m_suite = suite;
m_useDefaultListeners = useDefaultListeners;
@@ -462,12 +462,12 @@
private ITestListener[] m_failureGenerators;
private boolean m_useDefaultListeners;
private boolean m_skipFailedInvocationCounts;
- private IInvokedMethodListener m_invokedMethodListener;
+ private List<IInvokedMethodListener> m_invokedMethodListener;
public DefaultTestRunnerFactory(ITestListener[] failureListeners,
boolean useDefaultListeners,
boolean skipFailedInvocationCounts,
- IInvokedMethodListener invokedMethodListener)
+ List<IInvokedMethodListener> invokedMethodListener)
{
m_failureGenerators = failureListeners;
m_useDefaultListeners = useDefaultListeners;
diff --git a/src/main/org/testng/TestNG.java b/src/main/org/testng/TestNG.java
index 3b1d127..517c201 100644
--- a/src/main/org/testng/TestNG.java
+++ b/src/main/org/testng/TestNG.java
@@ -158,7 +158,8 @@
private IObjectFactory m_objectFactory;
- private IInvokedMethodListener m_invokedMethodListener;
+ private List<IInvokedMethodListener> m_invokedMethodListeners
+ = new ArrayList<IInvokedMethodListener>();
/**
* Default constructor. Setting also usage of default listeners/reporters.
@@ -601,12 +602,13 @@
if (listener instanceof IMethodInterceptor) {
m_methodInterceptor = (IMethodInterceptor) listener;
}
- if (listener instanceof IInvokedMethodListener) {
- m_invokedMethodListener = (IInvokedMethodListener) listener;
- }
}
}
+ public void addListener(IInvokedMethodListener listener) {
+ m_invokedMethodListeners.add((IInvokedMethodListener) listener);
+ }
+
public void addListener(ISuiteListener listener) {
if (null != listener) {
m_suiteListeners.add(listener);
@@ -625,8 +627,8 @@
}
}
- public void setInvokedMethodListener(IInvokedMethodListener listener) {
- m_invokedMethodListener = listener;
+ public void addInvokedMethodListener(IInvokedMethodListener listener) {
+ m_invokedMethodListeners.add(listener);
}
public List<IReporter> getReporters() {
@@ -851,7 +853,7 @@
},
m_objectFactory,
m_methodInterceptor,
- m_invokedMethodListener);
+ m_invokedMethodListeners);
result.setSkipFailedInvocationCounts(m_skipFailedInvocationCounts);
for (ISuiteListener isl : m_suiteListeners) {
diff --git a/src/main/org/testng/TestRunner.java b/src/main/org/testng/TestRunner.java
index ca804bd..53e97b1 100644
--- a/src/main/org/testng/TestRunner.java
+++ b/src/main/org/testng/TestRunner.java
@@ -128,17 +128,17 @@
}
};
- private IInvokedMethodListener m_invokedMethodListener;
+ private List<IInvokedMethodListener> m_invokedMethodListeners;
public TestRunner(ISuite suite,
XmlTest test,
String outputDirectory,
IAnnotationFinder finder,
boolean skipFailedInvocationCounts,
- IInvokedMethodListener invokedMethodListener)
+ List<IInvokedMethodListener> invokedMethodListeners)
{
init(suite, test, outputDirectory, finder, skipFailedInvocationCounts,
- invokedMethodListener);
+ invokedMethodListeners);
}
public TestRunner(ISuite suite, XmlTest test,
@@ -161,7 +161,7 @@
String outputDirectory,
IAnnotationFinder annotationFinder,
boolean skipFailedInvocationCounts,
- IInvokedMethodListener invokedMethodListener)
+ List<IInvokedMethodListener> invokedMethodListeners)
{
m_xmlTest= test;
m_suite = suite;
@@ -169,7 +169,7 @@
m_host = suite.getHost();
m_testClassesFromXml= test.getXmlClasses();
m_skipFailedInvocationCounts = skipFailedInvocationCounts;
- m_invokedMethodListener = invokedMethodListener;
+ m_invokedMethodListeners = invokedMethodListeners;
m_packageNamesFromXml= test.getXmlPackages();
if(null != m_packageNamesFromXml) {
@@ -182,7 +182,7 @@
m_invoker =
new Invoker(this, this, m_suite.getSuiteState(),
m_annotationFinder, m_skipFailedInvocationCounts,
- invokedMethodListener);
+ invokedMethodListeners);
setVerbose(test.getVerbose());
diff --git a/src/main/org/testng/internal/Invoker.java b/src/main/org/testng/internal/Invoker.java
index c6e9b2e..6d0a34f 100644
--- a/src/main/org/testng/internal/Invoker.java
+++ b/src/main/org/testng/internal/Invoker.java
@@ -1,18 +1,9 @@
package org.testng.internal;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import org.testng.IClass;
import org.testng.IHookable;
+import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.IRetryAnalyzer;
import org.testng.ITestClass;
@@ -35,6 +26,16 @@
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
/**
* This class is responsible for invoking methods:
* - test methods
@@ -51,20 +52,20 @@
private IAnnotationFinder m_annotationFinder;
private SuiteRunState m_suiteState;
private boolean m_skipFailedInvocationCounts;
- private IInvokedMethodListener m_invokedMethodListener;
+ private List<IInvokedMethodListener> m_invokedMethodListeners;
public Invoker(ITestContext testContext,
ITestResultNotifier notifier,
SuiteRunState state,
IAnnotationFinder annotationFinder,
boolean skipFailedInvocationCounts,
- IInvokedMethodListener invokedMethodListener) {
+ List<IInvokedMethodListener> invokedMethodListeners) {
m_testContext= testContext;
m_suiteState= state;
m_notifier= notifier;
m_annotationFinder= annotationFinder;
m_skipFailedInvocationCounts = skipFailedInvocationCounts;
- m_invokedMethodListener = invokedMethodListener;
+ m_invokedMethodListeners = invokedMethodListeners;
}
/**
@@ -395,9 +396,7 @@
isClass, /* ??? */
System.currentTimeMillis());
- if (m_invokedMethodListener != null) {
- m_invokedMethodListener.beforeInvocation(im, testResult);
- }
+ runInvokedMethodListeners(true /* before */, im, testResult);
m_notifier.addInvokedMethod(im);
try {
@@ -406,13 +405,28 @@
}
finally {
Reporter.setCurrentTestResult(testResult);
- if (m_invokedMethodListener != null) {
- m_invokedMethodListener.afterInvocation(im, testResult);
- }
+ runInvokedMethodListeners(false /* after */, im, testResult);
}
}
}
+ private void runInvokedMethodListeners(boolean before, IInvokedMethod method,
+ ITestResult testResult)
+ {
+ if (m_invokedMethodListeners != null) {
+ if (before) {
+ for (IInvokedMethodListener l : m_invokedMethodListeners) {
+ l.beforeInvocation(method, testResult);
+ }
+ }
+ else {
+ for (IInvokedMethodListener l : m_invokedMethodListeners) {
+ l.afterInvocation(method, testResult);
+ }
+ }
+ }
+ }
+
private ITestResult invokeMethod(Object[] instances,
int instanceIndex,
final ITestNGMethod tm,
@@ -462,9 +476,7 @@
false,
System.currentTimeMillis());
- if (m_invokedMethodListener != null) {
- m_invokedMethodListener.beforeInvocation(invokedMethod, testResult);
- }
+ runInvokedMethodListeners(true, invokedMethod, testResult);
m_notifier.addInvokedMethod(invokedMethod);
@@ -531,9 +543,7 @@
}
finally {
- if (m_invokedMethodListener != null) {
- m_invokedMethodListener.afterInvocation(invokedMethod, testResult);
- }
+ runInvokedMethodListeners(false, invokedMethod, testResult);
//
// Increment the invocation count for this method
diff --git a/test/src/test/invokedmethodlistener/InvokedMethodListenerTest.java b/test/src/test/invokedmethodlistener/InvokedMethodListenerTest.java
index 0b9d43d..d5a6865 100644
--- a/test/src/test/invokedmethodlistener/InvokedMethodListenerTest.java
+++ b/test/src/test/invokedmethodlistener/InvokedMethodListenerTest.java
@@ -12,7 +12,7 @@
TestNG tng = create();
tng.setTestClasses(classes);
MyListener l = new MyListener();
- tng.setInvokedMethodListener(l);
+ tng.addInvokedMethodListener(l);
tng.run();
Assert.assertEquals(l.getBeforeCount(), 9);