View Javadoc
1   package org.apache.maven.surefire.junitcore;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
23  import org.apache.maven.surefire.common.junit4.JUnit4StackTraceWriter;
24  import org.apache.maven.surefire.api.report.RunListener;
25  import org.apache.maven.surefire.api.report.StackTraceWriter;
26  import org.junit.runner.Description;
27  import org.junit.runner.Result;
28  import org.junit.runner.notification.Failure;
29  
30  import java.util.Map;
31  
32  import static org.apache.maven.surefire.api.util.internal.TestClassMethodNameUtils.extractClassName;
33  
34  /**
35   * Noteworthy things about JUnit4 listening:
36   * <br>
37   * A class that is annotated with @Ignore will have one invocation of "testSkipped" with source==name
38   * A method that is annotated with @Ignore will have a invocation of testSkipped with source and name distinct
39   * Methods annotated with @Ignore trigger no further events.
40   *
41   * @see org.apache.maven.surefire.junitcore.ConcurrentRunListener for details about parallel running
42   */
43  public class JUnitCoreRunListener
44      extends JUnit4RunListener
45  {
46      private final Map<String, TestSet> classMethodCounts;
47  
48      /**
49       * @param reporter          the report manager to log testing events to
50       * @param classMethodCounts A map of methods
51       */
52      public JUnitCoreRunListener( RunListener reporter, Map<String, TestSet> classMethodCounts )
53      {
54          super( reporter );
55          this.classMethodCounts = classMethodCounts;
56      }
57  
58      /**
59       * Called right before any tests from a specific class are run.
60       *
61       * @see org.junit.runner.notification.RunListener#testRunStarted(org.junit.runner.Description)
62       */
63      @Override
64      public void testRunStarted( Description description )
65          throws Exception
66      {
67          fillTestCountMap( description );
68          reporter.testSetStarting( null ); // Not entirely meaningful as we can see
69      }
70  
71      @Override
72      public void testRunFinished( Result result )
73          throws Exception
74      {
75          try
76          {
77              reporter.testSetCompleted( null );
78          }
79          finally
80          {
81              classMethodCounts.clear();
82          }
83      }
84  
85      private void fillTestCountMap( Description testDesc )
86      {
87          for ( Description child : testDesc.getChildren() )
88          {
89              if ( !asTestLeaf( child ) )
90              {
91                  fillTestCountMap( child );
92              }
93          }
94      }
95  
96      private boolean asTestLeaf( Description description )
97      {
98          if ( description.isTest() )
99          {
100             final String testClassName = extractClassName( description.getDisplayName() );
101             if ( testClassName != null )
102             {
103                 final TestSet testSet;
104                 if ( classMethodCounts.containsKey( testClassName ) )
105                 {
106                     testSet = classMethodCounts.get( testClassName );
107                 }
108                 else
109                 {
110                     testSet = new TestSet( testClassName );
111                     classMethodCounts.put( testClassName, testSet );
112                 }
113                 testSet.incrementTestMethodCount();
114             }
115             return true;
116         }
117         else
118         {
119             return false;
120         }
121     }
122 
123     @Override
124     protected StackTraceWriter createStackTraceWriter( Failure failure )
125     {
126         return new JUnit4StackTraceWriter( failure );
127     }
128 }