3333import eu .tsystems .mms .tic .testframework .events .MethodEndEvent ;
3434import eu .tsystems .mms .tic .testframework .events .MethodStartEvent ;
3535import eu .tsystems .mms .tic .testframework .exceptions .SystemException ;
36- import eu .tsystems .mms .tic .testframework .execution .testng .ListenerUtils ;
3736import eu .tsystems .mms .tic .testframework .execution .testng .worker .finish .MethodContextUpdateWorker ;
3837import eu .tsystems .mms .tic .testframework .execution .testng .worker .finish .MethodEndWorker ;
3938import eu .tsystems .mms .tic .testframework .execution .testng .worker .start .MethodParametersWorker ;
5049import eu .tsystems .mms .tic .testframework .report .model .steps .TestStep ;
5150import eu .tsystems .mms .tic .testframework .report .utils .DefaultTestNGContextGenerator ;
5251import eu .tsystems .mms .tic .testframework .report .utils .ExecutionContextController ;
52+ import java .util .Date ;
53+ import java .util .Locale ;
54+ import java .util .concurrent .ConcurrentHashMap ;
5355import org .apache .logging .log4j .Level ;
5456import org .apache .logging .log4j .core .LoggerContext ;
5557import org .apache .logging .log4j .core .config .Configurator ;
5658import org .apache .logging .log4j .core .config .DefaultConfiguration ;
5759import org .testng .IConfigurable ;
5860import org .testng .IConfigureCallBack ;
61+ import org .testng .IDataProviderListener ;
5962import org .testng .IHookCallBack ;
6063import org .testng .IHookable ;
6164import org .testng .IInvokedMethod ;
7073import org .testng .ITestNGMethod ;
7174import org .testng .ITestResult ;
7275import org .testng .annotations .Test ;
76+ import org .testng .internal .InvokedMethod ;
77+ import org .testng .internal .TestResult ;
7378import org .testng .xml .XmlSuite ;
74-
7579import java .util .List ;
76- import java .util .Locale ;
7780
7881/**
7982 * Listener for JUnit and TestNg, collects test informations for testreport.
@@ -88,7 +91,9 @@ public class TesterraListener implements
8891 IMethodInterceptor ,
8992 ITestListener ,
9093 ISuiteListener ,
91- Loggable {
94+ Loggable ,
95+ IDataProviderListener
96+ {
9297 /**
9398 * Default package namespace for project tests
9499 */
@@ -111,6 +116,7 @@ public class TesterraListener implements
111116 private static final Report report ;
112117 private static DefaultTestNGContextGenerator contextGenerator ;
113118 private static final TestStatusController testStatusController = new TestStatusController ();
119+ private static final ConcurrentHashMap <ITestNGMethod , Boolean > dataProviderSemaphore = new ConcurrentHashMap <>();
114120
115121 static {
116122 String logLevel = PropertyManager .getProperty ("log4j.level" );
@@ -276,30 +282,28 @@ public void beforeInvocation(
276282 * @param testResult result of invoked method.
277283 * @param testContext
278284 */
279- private void pBeforeInvocation (
285+ private MethodContext pBeforeInvocation (
280286 IInvokedMethod invokedMethod ,
281287 ITestResult testResult ,
282288 ITestContext testContext
283289 ) {
284290 final String methodName = getMethodName (testResult );
285291
286- if (ListenerUtils .wasMethodInvokedBefore ("beforeInvocationFor" + methodName , invokedMethod , testResult )) {
287- return ;
288- }
292+ // if (ListenerUtils.wasMethodInvokedBefore("beforeInvocationFor" + methodName, invokedMethod, testResult)) {
293+ // return null ;
294+ // }
289295
290296 /*
291297 * store testresult, create method context
292298 */
293299 MethodContext methodContext = ExecutionContextController .setCurrentTestResult (testResult ); // stores the actual testresult, auto-creates the method context
294- ExecutionContextController .setCurrentMethodContext (methodContext );
295-
296300 methodContext .getTestStep (TestStep .SETUP );
297301
298- final String infoText = "beforeInvocation: " + invokedMethod .getTestMethod ().getTestClass ().getName () + "." +
299- methodName +
300- " - " + Thread .currentThread ().getName ();
301-
302- log ().trace (infoText );
302+ // final String infoText = "beforeInvocation: " + invokedMethod.getTestMethod().getTestClass().getName() + "." +
303+ // methodName +
304+ // " - " + Thread.currentThread().getName();
305+ //
306+ // log().trace(infoText);
303307
304308 AbstractMethodEvent event = new MethodStartEvent ()
305309 .setTestResult (testResult )
@@ -312,6 +316,7 @@ private void pBeforeInvocation(
312316
313317 // We don't close teardown steps, because we want to collect further actions there
314318 //step.close();
319+ return methodContext ;
315320 }
316321
317322 /**
@@ -361,38 +366,30 @@ private void pAfterInvocation(
361366 ITestContext testContext
362367 ) {
363368
364- final String methodName ;
365- final String testClassName ;
366- if (invokedMethod != null ) {
367- methodName = invokedMethod .getTestMethod ().getMethodName ();
368- testClassName = invokedMethod .getTestMethod ().getTestClass ().getName ();
369- } else {
370- methodName = testResult .getMethod ().getConstructorOrMethod ().getName ();
371- testClassName = testResult .getTestClass ().getName ();
372- }
369+ // final String methodName;
370+ // final String testClassName;
371+ // if (invokedMethod != null) {
372+ // methodName = invokedMethod.getTestMethod().getMethodName();
373+ // testClassName = invokedMethod.getTestMethod().getTestClass().getName();
374+ // } else {
375+ // methodName = testResult.getMethod().getConstructorOrMethod().getName();
376+ // testClassName = testResult.getTestClass().getName();
377+ // }
373378
374379 // CHECKSTYLE:ON
375- if (ListenerUtils .wasMethodInvokedBefore ("afterInvocation" , testClassName , methodName , testResult , testContext )) {
376- return ;
377- }
378-
379- /*
380- Log
381- */
382- final String infoText = "afterInvocation: " + testClassName + "." + methodName + " - " + Thread .currentThread ().getName ();
380+ // if (ListenerUtils.wasMethodInvokedBefore("afterInvocation", testClassName, methodName, testResult, testContext)) {
381+ // return;
382+ // }
383383
384- log (). trace ( infoText );
384+ final String methodName = getMethodName ( testResult );
385385
386386 /*
387387 * Get test method container
388388 */
389389 MethodContext methodContext = ExecutionContextController .getCurrentMethodContext ();
390390 if (methodContext == null ) {
391391
392- if (
393- testResult .getStatus () == ITestResult .CREATED
394- || testResult .getStatus () == ITestResult .SKIP
395- ) {
392+ if (testResult .getStatus () == ITestResult .CREATED || testResult .getStatus () == ITestResult .SKIP ) {
396393 /*
397394 * TestNG bug or whatever ?!?!
398395 */
@@ -524,4 +521,25 @@ public void onFinish(ISuite iSuite) {
524521 public static boolean isActive () {
525522 return instances > 0 ;
526523 }
524+
525+ @ Override
526+ public void onDataProviderFailure (ITestNGMethod testNGMethod , ITestContext testContext , RuntimeException exception ) {
527+ /**
528+ * TestNG calls the data provider initialization for every thread.
529+ * Added a semaphore to prevent adding multiple method contexts.
530+ */
531+ if (!dataProviderSemaphore .containsKey (testNGMethod )) {
532+ TestResult testResult = TestResult .newContextAwareTestResult (testNGMethod , testContext );
533+ InvokedMethod invokedMethod = new InvokedMethod (new Date ().getTime (), testResult );
534+ MethodContext methodContext = pBeforeInvocation (invokedMethod , testResult , testContext );
535+ if (exception .getCause () != null ) {
536+ methodContext .addError (exception .getCause ());
537+ } else {
538+ methodContext .addError (exception );
539+ }
540+ pAfterInvocation (invokedMethod , testResult , testContext );
541+
542+ dataProviderSemaphore .put (testNGMethod , true );
543+ }
544+ }
527545}
0 commit comments