diff --git a/testng-core/src/test/java/test/hook/BaseConfigurable.java b/testng-core/src/test/java/test/hook/BaseConfigurable.java
deleted file mode 100644
index 80fcc16ea6..0000000000
--- a/testng-core/src/test/java/test/hook/BaseConfigurable.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package test.hook;
-
-import java.lang.reflect.Method;
-import org.testng.IConfigurable;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeSuite;
-import org.testng.annotations.BeforeTest;
-
-public abstract class BaseConfigurable implements IConfigurable {
- static int m_hookCount = 0;
- static boolean m_bs = false;
- static boolean m_bt = false;
- static boolean m_bm = false;
- static boolean m_bc = false;
- static String m_methodName = null;
-
- @BeforeSuite
- public void bs() {
- m_bs = true;
- }
-
- @BeforeTest
- public void bt() {
- m_bt = true;
- }
-
- @BeforeMethod
- public void bm(Method m) {
- m_bm = true;
- }
-
- @BeforeClass
- public void bc() {
- m_bc = true;
- }
-}
diff --git a/testng-core/src/test/java/test/hook/ConfigurableFailureTest.java b/testng-core/src/test/java/test/hook/ConfigurableFailureTest.java
deleted file mode 100644
index 09796e8e3f..0000000000
--- a/testng-core/src/test/java/test/hook/ConfigurableFailureTest.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package test.hook;
-
-import org.testng.Assert;
-import org.testng.IConfigureCallBack;
-import org.testng.ITestResult;
-import org.testng.annotations.Test;
-
-public class ConfigurableFailureTest extends BaseConfigurable {
-
- @Override
- public void run(IConfigureCallBack callBack, ITestResult testResult) {
- m_hookCount++;
- // Not calling the callback
- }
-
- @Test
- public void hookWasNotRun() {
- Assert.assertFalse(m_bc);
- Assert.assertFalse(m_bm);
- }
-}
diff --git a/testng-core/src/test/java/test/hook/ConfigurableListener.java b/testng-core/src/test/java/test/hook/ConfigurableListener.java
deleted file mode 100644
index c0db596b81..0000000000
--- a/testng-core/src/test/java/test/hook/ConfigurableListener.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package test.hook;
-
-import java.lang.reflect.Method;
-import org.testng.IConfigurable;
-import org.testng.IConfigureCallBack;
-import org.testng.ITestResult;
-
-public class ConfigurableListener implements IConfigurable {
- static int m_hookCount = 0;
- static String m_methodName;
-
- @Override
- public void run(IConfigureCallBack callBack, ITestResult testResult) {
- m_hookCount++;
- Object[] parameters = callBack.getParameters();
- if (parameters.length > 0) {
- m_methodName = ((Method) parameters[0]).getName();
- }
- callBack.runConfigurationMethod(testResult);
- }
-}
diff --git a/testng-core/src/test/java/test/hook/ConfigurableSuccessTest.java b/testng-core/src/test/java/test/hook/ConfigurableSuccessTest.java
deleted file mode 100644
index cea5e00d79..0000000000
--- a/testng-core/src/test/java/test/hook/ConfigurableSuccessTest.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package test.hook;
-
-import java.lang.reflect.Method;
-import org.testng.IConfigurable;
-import org.testng.IConfigureCallBack;
-import org.testng.ITestResult;
-import org.testng.annotations.Test;
-
-/** Test harness for {@link IConfigurable} */
-public class ConfigurableSuccessTest extends BaseConfigurable {
- @Override
- public void run(IConfigureCallBack callBack, ITestResult testResult) {
- m_hookCount++;
- Object[] parameters = callBack.getParameters();
- if (parameters.length > 0) {
- m_methodName = ((Method) parameters[0]).getName();
- }
- callBack.runConfigurationMethod(testResult);
- }
-
- @Test
- public void hookWasRun() {}
-}
diff --git a/testng-core/src/test/java/test/hook/ConfigurableSuccessWithListenerTest.java b/testng-core/src/test/java/test/hook/ConfigurableSuccessWithListenerTest.java
deleted file mode 100644
index f050538d1c..0000000000
--- a/testng-core/src/test/java/test/hook/ConfigurableSuccessWithListenerTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package test.hook;
-
-import java.lang.reflect.Method;
-import org.testng.Assert;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.BeforeSuite;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-@Listeners(ConfigurableListener.class)
-public class ConfigurableSuccessWithListenerTest {
- static boolean m_bm = false;
- static boolean m_bc = false;
- static boolean m_bt;
- static boolean m_bs;
-
- @BeforeSuite
- public void bs() {
- m_bs = true;
- }
-
- @BeforeMethod
- public void bt() {
- m_bt = true;
- }
-
- @BeforeMethod
- public void bm(Method m) {
- m_bm = true;
- }
-
- @BeforeClass
- public void bc() {
- m_bc = true;
- }
-
- @Test
- public void hookWasRun() {
- Assert.assertEquals(ConfigurableListener.m_hookCount, 2);
- Assert.assertTrue(m_bc);
- Assert.assertTrue(m_bm);
- }
-}
diff --git a/testng-core/src/test/java/test/hook/HookFailureTest.java b/testng-core/src/test/java/test/hook/HookFailureTest.java
deleted file mode 100644
index 46d6c9f168..0000000000
--- a/testng-core/src/test/java/test/hook/HookFailureTest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package test.hook;
-
-import org.testng.IHookCallBack;
-import org.testng.IHookable;
-import org.testng.ITestResult;
-import org.testng.annotations.Test;
-
-public class HookFailureTest implements IHookable {
- static boolean m_hook = false;
- static boolean m_testWasRun = false;
-
- @Override
- public void run(IHookCallBack callBack, ITestResult testResult) {
- m_hook = true;
- // Not invoking the callback: the method should not be run
- }
-
- @Test
- public void verify() {
- m_testWasRun = true;
- }
-}
diff --git a/testng-core/src/test/java/test/hook/HookListener.java b/testng-core/src/test/java/test/hook/HookListener.java
deleted file mode 100644
index 3cdfd27efe..0000000000
--- a/testng-core/src/test/java/test/hook/HookListener.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package test.hook;
-
-import org.testng.IHookCallBack;
-import org.testng.IHookable;
-import org.testng.ITestResult;
-
-public class HookListener implements IHookable {
- public static boolean m_hook = false;
-
- @Override
- public void run(IHookCallBack callBack, ITestResult testResult) {
- m_hook = true;
- callBack.runTestMethod(testResult);
- }
-}
diff --git a/testng-core/src/test/java/test/hook/HookSuccess599Test.java b/testng-core/src/test/java/test/hook/HookSuccess599Test.java
deleted file mode 100644
index 59808dda0f..0000000000
--- a/testng-core/src/test/java/test/hook/HookSuccess599Test.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package test.hook;
-
-import org.testng.IHookCallBack;
-import org.testng.IHookable;
-import org.testng.ITestResult;
-import org.testng.Reporter;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * Test harness for {@link IHookable}
- *
- * @author Cedric Beust
- * @since Aug 01, 2006
- */
-public class HookSuccess599Test implements IHookable {
- static boolean m_hook = false;
- static boolean m_testWasRun = false;
- static String m_parameter = null;
-
- @Override
- public void run(IHookCallBack callBack, ITestResult testResult) {
- m_hook = true;
- Object[] parameters = callBack.getParameters();
- if (parameters.length > 0) {
- m_parameter = parameters[0].toString();
- }
- callBack.runTestMethod(testResult);
- }
-
- @DataProvider
- public Object[][] dp() {
- return new Object[][] {new Object[] {"foo"}};
- }
-
- @Test(dataProvider = "dp", timeOut = 100)
- public void verify(String name) {
- m_testWasRun = true;
- Reporter.log("output from hook test.verify");
- }
-}
diff --git a/testng-core/src/test/java/test/hook/HookSuccessTest.java b/testng-core/src/test/java/test/hook/HookSuccessTest.java
deleted file mode 100644
index 0a7e538cb9..0000000000
--- a/testng-core/src/test/java/test/hook/HookSuccessTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package test.hook;
-
-import org.testng.IHookCallBack;
-import org.testng.IHookable;
-import org.testng.ITestResult;
-import org.testng.Reporter;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-public class HookSuccessTest implements IHookable {
- static boolean m_hook = false;
- static boolean m_testWasRun = false;
- static String m_parameter = null;
-
- @Override
- public void run(IHookCallBack callBack, ITestResult testResult) {
- m_hook = true;
- Object[] parameters = callBack.getParameters();
- if (parameters.length > 0) {
- m_parameter = parameters[0].toString();
- }
- callBack.runTestMethod(testResult);
- }
-
- @DataProvider
- public Object[][] dp() {
- return new Object[][] {new Object[] {"foo"}};
- }
-
- @Test(dataProvider = "dp")
- public void verify(String name) {
- m_testWasRun = true;
- Reporter.log("output from hook test.verify");
- }
-}
diff --git a/testng-core/src/test/java/test/hook/HookSuccessWithListenerTest.java b/testng-core/src/test/java/test/hook/HookSuccessWithListenerTest.java
deleted file mode 100644
index 9d6fb0f7a0..0000000000
--- a/testng-core/src/test/java/test/hook/HookSuccessWithListenerTest.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package test.hook;
-
-import org.testng.Assert;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-@Listeners(HookListener.class)
-public class HookSuccessWithListenerTest {
-
- @Test
- public void verify() {
- Assert.assertTrue(HookListener.m_hook);
- }
-}
diff --git a/testng-core/src/test/java/test/hook/HookableTest.java b/testng-core/src/test/java/test/hook/HookableTest.java
index 9da353685f..df7a7008a1 100644
--- a/testng-core/src/test/java/test/hook/HookableTest.java
+++ b/testng-core/src/test/java/test/hook/HookableTest.java
@@ -1,127 +1,193 @@
package test.hook;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import org.assertj.core.api.SoftAssertions;
+import org.testng.IInvokedMethod;
+import org.testng.IInvokedMethodListener;
+import org.testng.ITestResult;
+import org.testng.Reporter;
+import org.testng.TestNG;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import test.BaseTest;
-
-/**
- * Because IHookable and IConfigurable are global, it's safer to run them in a sub-TestNG object,
- * otherwise they will be run for your entire test suite...
- *
- * @author cbeust
- */
-public class HookableTest extends BaseTest {
-
- @BeforeMethod
- public void bm() {
- HookSuccessTest.m_hook = false;
- HookSuccessTest.m_testWasRun = false;
- HookSuccessTest.m_parameter = null;
- HookSuccess599Test.m_hook = false;
- HookSuccess599Test.m_testWasRun = false;
- HookSuccess599Test.m_parameter = null;
- HookFailureTest.m_hook = false;
- HookFailureTest.m_testWasRun = false;
- HookListener.m_hook = false;
- BaseConfigurable.m_hookCount = 0;
- BaseConfigurable.m_bc = false;
- BaseConfigurable.m_bm = false;
- BaseConfigurable.m_bs = false;
- BaseConfigurable.m_bt = false;
- BaseConfigurable.m_methodName = null;
- ConfigurableListener.m_hookCount = 0;
- ConfigurableListener.m_methodName = null;
- ConfigurableSuccessWithListenerTest.m_bc = false;
- ConfigurableSuccessWithListenerTest.m_bm = false;
+import test.SimpleBaseTest;
+import test.hook.samples.ConfigurableFailureSample;
+import test.hook.samples.ConfigurableSuccessSample;
+import test.hook.samples.ConfigurableSuccessWithListenerSample;
+import test.hook.samples.HookFailureSample;
+import test.hook.samples.HookSuccessDynamicParametersSample;
+import test.hook.samples.HookSuccessSample;
+import test.hook.samples.HookSuccessTimeoutSample;
+import test.hook.samples.HookSuccessWithListenerSample;
+
+public class HookableTest extends SimpleBaseTest {
+
+ public static final String HOOK_INVOKED_ATTRIBUTE = "hook";
+ public static final String HOOK_METHOD_INVOKED_ATTRIBUTE = "hookMethod";
+ public static final String HOOK_METHOD_PARAMS_ATTRIBUTE = "hookParamAttribute";
+
+ @Test(dataProvider = "getTestClasses")
+ public void hookSuccess(Class> clazz, String flow, boolean assertAttributes) {
+ Reporter.log("Running scenario " + flow, true);
+ TestNG tng = create(clazz);
+ TestResultsCollector listener = new TestResultsCollector();
+ tng.addListener(listener);
+ tng.run();
+ assertThat(listener.getPassedMethodNames()).contains("verify");
+ if (!assertAttributes) {
+ return;
+ }
+ SoftAssertions assertions = new SoftAssertions();
+ listener
+ .getPassed()
+ .forEach(
+ each -> {
+ assertions.assertThat(each.getAttribute(HOOK_INVOKED_ATTRIBUTE)).isNotNull();
+ assertions.assertThat(each.getAttribute(HOOK_METHOD_INVOKED_ATTRIBUTE)).isNotNull();
+ Object[] parameters = (Object[]) each.getAttribute(HOOK_METHOD_PARAMS_ATTRIBUTE);
+ assertions.assertThat(parameters).hasSize(1);
+ assertions.assertThat(parameters[0]).isInstanceOf(UUID.class);
+ });
+ assertions.assertAll();
}
- @Test
- public void hookSuccess() {
- addClass(HookSuccessTest.class);
- run();
-
- verifyTests("Passed", new String[] {"verify"}, getPassedTests());
- Assert.assertTrue(HookSuccessTest.m_hook);
- Assert.assertTrue(HookSuccessTest.m_testWasRun);
- Assert.assertEquals(HookSuccessTest.m_parameter, "foo");
- }
-
- @Test(description = "https://github.com/cbeust/testng/issues/599")
- public void issue599() {
- addClass(HookSuccess599Test.class);
- run();
-
- verifyTests("Passed", new String[] {"verify"}, getPassedTests());
- Assert.assertTrue(HookSuccess599Test.m_hook);
- Assert.assertTrue(HookSuccess599Test.m_testWasRun);
- Assert.assertEquals(HookSuccess599Test.m_parameter, "foo");
- }
-
- @Test(description = "https://github.com/cbeust/testng/pull/862")
- public void issue862() {
- addClass(HookSuccess862Test.class);
- run();
-
- verifyTests("Passed", new String[] {"verify"}, getPassedTests());
+ @DataProvider(name = "getTestClasses")
+ public Object[][] getTestClasses() {
+ return new Object[][] {
+ {HookSuccessSample.class, "Happy Flow", true},
+ {HookSuccessTimeoutSample.class, "With Timeouts (GITHUB-599)", true},
+ {HookSuccessDynamicParametersSample.class, "With Dynamic Parameters (GITHUB-862)", false}
+ };
}
@Test
public void hookSuccessWithListener() {
- addClass(HookSuccessWithListenerTest.class);
- run();
-
- verifyTests("Passed", new String[] {"verify"}, getPassedTests());
- Assert.assertTrue(HookListener.m_hook);
+ TestNG tng = create(HookSuccessWithListenerSample.class);
+ TestResultsCollector listener = new TestResultsCollector();
+ tng.addListener(listener);
+ tng.run();
+ assertThat(listener.getPassedMethodNames()).contains("verify");
+ assertThat(listener.getPassed().get(0).getAttribute(HOOK_INVOKED_ATTRIBUTE)).isNotNull();
}
@Test
public void hookFailure() {
- addClass(HookFailureTest.class);
- run();
-
- // To investigate: TestNG still thinks the test passed since it can't know whether
- // the hook ended up invoking the test or not.
- // verifyTests("Passed", new String[] { }, getPassedTests());
- Assert.assertTrue(HookFailureTest.m_hook);
- Assert.assertFalse(HookFailureTest.m_testWasRun);
+ TestNG tng = create(HookFailureSample.class);
+ TestResultsCollector listener = new TestResultsCollector();
+ tng.addListener(listener);
+ tng.run();
+ assertThat(listener.getPassedMethodNames()).isNotNull();
+ SoftAssertions assertions = new SoftAssertions();
+ listener
+ .getInvoked()
+ .forEach(
+ each -> {
+ assertions.assertThat(each.getAttribute(HOOK_INVOKED_ATTRIBUTE)).isNotNull();
+ assertions.assertThat(each.getAttribute(HOOK_METHOD_INVOKED_ATTRIBUTE)).isNull();
+ });
+ assertions.assertAll();
}
- @Test
- public void configurableSuccess() {
- addClass(ConfigurableSuccessTest.class);
- run();
-
- Assert.assertEquals(BaseConfigurable.m_hookCount, 4);
- Assert.assertTrue(BaseConfigurable.m_bc);
- Assert.assertTrue(BaseConfigurable.m_bm);
- Assert.assertTrue(BaseConfigurable.m_bs);
- Assert.assertTrue(BaseConfigurable.m_bt);
- Assert.assertEquals(BaseConfigurable.m_methodName, "hookWasRun");
+ @Test(dataProvider = "getConfigClasses")
+ public void configurableSuccess(Class> clazz, String flow) {
+ Reporter.log("Running scenario " + flow, true);
+ TestNG tng = create(clazz);
+ TestResultsCollector listener = new TestResultsCollector();
+ tng.addListener(listener);
+ tng.run();
+ assertThat(listener.getPassedConfigs()).hasSize(4);
+ assertThat(listener.getPassedConfigNames()).contains("bs", "bt", "bc", "bm");
+ SoftAssertions assertions = new SoftAssertions();
+ listener
+ .getPassedConfigs()
+ .forEach(
+ each -> {
+ assertions.assertThat(each.getAttribute(HOOK_INVOKED_ATTRIBUTE)).isNotNull();
+ Object[] parameters = (Object[]) each.getAttribute(HOOK_METHOD_PARAMS_ATTRIBUTE);
+ if (parameters != null && parameters.length != 0) {
+ assertions.assertThat(parameters).hasSize(1);
+ assertions.assertThat(parameters[0]).isInstanceOf(Method.class);
+ String methodName = ((Method) parameters[0]).getName();
+ assertions.assertThat(methodName).isEqualTo("hookWasRun");
+ }
+ });
+ assertions.assertAll();
}
- @Test
- public void configurableSuccessWithListener() {
- addClass(ConfigurableSuccessWithListenerTest.class);
- run();
-
- Assert.assertEquals(ConfigurableListener.m_hookCount, 4);
- Assert.assertTrue(ConfigurableSuccessWithListenerTest.m_bs);
- Assert.assertTrue(ConfigurableSuccessWithListenerTest.m_bt);
- Assert.assertTrue(ConfigurableSuccessWithListenerTest.m_bc);
- Assert.assertTrue(ConfigurableSuccessWithListenerTest.m_bm);
- Assert.assertEquals(ConfigurableListener.m_methodName, "hookWasRun");
+ @DataProvider(name = "getConfigClasses")
+ public Object[][] getConfigClasses() {
+ return new Object[][] {
+ {ConfigurableSuccessSample.class, "IConfigurable as test class"},
+ {ConfigurableSuccessWithListenerSample.class, "IConfigurable as listener"},
+ };
}
@Test
public void configurableFailure() {
- addClass(ConfigurableFailureTest.class);
- run();
-
- Assert.assertEquals(BaseConfigurable.m_hookCount, 4);
- Assert.assertFalse(BaseConfigurable.m_bc);
- Assert.assertFalse(BaseConfigurable.m_bm);
- Assert.assertFalse(BaseConfigurable.m_bs);
- Assert.assertFalse(BaseConfigurable.m_bt);
+ TestNG tng = create(ConfigurableFailureSample.class);
+ TestResultsCollector listener = new TestResultsCollector();
+ tng.addListener(listener);
+ tng.run();
+ assertThat(listener.getPassedConfigNames()).containsExactly("bs", "bt", "bc", "bm");
+ assertThat(listener.getPassedConfigs()).hasSize(4);
+ SoftAssertions assertions = new SoftAssertions();
+ listener
+ .getPassedConfigs()
+ .forEach(
+ each -> {
+ assertions.assertThat(each.getAttribute(HOOK_INVOKED_ATTRIBUTE)).isNotNull();
+ assertions.assertThat(each.getAttribute(HOOK_METHOD_INVOKED_ATTRIBUTE)).isNull();
+ });
+ assertions.assertAll();
+ }
+
+ public static class TestResultsCollector implements IInvokedMethodListener {
+ private final List passed = new ArrayList<>();
+ private final List invoked = new ArrayList<>();
+ private final List passedConfigs = new ArrayList<>();
+
+ @Override
+ public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
+ invoked.add(testResult);
+ if (testResult.isSuccess()) {
+ if (method.isTestMethod()) {
+ passed.add(testResult);
+ }
+ if (method.isConfigurationMethod()) {
+ passedConfigs.add(testResult);
+ }
+ }
+ }
+
+ public List getPassedConfigs() {
+ return passedConfigs;
+ }
+
+ public List getPassed() {
+ return passed;
+ }
+
+ public List getInvoked() {
+ return invoked;
+ }
+
+ public List getPassedMethodNames() {
+ return asString(passed);
+ }
+
+ public List getPassedConfigNames() {
+ return asString(passedConfigs);
+ }
+
+ private static List asString(List list) {
+ return list.stream()
+ .map(each -> each.getMethod().getMethodName())
+ .collect(Collectors.toList());
+ }
}
}
diff --git a/testng-core/src/test/java/test/hook/samples/BaseConfigurableSample.java b/testng-core/src/test/java/test/hook/samples/BaseConfigurableSample.java
new file mode 100644
index 0000000000..b4435855dc
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/BaseConfigurableSample.java
@@ -0,0 +1,23 @@
+package test.hook.samples;
+
+import java.lang.reflect.Method;
+import org.testng.IConfigurable;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.BeforeTest;
+
+public abstract class BaseConfigurableSample implements IConfigurable {
+
+ @BeforeSuite
+ public void bs() {}
+
+ @BeforeTest
+ public void bt() {}
+
+ @BeforeMethod
+ public void bm(Method m) {}
+
+ @BeforeClass
+ public void bc() {}
+}
diff --git a/testng-core/src/test/java/test/hook/samples/ConfigurableFailureSample.java b/testng-core/src/test/java/test/hook/samples/ConfigurableFailureSample.java
new file mode 100644
index 0000000000..ee81366b3b
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/ConfigurableFailureSample.java
@@ -0,0 +1,19 @@
+package test.hook.samples;
+
+import static test.hook.HookableTest.HOOK_INVOKED_ATTRIBUTE;
+
+import org.testng.IConfigureCallBack;
+import org.testng.ITestResult;
+import org.testng.annotations.Test;
+
+public class ConfigurableFailureSample extends BaseConfigurableSample {
+
+ @Override
+ public void run(IConfigureCallBack callBack, ITestResult testResult) {
+ testResult.setAttribute(HOOK_INVOKED_ATTRIBUTE, "true");
+ // Not calling the callback
+ }
+
+ @Test
+ public void hookWasNotRun() {}
+}
diff --git a/testng-core/src/test/java/test/hook/samples/ConfigurableSuccessSample.java b/testng-core/src/test/java/test/hook/samples/ConfigurableSuccessSample.java
new file mode 100644
index 0000000000..2aa61d0988
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/ConfigurableSuccessSample.java
@@ -0,0 +1,20 @@
+package test.hook.samples;
+
+import static test.hook.HookableTest.HOOK_INVOKED_ATTRIBUTE;
+import static test.hook.HookableTest.HOOK_METHOD_PARAMS_ATTRIBUTE;
+
+import org.testng.IConfigureCallBack;
+import org.testng.ITestResult;
+import org.testng.annotations.Test;
+
+public class ConfigurableSuccessSample extends BaseConfigurableSample {
+ @Override
+ public void run(IConfigureCallBack callBack, ITestResult testResult) {
+ testResult.setAttribute(HOOK_INVOKED_ATTRIBUTE, "true");
+ testResult.setAttribute(HOOK_METHOD_PARAMS_ATTRIBUTE, callBack.getParameters());
+ callBack.runConfigurationMethod(testResult);
+ }
+
+ @Test
+ public void hookWasRun() {}
+}
diff --git a/testng-core/src/test/java/test/hook/samples/ConfigurableSuccessWithListenerSample.java b/testng-core/src/test/java/test/hook/samples/ConfigurableSuccessWithListenerSample.java
new file mode 100644
index 0000000000..dd4c6957f9
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/ConfigurableSuccessWithListenerSample.java
@@ -0,0 +1,39 @@
+package test.hook.samples;
+
+import static test.hook.HookableTest.HOOK_INVOKED_ATTRIBUTE;
+import static test.hook.HookableTest.HOOK_METHOD_PARAMS_ATTRIBUTE;
+
+import java.lang.reflect.Method;
+import org.testng.IConfigurable;
+import org.testng.IConfigureCallBack;
+import org.testng.ITestResult;
+import org.testng.annotations.*;
+
+@Listeners(ConfigurableSuccessWithListenerSample.ConfigurableListener.class)
+public class ConfigurableSuccessWithListenerSample {
+
+ @BeforeSuite
+ public void bs() {}
+
+ @BeforeMethod
+ public void bt() {}
+
+ @BeforeMethod
+ public void bm(Method m) {}
+
+ @BeforeClass
+ public void bc() {}
+
+ @Test
+ public void hookWasRun() {}
+
+ public static class ConfigurableListener implements IConfigurable {
+
+ @Override
+ public void run(IConfigureCallBack callBack, ITestResult testResult) {
+ testResult.setAttribute(HOOK_INVOKED_ATTRIBUTE, "true");
+ testResult.setAttribute(HOOK_METHOD_PARAMS_ATTRIBUTE, callBack.getParameters());
+ callBack.runConfigurationMethod(testResult);
+ }
+ }
+}
diff --git a/testng-core/src/test/java/test/hook/samples/HookFailureSample.java b/testng-core/src/test/java/test/hook/samples/HookFailureSample.java
new file mode 100644
index 0000000000..4f659ecb9b
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/HookFailureSample.java
@@ -0,0 +1,24 @@
+package test.hook.samples;
+
+import static test.hook.HookableTest.HOOK_INVOKED_ATTRIBUTE;
+import static test.hook.HookableTest.HOOK_METHOD_INVOKED_ATTRIBUTE;
+
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITestResult;
+import org.testng.Reporter;
+import org.testng.annotations.Test;
+
+public class HookFailureSample implements IHookable {
+
+ @Override
+ public void run(IHookCallBack callBack, ITestResult testResult) {
+ testResult.setAttribute(HOOK_INVOKED_ATTRIBUTE, "true");
+ // Not invoking the callback: the method should not be run
+ }
+
+ @Test
+ public void verify() {
+ Reporter.getCurrentTestResult().setAttribute(HOOK_METHOD_INVOKED_ATTRIBUTE, "true");
+ }
+}
diff --git a/testng-core/src/test/java/test/hook/HookSuccess862Test.java b/testng-core/src/test/java/test/hook/samples/HookSuccessDynamicParametersSample.java
similarity index 82%
rename from testng-core/src/test/java/test/hook/HookSuccess862Test.java
rename to testng-core/src/test/java/test/hook/samples/HookSuccessDynamicParametersSample.java
index 7a8a09a7a0..74499a694a 100644
--- a/testng-core/src/test/java/test/hook/HookSuccess862Test.java
+++ b/testng-core/src/test/java/test/hook/samples/HookSuccessDynamicParametersSample.java
@@ -1,13 +1,16 @@
-package test.hook;
+package test.hook.samples;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import javax.inject.Named;
-import org.testng.*;
+import org.testng.Assert;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITestResult;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-public class HookSuccess862Test implements IHookable {
+public class HookSuccessDynamicParametersSample implements IHookable {
@Override
public void run(IHookCallBack callBack, ITestResult testResult) {
diff --git a/testng-core/src/test/java/test/hook/samples/HookSuccessSample.java b/testng-core/src/test/java/test/hook/samples/HookSuccessSample.java
new file mode 100644
index 0000000000..776c2d7c08
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/HookSuccessSample.java
@@ -0,0 +1,31 @@
+package test.hook.samples;
+
+import static test.hook.HookableTest.*;
+
+import java.util.UUID;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITestResult;
+import org.testng.Reporter;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class HookSuccessSample implements IHookable {
+
+ @Override
+ public void run(IHookCallBack callBack, ITestResult testResult) {
+ testResult.setAttribute(HOOK_INVOKED_ATTRIBUTE, "true");
+ testResult.setAttribute(HOOK_METHOD_PARAMS_ATTRIBUTE, callBack.getParameters());
+ callBack.runTestMethod(testResult);
+ }
+
+ @DataProvider
+ public Object[][] dp() {
+ return new Object[][] {new Object[] {UUID.randomUUID()}};
+ }
+
+ @Test(dataProvider = "dp")
+ public void verify(UUID uuid) {
+ Reporter.getCurrentTestResult().setAttribute(HOOK_METHOD_INVOKED_ATTRIBUTE, uuid);
+ }
+}
diff --git a/testng-core/src/test/java/test/hook/samples/HookSuccessTimeoutSample.java b/testng-core/src/test/java/test/hook/samples/HookSuccessTimeoutSample.java
new file mode 100644
index 0000000000..e53706e3eb
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/HookSuccessTimeoutSample.java
@@ -0,0 +1,31 @@
+package test.hook.samples;
+
+import static test.hook.HookableTest.*;
+
+import java.util.UUID;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITestResult;
+import org.testng.Reporter;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class HookSuccessTimeoutSample implements IHookable {
+
+ @Override
+ public void run(IHookCallBack callBack, ITestResult testResult) {
+ testResult.setAttribute(HOOK_INVOKED_ATTRIBUTE, "true");
+ testResult.setAttribute(HOOK_METHOD_PARAMS_ATTRIBUTE, callBack.getParameters());
+ callBack.runTestMethod(testResult);
+ }
+
+ @DataProvider
+ public Object[][] dp() {
+ return new Object[][] {new Object[] {UUID.randomUUID()}};
+ }
+
+ @Test(dataProvider = "dp", timeOut = 100)
+ public void verify(UUID uuid) {
+ Reporter.getCurrentTestResult().setAttribute(HOOK_METHOD_INVOKED_ATTRIBUTE, uuid);
+ }
+}
diff --git a/testng-core/src/test/java/test/hook/samples/HookSuccessWithListenerSample.java b/testng-core/src/test/java/test/hook/samples/HookSuccessWithListenerSample.java
new file mode 100644
index 0000000000..168ead15e4
--- /dev/null
+++ b/testng-core/src/test/java/test/hook/samples/HookSuccessWithListenerSample.java
@@ -0,0 +1,31 @@
+package test.hook.samples;
+
+import static test.hook.HookableTest.*;
+
+import org.testng.Assert;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITestResult;
+import org.testng.Reporter;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+
+@Listeners(HookSuccessWithListenerSample.HookListener.class)
+public class HookSuccessWithListenerSample {
+
+ @Test
+ public void verify() {
+ ITestResult itr = Reporter.getCurrentTestResult();
+ boolean attribute = Boolean.parseBoolean(itr.getAttribute(HOOK_INVOKED_ATTRIBUTE).toString());
+ Assert.assertTrue(attribute);
+ }
+
+ public static class HookListener implements IHookable {
+
+ @Override
+ public void run(IHookCallBack callBack, ITestResult testResult) {
+ testResult.setAttribute(HOOK_INVOKED_ATTRIBUTE, "true");
+ callBack.runTestMethod(testResult);
+ }
+ }
+}