You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2020/04/18 21:18:40 UTC

[maven-surefire] branch SUREFIRE-1695 created (now e5d6e58)

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a change to branch SUREFIRE-1695
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git.


      at e5d6e58  [SUREFIRE-1695] Support multiple inheritance of @Categories

This branch includes the following new commits:

     new e5d6e58  [SUREFIRE-1695] Support multiple inheritance of @Categories

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[maven-surefire] 01/01: [SUREFIRE-1695] Support multiple inheritance of @Categories

Posted by ti...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch SUREFIRE-1695
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit e5d6e583ecdec87c29a65feac8f56d55553f5c0a
Author: Ioannis Dermitzakis <io...@gebit.de>
AuthorDate: Thu Aug 29 09:48:43 2019 +0200

    [SUREFIRE-1695] Support multiple inheritance of @Categories
---
 .../jiras/Surefire995CategoryInheritanceIT.java    | 122 +++++++++---
 .../surefire-995-categoryInheritance/pom.xml       |   7 +-
 .../test/java/jiras/surefire955/group/ABCTest.java |  36 ++++
 .../test/java/jiras/surefire955/group/ATest.java   |  36 ++++
 .../jiras/surefire955/group/AbstractBCTest.java    |  37 ++++
 .../jiras/surefire955/group/AbstractCTest.java     |  37 ++++
 .../test/java/jiras/surefire955/group/BBCTest.java |  36 ++++
 .../test/java/jiras/surefire955/group/BCTest.java  |  33 ++++
 .../test/java/jiras/surefire955/group/BTest.java   |  37 ++++
 .../jiras/surefire955/group/UncategorizedTest.java |  33 ++++
 .../jiras/surefire955/group/marker/CategoryA.java  |  24 +++
 .../jiras/surefire955/group/marker/CategoryB.java  |  24 +++
 .../jiras/surefire955/group/marker/CategoryC.java  |  24 +++
 surefire-providers/common-junit48/pom.xml          | 220 ++++++++++++++-------
 .../common/junit48/GroupMatcherCategoryFilter.java |  49 ++++-
 .../GroupMatcherCategoryFilterPreJUnit412Test.java | 100 ++++++++++
 .../junit48/GroupMatcherCategoryFilterTest.java    | 138 +++++++++++++
 .../junit48/tests/group/ABCParameterizedTest.java  |  63 ++++++
 .../common/junit48/tests/group/ABCTest.java        |  40 ++++
 .../common/junit48/tests/group/ABMethodTest.java   |  47 +++++
 .../surefire/common/junit48/tests/group/ATest.java |  39 ++++
 .../common/junit48/tests/group/AbstractBCTest.java |  40 ++++
 .../common/junit48/tests/group/AbstractCTest.java  |  39 ++++
 .../common/junit48/tests/group/BBCTest.java        |  40 ++++
 .../common/junit48/tests/group/BCTest.java         |  37 ++++
 .../surefire/common/junit48/tests/group/BTest.java |  39 ++++
 .../junit48/tests/group/UncategorizedTest.java     |  36 ++++
 .../junit48/tests/group/marker/CategoryA.java      |  27 +++
 .../junit48/tests/group/marker/CategoryB.java      |  27 +++
 .../junit48/tests/group/marker/CategoryC.java      |  27 +++
 30 files changed, 1389 insertions(+), 105 deletions(-)

diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire995CategoryInheritanceIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire995CategoryInheritanceIT.java
index d776724..c571556 100644
--- a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire995CategoryInheritanceIT.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire995CategoryInheritanceIT.java
@@ -19,68 +19,140 @@ package org.apache.maven.surefire.its.jiras;
  * under the License.
  */
 
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.surefire.its.fixture.OutputValidator;
 import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
 import org.apache.maven.surefire.its.fixture.SurefireLauncher;
 import org.junit.Test;
 
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+
 /**
  * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
  * @see <a href="https://issues.apache.org/jira/browse/SUREFIRE-995">SUREFIRE-995</a>
  * @since 2.18.1
  */
