1 package org.apache.maven.surefire.common.junit4;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.report.ReportEntry;
23 import org.apache.maven.surefire.report.RunListener;
24 import org.apache.maven.surefire.report.SimpleReportEntry;
25 import org.apache.maven.surefire.report.StackTraceWriter;
26 import org.apache.maven.surefire.testset.TestSetFailedException;
27 import org.junit.runner.Description;
28 import org.junit.runner.Result;
29 import org.junit.runner.notification.Failure;
30
31 import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.isFailureInsideJUnitItself;
32 import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.getAnnotatedIgnoreValue;
33 import static org.apache.maven.surefire.report.SimpleReportEntry.assumption;
34 import static org.apache.maven.surefire.report.SimpleReportEntry.ignored;
35 import static org.apache.maven.surefire.report.SimpleReportEntry.withException;
36 import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractClassName;
37 import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractMethodName;
38
39
40
41
42
43 public class JUnit4RunListener
44 extends org.junit.runner.notification.RunListener
45 {
46 protected final RunListener reporter;
47
48
49
50
51
52
53 private final ThreadLocal<Boolean> failureFlag = new InheritableThreadLocal<>();
54
55
56
57
58
59
60 public JUnit4RunListener( RunListener reporter )
61 {
62 this.reporter = reporter;
63 }
64
65
66
67
68
69
70
71
72 @Override
73 public void testIgnored( Description description )
74 throws Exception
75 {
76 String reason = getAnnotatedIgnoreValue( description );
77 reporter.testSkipped( ignored( getClassName( description ), description.getDisplayName(), reason ) );
78 }
79
80
81
82
83
84
85 @Override
86 public void testStarted( Description description )
87 throws Exception
88 {
89 try
90 {
91 reporter.testStarting( createReportEntry( description ) );
92 }
93 finally
94 {
95 failureFlag.remove();
96 }
97 }
98
99
100
101
102
103
104 @Override
105 @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" } )
106 public void testFailure( Failure failure )
107 throws Exception
108 {
109 try
110 {
111 String testHeader = failure.getTestHeader();
112 if ( isInsaneJunitNullString( testHeader ) )
113 {
114 testHeader = "Failure when constructing test";
115 }
116
117 String testClassName = getClassName( failure.getDescription() );
118 StackTraceWriter stackTrace = createStackTraceWriter( failure );
119
120 ReportEntry report = withException( testClassName, testHeader, stackTrace );
121
122 if ( failure.getException() instanceof AssertionError )
123 {
124 reporter.testFailed( report );
125 }
126 else
127 {
128 reporter.testError( report );
129 }
130 }
131 finally
132 {
133 failureFlag.set( true );
134 }
135 }
136
137 @SuppressWarnings( "UnusedDeclaration" )
138 public void testAssumptionFailure( Failure failure )
139 {
140 try
141 {
142 Description desc = failure.getDescription();
143 String test = getClassName( desc );
144 reporter.testAssumptionFailure( assumption( test, desc.getDisplayName(), failure.getMessage() ) );
145 }
146 finally
147 {
148 failureFlag.set( true );
149 }
150 }
151
152
153
154
155
156
157 @Override
158 public void testFinished( Description description )
159 throws Exception
160 {
161 Boolean failure = failureFlag.get();
162 if ( failure == null )
163 {
164 reporter.testSucceeded( createReportEntry( description ) );
165 }
166 }
167
168
169
170
171 public void testExecutionSkippedByUser()
172 {
173 reporter.testExecutionSkippedByUser();
174 }
175
176 private String getClassName( Description description )
177 {
178 String name = extractDescriptionClassName( description );
179 if ( name == null || isInsaneJunitNullString( name ) )
180 {
181
182 Description subDescription = description.getChildren().get( 0 );
183 if ( subDescription != null )
184 {
185 name = extractDescriptionClassName( subDescription );
186 }
187 if ( name == null )
188 {
189 name = "Test Instantiation Error";
190 }
191 }
192 return name;
193 }
194
195 protected StackTraceWriter createStackTraceWriter( Failure failure )
196 {
197 return new JUnit4StackTraceWriter( failure );
198 }
199
200 protected SimpleReportEntry createReportEntry( Description description )
201 {
202 return new SimpleReportEntry( getClassName( description ), description.getDisplayName() );
203 }
204
205 protected String extractDescriptionClassName( Description description )
206 {
207 return extractClassName( description.getDisplayName() );
208 }
209
210 protected String extractDescriptionMethodName( Description description )
211 {
212 return extractMethodName( description.getDisplayName() );
213 }
214
215 public static void rethrowAnyTestMechanismFailures( Result run )
216 throws TestSetFailedException
217 {
218 for ( Failure failure : run.getFailures() )
219 {
220 if ( isFailureInsideJUnitItself( failure.getDescription() ) )
221 {
222 throw new TestSetFailedException( failure.getTestHeader() + " :: " + failure.getMessage(),
223 failure.getException() );
224 }
225 }
226 }
227
228 private static boolean isInsaneJunitNullString( String value )
229 {
230 return "null".equals( value );
231 }
232 }