From de83c87fbdcc6b460f3dfe5b190da89e7de00bf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4fer?= Date: Sun, 30 Aug 2015 14:56:54 +0200 Subject: [PATCH] use one report model per class when using TestNG (fixes #115) --- .../report/impl/CommonReportHelper.java | 1 - .../jgiven/report/model/ReportModel.java | 5 ++- jgiven-testng/build.gradle | 3 ++ .../jgiven/testng/ScenarioTestListener.java | 32 +++++++++++++++---- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/impl/CommonReportHelper.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/impl/CommonReportHelper.java index b3d07e844e..0b313b1ba2 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/impl/CommonReportHelper.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/impl/CommonReportHelper.java @@ -28,7 +28,6 @@ public void finishReport( ReportModel model ) { if( Config.config().textReport() ) { new PlainTextReporter().write( model ).flush(); - ; } Optional optionalReportDir = Config.config().getReportDir(); diff --git a/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModel.java b/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModel.java index a73bbc1dec..23d422ea86 100644 --- a/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModel.java +++ b/jgiven-core/src/main/java/com/tngtech/jgiven/report/model/ReportModel.java @@ -163,7 +163,10 @@ public synchronized void addScenarioModelOrMergeWithExistingOne( ScenarioModel s } } - public void setTestClass( Class testClass ) { + public synchronized void setTestClass( Class testClass ) { + AssertionUtil.assertTrue( className == null || testClass.getName().equals( className ), + "Test class of the same report model was set to different values. 1st value: " + className + + ", 2nd value: " + testClass.getName() ); setClassName( testClass.getName() ); if( testClass.isAnnotationPresent( Description.class ) ) { setDescription( testClass.getAnnotation( Description.class ).value() ); diff --git a/jgiven-testng/build.gradle b/jgiven-testng/build.gradle index 9a83f09a10..1a9129f118 100644 --- a/jgiven-testng/build.gradle +++ b/jgiven-testng/build.gradle @@ -2,6 +2,7 @@ description = "Module to write JGiven tests with TestNG" dependencies { compile project(':jgiven-core') + compile project(':jgiven-html5-report') compile(group: 'org.testng', name: 'testng', version:'6.8.7') { /* This dependency was originally in the Maven provided scope, but the project was not of type war. This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency. @@ -10,3 +11,5 @@ dependencies { } test.useTestNG() +test.finalizedBy(jgivenHtml5Report) + diff --git a/jgiven-testng/src/main/java/com/tngtech/jgiven/testng/ScenarioTestListener.java b/jgiven-testng/src/main/java/com/tngtech/jgiven/testng/ScenarioTestListener.java index b0b3a122be..ed1cc19a47 100644 --- a/jgiven-testng/src/main/java/com/tngtech/jgiven/testng/ScenarioTestListener.java +++ b/jgiven-testng/src/main/java/com/tngtech/jgiven/testng/ScenarioTestListener.java @@ -7,6 +7,8 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import org.testng.ITestContext; import org.testng.ITestListener; @@ -15,6 +17,7 @@ import com.google.common.base.Throwables; import com.tngtech.jgiven.base.ScenarioTestBase; import com.tngtech.jgiven.impl.ScenarioBase; +import com.tngtech.jgiven.impl.util.AssertionUtil; import com.tngtech.jgiven.impl.util.ParameterNameUtil; import com.tngtech.jgiven.report.impl.CommonReportHelper; import com.tngtech.jgiven.report.model.NamedArgument; @@ -24,15 +27,14 @@ * TestNG Test listener to enable JGiven for a test class */ public class ScenarioTestListener implements ITestListener { - private volatile ReportModel reportModel; - private final Map scenarioMap = Collections.synchronizedMap( - new IdentityHashMap() ); + private volatile ConcurrentMap reportModels; + + private volatile Map scenarioMap; @Override public void onTestStart( ITestResult paramITestResult ) { Object instance = paramITestResult.getInstance(); - reportModel.setTestClass( instance.getClass() ); ScenarioBase scenario; @@ -45,6 +47,7 @@ public void onTestStart( ITestResult paramITestResult ) { scenarioMap.put( paramITestResult, scenario ); + ReportModel reportModel = getReportModel( instance.getClass() ); scenario.setModel( reportModel ); scenario.getExecutor().injectSteps( instance ); @@ -55,6 +58,20 @@ public void onTestStart( ITestResult paramITestResult ) { scenario.getExecutor().readScenarioState( instance ); } + private ReportModel getReportModel( Class clazz ) { + ReportModel model = reportModels.get( clazz.getName() ); + if( model == null ) { + model = new ReportModel(); + model.setClassName( clazz.getName() ); + ReportModel previousModel = reportModels.putIfAbsent( clazz.getName(), model ); + if( previousModel != null ) { + model = previousModel; + } + } + AssertionUtil.assertNotNull( model, "Report model is null" ); + return model; + } + @Override public void onTestSuccess( ITestResult paramITestResult ) { testFinished( paramITestResult ); @@ -86,12 +103,15 @@ public void onTestFailedButWithinSuccessPercentage( ITestResult paramITestResult @Override public void onStart( ITestContext paramITestContext ) { - reportModel = new ReportModel(); + reportModels = new ConcurrentHashMap(); + scenarioMap = Collections.synchronizedMap( new IdentityHashMap() ); } @Override public void onFinish( ITestContext paramITestContext ) { - new CommonReportHelper().finishReport( reportModel ); + for( ReportModel reportModel : reportModels.values() ) { + new CommonReportHelper().finishReport( reportModel ); + } } private List getArgumentsFrom( Method method, ITestResult paramITestResult ) {