-public class Surefire995CategoryInheritanceIT
-    extends SurefireJUnit4IntegrationTestCase
+public class Surefire995CategoryInheritanceIT extends SurefireJUnit4IntegrationTestCase
 {
 
     @Test
     public void negativeTestShouldRunAllCategories()
     {
         unpack()
-            .setTestToRun( "Special*Test" )
-            .executeTest()
-            .verifyErrorFree( 3 );
+                .setTestToRun( "Special*Test" )
+                .executeTest()
+                .verifyErrorFree( 3 );
     }
 
     @Test
     public void junit411ShouldRunExplicitCategory()
     {
-        unpack()
-            .addGoal( "-Ppositive-tests" )
-            .sysProp( "version.junit", "4.11" )
-            .executeTest()
-            .verifyErrorFree( 1 )
-            .verifyTextInLog( "CategorizedTest#a" );
+        final OutputValidator outputValidator = unpack()
+                .addGoal( "-Ppositive-tests" )
+                .sysProp( "version.junit", "4.11" )
+                .executeTest();
+
+        outputValidator
+                .verifyErrorFree( 1 )
+                .verifyTextInLog( "CategorizedTest#a" );
     }
 
     @Test
     public void junit411ShouldExcludeExplicitCategory()
     {
-        unpack()
-            .addGoal( "-Ppositive-tests-excluded-categories" )
-            .sysProp( "version.junit", "4.11" )
-            .executeTest()
-            .verifyErrorFree( 2 );
+        final OutputValidator outputValidator = unpack()
+                .addGoal( "-Ppositive-tests-excluded-categories" )
+                .sysProp( "version.junit", "4.11" )
+                .executeTest();
+        // SpecialCategorizedTest inherits the excluded annotation but should still run as
+        // until junit 4.11, the Category annotation is not inherited
+        outputValidator
+                .verifyTextInLog( "SpecialCategorizedTest#b" )
+                .verifyErrorFree( 16 );
     }
 
     @Test
     public void junit412ShouldRunInheritedCategory()
     {
         unpack()
-            .setTestToRun( "Special*Test" )
-            .addGoal( "-Ppositive-tests" )
-            .executeTest()
-            .verifyErrorFree( 2 );
+                .setTestToRun( "Special*Test" )
+                .addGoal( "-Ppositive-tests" )
+                .executeTest()
+                .verifyErrorFree( 2 );
     }
 
     @Test
     public void junit412ShouldExcludeInheritedCategory()
     {
         unpack()
-            .setTestToRun( "Special*Test" )
-            .addGoal( "-Ppositive-tests-excluded-categories" )
-            .executeTest()
-            .verifyErrorFree( 1 )
-            .verifyTextInLog( "SpecialNonCategoryTest#test" );
+                .setTestToRun( "Special*Test" )
+                .addGoal( "-Ppositive-tests-excluded-categories" )
+                .executeTest()
+                .verifyErrorFree( 1 )
+                .verifyTextInLog( "SpecialNonCategoryTest#test" );
+    }
+
+    @Test
+    public void junit411ShouldIgnoreInheritedCategories() throws VerificationException
+    {
+        // GIVEN a project using junit 4.11
+        final OutputValidator outputValidator = unpack()
+                .addGoal( "-Ppositive-tests-included-and-excluded-categories" )
+                .sysProp( "version.junit", "4.11" )
+                // AND the tests marked with CategoryB are marked for execution
+                .setGroups( "jiras.surefire955.group.marker.CategoryB" )
+                // WHEN the tests are executed
+                .executeTest();
+
+        // THEN only the tests in classes directly annotated should be executed
+        outputValidator
+                // Test runs when the category is present in the concrete class
+                .verifyTextInLog( "Running jiras.surefire955.group.BBCTest" )
+                .verifyTextInLog( "BBCTest#bbc" )
+                .verifyTextInLog( "AbstractBCTest#pb" )
+                .verifyTextInLog( "AbstractCTest#pc" )
+                .verifyTextInLog( "Running jiras.surefire955.group.BTest" )
+                .verifyTextInLog( "BTest#b" )
+                // Test does not run when there is no category in the concrete class
+                .assertThatLogLine( containsString( "BCTest#bc" ), is( 0 ) )
+                .assertThatLogLine( containsString( "ABCTest#abc" ), is( 0 ) )
+                .verifyErrorFree( 4 );
+    }
+
+    @Test
+    public void junit412ShouldExecuteInheritedCategories() throws VerificationException
+    {
+        // GIVEN a project using junit 4.12
+        final OutputValidator outputValidator = unpack()
+                .addGoal( "-Ppositive-tests-included-and-excluded-categories" )
+                .sysProp( "version.junit", "4.12" )
+                // AND the tests marked with CategoryB are marked for execution
+                .setGroups( "jiras.surefire955.group.marker.CategoryB" )
+                // WHEN the tests are executed
+                .executeTest();
+
+        // THEN the tests in classes directly marked with the CategoryB
+        outputValidator
+                .verifyErrorFree( 10 )
+                .verifyTextInLog( "Running jiras.surefire955.group.BBCTest" )
+                // AND Test runs when an already existing category is added in the concrete class
+                .verifyTextInLog( "BBCTest#bbc" )
+                .verifyTextInLog( "AbstractBCTest#pb" )
+                .verifyTextInLog( "AbstractCTest#pc" )
+                .verifyTextInLog( "Running jiras.surefire955.group.BTest" )
+                .verifyTextInLog( "BTest#b" )
+                // AND the tests in classes inheriting the CategoryB category should be executed
+                .verifyTextInLog( "Running jiras.surefire955.group.ABCTest" )
+                // AND Test runs when the concrete class has an additional (not excluded) category
+                .verifyTextInLog( "ABCTest#abc" )
+                .verifyTextInLog( "AbstractBCTest#pb" )
+                .verifyTextInLog( "AbstractCTest#pc" )
+                .verifyTextInLog( "Running jiras.surefire955.group.BCTest" )
+                // AND Test runs when there is no category in the concrete class
+                .verifyTextInLog( "BCTest#bc" )
+                .verifyTextInLog( "AbstractBCTest#pb" )
+                .verifyTextInLog( "AbstractCTest#pc" );
     }
 
     private SurefireLauncher unpack()
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/pom.xml b/surefire-its/src/test/resources/surefire-995-categoryInheritance/pom.xml
index 4662f24..f59e133 100644
--- a/surefire-its/src/test/resources/surefire-995-categoryInheritance/pom.xml
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/pom.xml
@@ -86,5 +86,8 @@
         </plugins>
       </build>
     </profile>
-  </profiles>
-</project>
+    <profile>
+      <id>positive-tests-included-and-excluded-categories</id>
+     </profile>
+   </profiles>
+ </project>
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/ABCTest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/ABCTest.java
new file mode 100644
index 0000000..1d37ff5
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/ABCTest.java
@@ -0,0 +1,36 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import jiras.surefire955.group.marker.CategoryA;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category( CategoryA.class )
+public class ABCTest extends jiras.surefire955.group.AbstractBCTest
+{
+
+    @Test
+    public void abc()
+    {
+        System.out.println( "ABCTest#abc" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/ATest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/ATest.java
new file mode 100644
index 0000000..0fef6c8
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/ATest.java
@@ -0,0 +1,36 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import jiras.surefire955.group.marker.CategoryA;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category( CategoryA.class )
+public class ATest
+{
+
+    @Test
+    public void a()
+    {
+        System.out.println( "ATest#a" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/AbstractBCTest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/AbstractBCTest.java
new file mode 100644
index 0000000..8511917
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/AbstractBCTest.java
@@ -0,0 +1,37 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import jiras.surefire955.group.marker.CategoryB;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+
+@Category( CategoryB.class )
+public abstract class AbstractBCTest extends jiras.surefire955.group.AbstractCTest
+{
+
+    @Test
+    public void pb()
+    {
+        System.out.println( "AbstractBCTest#pb" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/AbstractCTest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/AbstractCTest.java
new file mode 100644
index 0000000..34745c6
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/AbstractCTest.java
@@ -0,0 +1,37 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import jiras.surefire955.group.marker.CategoryC;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+
+@Category( CategoryC.class )
+public abstract class AbstractCTest
+{
+
+    @Test
+    public void pc()
+    {
+        System.out.println( "AbstractCTest#pc" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BBCTest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BBCTest.java
new file mode 100644
index 0000000..0fbe803
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BBCTest.java
@@ -0,0 +1,36 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import jiras.surefire955.group.marker.CategoryB;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category( CategoryB.class )
+public class BBCTest extends jiras.surefire955.group.AbstractBCTest
+{
+
+    @Test
+    public void bbc()
+    {
+        System.out.println( "BBCTest#bbc" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BCTest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BCTest.java
new file mode 100644
index 0000000..e99c2b6
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BCTest.java
@@ -0,0 +1,33 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.junit.Test;
+
+public class BCTest extends jiras.surefire955.group.AbstractBCTest
+{
+
+    @Test
+    public void bc()
+    {
+        System.out.println( "BCTest#bc" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BTest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BTest.java
new file mode 100644
index 0000000..d0bf839
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/BTest.java
@@ -0,0 +1,37 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import jiras.surefire955.group.marker.CategoryB;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+
+@Category( CategoryB.class )
+public class BTest
+{
+
+    @Test
+    public void b()
+    {
+        System.out.println( "BTest#b" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/UncategorizedTest.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/UncategorizedTest.java
new file mode 100644
index 0000000..06f8554
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/UncategorizedTest.java
@@ -0,0 +1,33 @@
+package jiras.surefire955.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.junit.Test;
+
+public class UncategorizedTest
+{
+
+    @Test
+    public void a()
+    {
+        System.out.println( "Uncategorized#a" );
+    }
+
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryA.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryA.java
new file mode 100644
index 0000000..cfda982
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryA.java
@@ -0,0 +1,24 @@
+package jiras.surefire955.group.marker;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public interface CategoryA
+{
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryB.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryB.java
new file mode 100644
index 0000000..16f269e
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryB.java
@@ -0,0 +1,24 @@
+package jiras.surefire955.group.marker;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public interface CategoryB
+{
+}
diff --git a/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryC.java b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryC.java
new file mode 100644
index 0000000..18dd3bb
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-995-categoryInheritance/src/test/java/jiras/surefire955/group/marker/CategoryC.java
@@ -0,0 +1,24 @@
+package jiras.surefire955.group.marker;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public interface CategoryC
+{
+}
diff --git a/surefire-providers/common-junit48/pom.xml b/surefire-providers/common-junit48/pom.xml
index fa80e47..a011654 100644
--- a/surefire-providers/common-junit48/pom.xml
+++ b/surefire-providers/common-junit48/pom.xml
@@ -17,77 +17,161 @@
   ~ under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
 
-  <parent>
-    <groupId>org.apache.maven.surefire</groupId>
-    <artifactId>surefire-providers</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
-  </parent>
+    <parent>
+        <groupId>org.apache.maven.surefire</groupId>
+        <artifactId>surefire-providers</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+    </parent>
 
-  <artifactId>common-junit48</artifactId>
+    <artifactId>common-junit48</artifactId>
 
-  <name>Shared JUnit48 Provider Code</name>
-  <description>Shared JUnit48 Provider Code</description>
+    <name>Shared JUnit48 Provider Code</name>
+    <description>Shared JUnit48 Provider Code</description>
 
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.8.1</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.surefire</groupId>
-      <artifactId>common-junit4</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.surefire</groupId>
-      <artifactId>surefire-grouper</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven.shared</groupId>
-      <artifactId>maven-shared-utils</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.jacoco</groupId>
-        <artifactId>jacoco-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>jacoco-agent</id>
-            <goals>
-              <goal>prepare-agent</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <propertyName>jacoco.agent</propertyName>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <argLine>${jvm.args.tests} ${jacoco.agent}</argLine>
-          <includes>
-            <include>**/JUnit4SuiteTest.java</include>
-          </includes>
-        </configuration>
-        <dependencies>
-          <dependency>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.8.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.surefire</groupId>
+            <artifactId>common-junit4</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.maven.surefire</groupId>
-            <artifactId>surefire-shadefire</artifactId>
-            <version>3.0.0-M4</version> <!-- ${shadedVersion}, but resolved due to https://issues.apache.org/jira/browse/MRELEASE-799 -->
-          </dependency>
-        </dependencies>
-      </plugin>
-    </plugins>
-  </build>
+            <artifactId>surefire-grouper</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-shared-utils</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>jacoco-agent</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <propertyName>jacoco.agent</propertyName>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>junit-4.11</id>
+                        <phase>process-test-sources</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/endorsed-test</outputDirectory>
+                            <overWriteIfNewer>false</overWriteIfNewer>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>junit</groupId>
+                                    <artifactId>junit</artifactId>
+                                    <version>4.11</version>
+                                    <type>jar</type>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>test</id>
+                        <phase>process-test-sources</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/endorsed-test</outputDirectory>
+                            <overWriteIfNewer>false</overWriteIfNewer>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>junit</groupId>
+                                    <artifactId>junit</artifactId>
+                                    <version>4.12</version>
+                                    <type>jar</type>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>default-test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <configuration>
+                            <includes>
+                                <include>**/JUnit4SuiteTest.java</include>
+                            </includes>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>junit-4.11</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <configuration>
+                            <test>GroupMatcherCategoryFilterPreJUnit412Test$JUnit4SuiteTest</test>
+                            <classpathDependencyExcludes>junit:junit</classpathDependencyExcludes>
+                            <additionalClasspathElements>
+                                <additionalClasspathElement>${project.build.directory}/endorsed-test/junit-4.11.jar</additionalClasspathElement>
+                            </additionalClasspathElements>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>junit-4.12</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>test</goal>
+                        </goals>
+                        <configuration>
+                            <test>GroupMatcherCategoryFilterTest$JUnit4SuiteTest</test>
+                            <classpathDependencyExcludes>junit:junit</classpathDependencyExcludes>
+                            <additionalClasspathElements>
+                                <additionalClasspathElement>${project.build.directory}/endorsed-test/junit-4.12.jar</additionalClasspathElement>
+                            </additionalClasspathElements>
+                        </configuration>
+                    </execution>
+                </executions>
+                <configuration>
+                    <argLine>${jvm.args.tests} ${jacoco.agent}</argLine>
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.maven.surefire</groupId>
+                        <artifactId>surefire-shadefire</artifactId>
+                        <version>3.0.0-M4
+                        </version> <!-- ${shadedVersion}, but resolved due to https://issues.apache.org/jira/browse/MRELEASE-799 -->
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilter.java b/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilter.java
index 484defd..287d327 100644
--- a/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilter.java
+++ b/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilter.java
@@ -26,6 +26,7 @@ import org.junit.experimental.categories.Category;
 import org.junit.runner.Description;
 import org.junit.runner.manipulation.Filter;
 
+import java.lang.annotation.Inherited;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
@@ -33,9 +34,13 @@ import java.util.Set;
 import static java.util.Collections.addAll;
 import static org.junit.runner.Description.createSuiteDescription;
 
-final class GroupMatcherCategoryFilter
-    extends Filter
+final class GroupMatcherCategoryFilter extends Filter
 {
+    /**
+     * Only traverse the tree if <code>@Category</code> annotation is inherited (since <code>junit 4.12</code>).
+     */
+    private static final boolean IS_CATEGORY_INHERITED = Category.class.isAnnotationPresent( Inherited.class );
+
     private final AndGroupMatcher matcher;
 
     GroupMatcherCategoryFilter( GroupMatcher included, GroupMatcher excluded )
@@ -63,33 +68,56 @@ final class GroupMatcherCategoryFilter
     @Override
     public boolean shouldRun( Description description )
     {
-        if ( description.getMethodName() == null || description.getTestClass() == null )
+        if ( invalidTestClass( description ) )
         {
             return shouldRun( description, null, null );
         }
+
+        if ( describesTestClass( description ) ) // is a test class
+        {
+            Class<?> testClass = description.getTestClass();
+            return shouldRun( description, null, testClass );
+        }
         else
+        // is a test method
         {
             Class<?> testClass = description.getTestClass();
             return shouldRun( description, createSuiteDescription( testClass ), testClass );
         }
     }
 
+    private boolean describesTestClass( Description description )
+    {
+        String methodName = description.getMethodName();
+        // Description parser in Junit 4.8 can return "null" String.
+        return methodName == null || methodName.equals( "null" );
+    }
+
+    private boolean invalidTestClass( Description description )
+    {
+        return description.getTestClass() == null;
+    }
+
     private static void findSuperclassCategories( Set<Class<?>> cats, Class<?> clazz )
     {
-        if ( clazz != null && clazz.getSuperclass() != null )
+        if ( IS_CATEGORY_INHERITED && hasSuperclass( clazz ) )
         {
             Category cat = clazz.getSuperclass().getAnnotation( Category.class );
             if ( cat != null )
             {
+                // Found categories in current superclass
                 addAll( cats, cat.value() );
             }
-            else
-            {
-                findSuperclassCategories( cats, clazz.getSuperclass() );
-            }
+            // Search the hierarchy
+            findSuperclassCategories( cats, clazz.getSuperclass() );
         }
     }
 
+    private static boolean hasSuperclass( Class<?> clazz )
+    {
+        return clazz != null && clazz.getSuperclass() != null;
+    }
+
     private boolean shouldRun( Description description, Description parent, Class<?> parentClass )
     {
         if ( matcher == null )
@@ -102,6 +130,7 @@ final class GroupMatcherCategoryFilter
             Category cat = description.getAnnotation( Category.class );
             if ( cat != null )
             {
+                // Found categories in current description
                 addAll( cats, cat.value() );
             }
 
@@ -110,10 +139,10 @@ final class GroupMatcherCategoryFilter
                 cat = parent.getAnnotation( Category.class );
                 if ( cat != null )
                 {
+                    // Found categories in current parent
                     addAll( cats, cat.value() );
                 }
             }
-
             if ( parentClass != null )
             {
                 findSuperclassCategories( cats, parentClass );
@@ -125,12 +154,12 @@ final class GroupMatcherCategoryFilter
                 cat = testClass.getAnnotation( Category.class );
                 if ( cat != null )
                 {
+                    // Found categories in current testClass
                     addAll( cats, cat.value() );
                 }
             }
 
             cats.remove( null );
-
             boolean result = matcher.enabled( cats.toArray( new Class<?>[cats.size()] ) );
 
             if ( !result )
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilterPreJUnit412Test.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilterPreJUnit412Test.java
new file mode 100644
index 0000000..543e585
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilterPreJUnit412Test.java
@@ -0,0 +1,100 @@
+package org.apache.maven.surefire.common.junit48;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.runner.Version;
+import org.apache.maven.surefire.common.junit48.tests.group.ABCParameterizedTest;
+import org.apache.maven.surefire.common.junit48.tests.group.ABCTest;
+import org.apache.maven.surefire.common.junit48.tests.group.ATest;
+import org.apache.maven.surefire.common.junit48.tests.group.BCTest;
+import org.apache.maven.surefire.group.match.GroupMatcher;
+import org.apache.maven.surefire.group.match.SingleGroupMatcher;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.runner.Description.createSuiteDescription;
+import static org.junit.runner.Description.createTestDescription;
+
+/**
+ * Before JUnit 4.12, @Category annotation was not @Inherited. These tests make sure the implied contract is honored.
+ */
+public class GroupMatcherCategoryFilterPreJUnit412Test
+{
+    private GroupMatcherCategoryFilter cut;
+
+    @BeforeClass
+    public static void printVersion()
+    {
+        System.out.println( Version.id() );
+    }
+
+    @Test
+    public void shouldNotMatchIncludedCategoryInParent()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB" );
+        GroupMatcher excluded = null;
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertFalse( cut.shouldRun( createSuiteDescription( BCTest.class ) ) );
+        assertFalse( cut.shouldRun( createSuiteDescription( ATest.class ) ) );
+    }
+
+    @Test
+    public void shouldNotMatchIncludedCategoryInHierarchy()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryC" );
+        GroupMatcher excluded = null;
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertFalse( cut.shouldRun( createSuiteDescription( ABCTest.class ) ) );
+        assertFalse( cut.shouldRun( createSuiteDescription( BCTest.class ) ) );
+        assertFalse( cut.shouldRun( createSuiteDescription( ATest.class ) ) );
+    }
+
+    @Test
+    public void shouldNotMatchIncludedCategoryInParentWhenSelfHasAnother()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB" );
+        GroupMatcher excluded = null;
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertFalse( cut.shouldRun( createSuiteDescription( ABCTest.class ) ) );
+        assertFalse( cut.shouldRun( createTestDescription( ABCTest.class, "abc" ) ) );
+        assertFalse( cut.shouldRun( createSuiteDescription( ABCParameterizedTest.class ) ) );
+        assertFalse( cut.shouldRun( createTestDescription( ABCParameterizedTest.class, "abc" ) ) );
+    }
+
+    /**
+     *
+     */
+    public static class JUnit4SuiteTest extends TestCase
+    {
+        public static junit.framework.Test suite()
+        {
+            TestSuite suite = new TestSuite();
+            suite.addTest( new JUnit4TestAdapter( GroupMatcherCategoryFilterPreJUnit412Test.class ) );
+            return suite;
+        }
+    }
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilterTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilterTest.java
new file mode 100644
index 0000000..6ddb11a
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/GroupMatcherCategoryFilterTest.java
@@ -0,0 +1,138 @@
+package org.apache.maven.surefire.common.junit48;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.runner.Version;
+import org.apache.maven.surefire.common.junit48.tests.group.ABCParameterizedTest;
+import org.apache.maven.surefire.common.junit48.tests.group.ABCTest;
+import org.apache.maven.surefire.common.junit48.tests.group.ATest;
+import org.apache.maven.surefire.common.junit48.tests.group.BBCTest;
+import org.apache.maven.surefire.common.junit48.tests.group.BCTest;
+import org.apache.maven.surefire.common.junit48.tests.group.BTest;
+import org.apache.maven.surefire.group.match.GroupMatcher;
+import org.apache.maven.surefire.group.match.SingleGroupMatcher;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.runner.Description.createSuiteDescription;
+import static org.junit.runner.Description.createTestDescription;
+
+/**
+ * Tests covering inheritance in @Categories for Test classes.
+ */
+public class GroupMatcherCategoryFilterTest
+{
+    private GroupMatcherCategoryFilter cut;
+
+    @BeforeClass
+    public static void printVersion()
+    {
+        System.out.println( Version.id() );
+    }
+
+    @Test
+    public void shouldMatchIncludedCategoryInSelf()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB" );
+        GroupMatcher excluded = null;
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertTrue( cut.shouldRun( createSuiteDescription( BTest.class ) ) );
+    }
+
+    @Test
+    public void shouldMatchIncludedCategoryInParent()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB" );
+        GroupMatcher excluded = null;
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertTrue( cut.shouldRun( createSuiteDescription( BCTest.class ) ) );
+        assertFalse( cut.shouldRun( createSuiteDescription( ATest.class ) ) );
+    }
+
+    @Test
+    public void shouldMatchIncludedCategoryInHierarchy()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryC" );
+        GroupMatcher excluded = null;
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertTrue( cut.shouldRun( createSuiteDescription( ABCTest.class ) ) );
+        assertTrue( cut.shouldRun( createSuiteDescription( BCTest.class ) ) );
+        assertFalse( cut.shouldRun( createSuiteDescription( ATest.class ) ) );
+    }
+
+    @Test
+    public void shouldMatchIncludedCategoryInParentWhenSelfHasAnother()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB" );
+        GroupMatcher excluded = null;
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertTrue( cut.shouldRun( createSuiteDescription( ABCTest.class ) ) );
+        assertTrue( cut.shouldRun( createTestDescription( ABCTest.class, "abc" ) ) );
+        assertTrue( cut.shouldRun( createSuiteDescription( ABCParameterizedTest.class ) ) );
+        assertTrue( cut.shouldRun( createTestDescription( ABCParameterizedTest.class, "abc" ) ) );
+    }
+
+    @Test
+    public void shouldNotMatchIncludedCategoryInParentWhenSelfHasExcludedCategory()
+    {
+        GroupMatcher included =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB" );
+        GroupMatcher excluded =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryA" );
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertFalse( cut.shouldRun( createSuiteDescription( ABCTest.class ) ) );
+        assertTrue( cut.shouldRun( createSuiteDescription( BBCTest.class ) ) );
+        assertTrue( cut.shouldRun( createSuiteDescription( BTest.class ) ) );
+    }
+
+    @Test
+    public void shouldMatchExcludedCategoryInSelf()
+    {
+        GroupMatcher included = null;
+        GroupMatcher excluded =
+            new SingleGroupMatcher( "org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryA" );
+        cut = new GroupMatcherCategoryFilter( included, excluded );
+        assertFalse( cut.shouldRun( createSuiteDescription( ATest.class ) ) );
+        assertTrue( cut.shouldRun( createSuiteDescription( BTest.class ) ) );
+        assertTrue( cut.shouldRun( createSuiteDescription( BBCTest.class ) ) );
+    }
+
+    /**
+     *
+     */
+    public static class JUnit4SuiteTest extends TestCase
+    {
+        public static junit.framework.Test suite()
+        {
+            TestSuite suite = new TestSuite();
+            suite.addTest( new JUnit4TestAdapter( GroupMatcherCategoryFilterTest.class ) );
+            return suite;
+        }
+    }
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABCParameterizedTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABCParameterizedTest.java
new file mode 100644
index 0000000..a1cd44a
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABCParameterizedTest.java
@@ -0,0 +1,63 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryA;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * ABCParameterizedTest.
+ */
+@Category( CategoryA.class )
+@RunWith( Parameterized.class )
+public class ABCParameterizedTest
+    extends AbstractBCTest
+{
+    @Parameterized.Parameters
+    public static List<Object[]> data()
+    {
+        return Arrays.asList( 
+                              new Object[][] { 
+                                  { 0 }, 
+                                  { 1 }, 
+                                  { 6 } 
+                                  } );
+    }
+
+    private int number;
+
+    public ABCParameterizedTest( int number )
+    {
+        this.number = number;
+    }
+
+    @Test
+    public void abc()
+    {
+        System.out.println( "ABCTest#abc(" + number + ")" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABCTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABCTest.java
new file mode 100644
index 0000000..63749aa
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABCTest.java
@@ -0,0 +1,40 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryA;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * ABCTest.
+ */
+@Category( CategoryA.class )
+public class ABCTest
+    extends AbstractBCTest
+{
+
+    @Test
+    public void abc()
+    {
+        System.out.println( "ABCTest#abc" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABMethodTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABMethodTest.java
new file mode 100644
index 0000000..5146c55
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ABMethodTest.java
@@ -0,0 +1,47 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryA;
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * ABMethodTest.
+ */
+@Category( CategoryA.class )
+public class ABMethodTest
+{
+
+    @Test
+    public void a()
+    {
+        System.out.println( "ATest#a" );
+    }
+
+    @Category( CategoryB.class )
+    @Test
+    public void b()
+    {
+        System.out.println( "ATest#b" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ATest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ATest.java
new file mode 100644
index 0000000..3f2f9d5
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/ATest.java
@@ -0,0 +1,39 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryA;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * ATest.
+ */
+@Category( CategoryA.class )
+public class ATest
+{
+
+    @Test
+    public void a()
+    {
+        System.out.println( "ATest#a" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/AbstractBCTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/AbstractBCTest.java
new file mode 100644
index 0000000..8cef8ab
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/AbstractBCTest.java
@@ -0,0 +1,40 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * AbstractBCTest.
+ */
+@Category( CategoryB.class )
+public abstract class AbstractBCTest
+    extends AbstractCTest
+{
+
+    @Test
+    public void pb()
+    {
+        System.out.println( "AbstractBCTest#pb" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/AbstractCTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/AbstractCTest.java
new file mode 100644
index 0000000..942f915
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/AbstractCTest.java
@@ -0,0 +1,39 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryC;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * AbstractCTest.
+ */
+@Category( CategoryC.class )
+public abstract class AbstractCTest
+{
+
+    @Test
+    public void pc()
+    {
+        System.out.println( "AbstractCTest#pc" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BBCTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BBCTest.java
new file mode 100644
index 0000000..e48cbec
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BBCTest.java
@@ -0,0 +1,40 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * BBCTest.
+ */
+@Category( CategoryB.class )
+public class BBCTest
+    extends AbstractBCTest
+{
+
+    @Test
+    public void bbc()
+    {
+        System.out.println( "BBCTest#bbc" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BCTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BCTest.java
new file mode 100644
index 0000000..0cd859c
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BCTest.java
@@ -0,0 +1,37 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.junit.Test;
+
+/**
+ * BCTest.
+ */
+public class BCTest
+    extends AbstractBCTest
+{
+
+    @Test
+    public void bc()
+    {
+        System.out.println( "BCTest#bc" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BTest.java
new file mode 100644
index 0000000..126678d
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/BTest.java
@@ -0,0 +1,39 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.common.junit48.tests.group.marker.CategoryB;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+/**
+ * BTest.
+ */
+@Category( CategoryB.class )
+public class BTest
+{
+
+    @Test
+    public void b()
+    {
+        System.out.println( "BTest#b" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/UncategorizedTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/UncategorizedTest.java
new file mode 100644
index 0000000..92a4a7a
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/UncategorizedTest.java
@@ -0,0 +1,36 @@
+package org.apache.maven.surefire.common.junit48.tests.group;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.junit.Test;
+
+/**
+ * UncategorizedTest.
+ */
+public class UncategorizedTest
+{
+
+    @Test
+    public void a()
+    {
+        System.out.println( "Uncategorized#a" );
+    }
+
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryA.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryA.java
new file mode 100644
index 0000000..5d69a12
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryA.java
@@ -0,0 +1,27 @@
+package org.apache.maven.surefire.common.junit48.tests.group.marker;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * CategoryA marker.
+ */
+public interface CategoryA
+{
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryB.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryB.java
new file mode 100644
index 0000000..380b895
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryB.java
@@ -0,0 +1,27 @@
+package org.apache.maven.surefire.common.junit48.tests.group.marker;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * CategoryB marker.
+ */
+public interface CategoryB
+{
+}
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryC.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryC.java
new file mode 100644
index 0000000..df16556
--- /dev/null
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/tests/group/marker/CategoryC.java
@@ -0,0 +1,27 @@
+package org.apache.maven.surefire.common.junit48.tests.group.marker;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * CategoryC marker.
+ */
+public interface CategoryC
+{
+}