[maven-checkstyle-plugin] branch MCHECKSTYLE-99 created (now 2f45933)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[maven-checkstyle-plugin] branch MCHECKSTYLE-99 created (now 2f45933)

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

slachiewicz pushed a change to branch MCHECKSTYLE-99
in repository https://gitbox.apache.org/repos/asf/maven-checkstyle-plugin.git.


      at 2f45933  [MCHECKSTYLE-99] <includeTestSourceDirectory> should use default test

This branch includes the following new commits:

     new 2f45933  [MCHECKSTYLE-99] <includeTestSourceDirectory> should use default test

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.

Reply | Threaded
Open this post in threaded view
|

[maven-checkstyle-plugin] 01/01: [MCHECKSTYLE-99] <includeTestSourceDirectory> should use default test

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

slachiewicz pushed a commit to branch MCHECKSTYLE-99
in repository https://gitbox.apache.org/repos/asf/maven-checkstyle-plugin.git

commit 2f45933ff9ce22413dcededc5be9a8f48b9942df
Author: Stefan Paal <[hidden email]>
AuthorDate: Sun Jul 12 20:20:29 2020 +0200

    [MCHECKSTYLE-99] <includeTestSourceDirectory> should use default test
   
    sources xref output dir: ${project.reporting.outputDirectory}/xref-test
   
    - add parameter xrefTestLocation
    - use xrefTestLocation to create jxr report links for test source file
    - add integration tests
    - do not use StringUtils.isEmpty but explicitly evaluate the string
    content
   
    Closes #34
---
 .../invoker.properties                             | 18 +++++
 .../pom.xml                                        | 73 +++++++++++++++++++
 .../src/main/java/com/example/App.java             | 32 ++++++++
 .../src/test/java/com/example/AppTest.java         | 57 +++++++++++++++
 .../verify.groovy                                  | 26 +++++++
 src/it/MCHECKSTYLE-99/invoker.properties           | 18 +++++
 src/it/MCHECKSTYLE-99/pom.xml                      | 72 ++++++++++++++++++
 .../src/main/java/com/example/App.java             | 32 ++++++++
 .../src/test/java/com/example/AppTest.java         | 57 +++++++++++++++
 src/it/MCHECKSTYLE-99/verify.groovy                | 26 +++++++
 .../checkstyle/AbstractCheckstyleReport.java       | 85 ++++++++++++++++------
 .../checkstyle/CheckstyleReportGenerator.java      | 55 +++++++++++++-
 src/test/plugin-configs/custom-plugin-config.xml   |  1 +
 .../dep-resolution-exception-plugin-config.xml     |  1 +
 .../plugin-configs/fail-on-error-plugin-config.xml |  1 +
 src/test/plugin-configs/min-plugin-config.xml      |  1 +
 src/test/plugin-configs/multi-plugin-config.xml    |  1 +
 src/test/plugin-configs/no-files-plugin-config.xml |  1 +
 src/test/plugin-configs/no-rules-plugin-config.xml |  1 +
 .../plugin-configs/no-severity-plugin-config.xml   |  1 +
 .../plugin-configs/no-source-plugin-config.xml     |  1 +
 .../test-source-directory-plugin-config.xml        |  1 +
 src/test/plugin-configs/useFile-plugin-config.xml  |  1 +
 23 files changed, 536 insertions(+), 26 deletions(-)

diff --git a/src/it/MCHECKSTYLE-99-custom-xref-test-location/invoker.properties b/src/it/MCHECKSTYLE-99-custom-xref-test-location/invoker.properties
new file mode 100644
index 0000000..4adad81
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99-custom-xref-test-location/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean checkstyle:checkstyle
diff --git a/src/it/MCHECKSTYLE-99-custom-xref-test-location/pom.xml b/src/it/MCHECKSTYLE-99-custom-xref-test-location/pom.xml
new file mode 100644
index 0000000..2c3839f
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99-custom-xref-test-location/pom.xml
@@ -0,0 +1,73 @@
+<!--
+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.
+-->
+<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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example</groupId>
+  <artifactId>checkstyle-new</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>checkstyle-new</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <checkstyleVersion>@pom.version@</checkstyleVersion>
+    <jxrPluginVersion>3.0.0</jxrPluginVersion>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <version>@pom.version@</version>
+          <configuration>
+            <configLocation>https://raw.githubusercontent.com/checkstyle/checkstyle/checkstyle-8.28/src/main/resources/sun_checks.xml</configLocation>
+            <includeTestSourceDirectory>true</includeTestSourceDirectory>
+            <xrefTestLocation>custom-xref-test-location</xrefTestLocation>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jxr-plugin</artifactId>
+          <version>${jxrPluginVersion}</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>  
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
diff --git a/src/it/MCHECKSTYLE-99-custom-xref-test-location/src/main/java/com/example/App.java b/src/it/MCHECKSTYLE-99-custom-xref-test-location/src/main/java/com/example/App.java
new file mode 100644
index 0000000..498f612
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99-custom-xref-test-location/src/main/java/com/example/App.java
@@ -0,0 +1,32 @@
+package com.example;
+
+/*
+ * 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.
+ */
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+    public static void main( String[] args )
+    {
+        System.out.println( "Hello World!" );
+    }
+}
diff --git a/src/it/MCHECKSTYLE-99-custom-xref-test-location/src/test/java/com/example/AppTest.java b/src/it/MCHECKSTYLE-99-custom-xref-test-location/src/test/java/com/example/AppTest.java
new file mode 100644
index 0000000..0d6c5ab
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99-custom-xref-test-location/src/test/java/com/example/AppTest.java
@@ -0,0 +1,57 @@
+package com.example;
+
+/*
+ * 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.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public AppTest( String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( AppTest.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}
diff --git a/src/it/MCHECKSTYLE-99-custom-xref-test-location/verify.groovy b/src/it/MCHECKSTYLE-99-custom-xref-test-location/verify.groovy
new file mode 100644
index 0000000..c0e8435
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99-custom-xref-test-location/verify.groovy
@@ -0,0 +1,26 @@
+
+/*
+ * 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.
+ */
+
+site = new File( basedir, 'target/site/checkstyle.html' )
+assert site.exists();
+assert site.text.contains( '<a href="./xref/com/example/App.html#L26">' )
+assert site.text.contains( '<a href="./custom-xref-test-location/com/example/AppTest.html#L32">' )
+
+return true;
diff --git a/src/it/MCHECKSTYLE-99/invoker.properties b/src/it/MCHECKSTYLE-99/invoker.properties
new file mode 100644
index 0000000..4adad81
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean checkstyle:checkstyle
diff --git a/src/it/MCHECKSTYLE-99/pom.xml b/src/it/MCHECKSTYLE-99/pom.xml
new file mode 100644
index 0000000..450f13c
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99/pom.xml
@@ -0,0 +1,72 @@
+<!--
+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.
+-->
+<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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example</groupId>
+  <artifactId>checkstyle-new</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>checkstyle-new</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <checkstyleVersion>@pom.version@</checkstyleVersion>
+    <jxrPluginVersion>3.0.0</jxrPluginVersion>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <version>@pom.version@</version>
+          <configuration>
+            <configLocation>https://raw.githubusercontent.com/checkstyle/checkstyle/checkstyle-8.28/src/main/resources/sun_checks.xml</configLocation>
+            <includeTestSourceDirectory>true</includeTestSourceDirectory>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jxr-plugin</artifactId>
+          <version>${jxrPluginVersion}</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>  
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
diff --git a/src/it/MCHECKSTYLE-99/src/main/java/com/example/App.java b/src/it/MCHECKSTYLE-99/src/main/java/com/example/App.java
new file mode 100644
index 0000000..498f612
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99/src/main/java/com/example/App.java
@@ -0,0 +1,32 @@
+package com.example;
+
+/*
+ * 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.
+ */
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+    public static void main( String[] args )
+    {
+        System.out.println( "Hello World!" );
+    }
+}
diff --git a/src/it/MCHECKSTYLE-99/src/test/java/com/example/AppTest.java b/src/it/MCHECKSTYLE-99/src/test/java/com/example/AppTest.java
new file mode 100644
index 0000000..0d6c5ab
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99/src/test/java/com/example/AppTest.java
@@ -0,0 +1,57 @@
+package com.example;
+
+/*
+ * 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.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public AppTest( String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( AppTest.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}
diff --git a/src/it/MCHECKSTYLE-99/verify.groovy b/src/it/MCHECKSTYLE-99/verify.groovy
new file mode 100644
index 0000000..1567552
--- /dev/null
+++ b/src/it/MCHECKSTYLE-99/verify.groovy
@@ -0,0 +1,26 @@
+
+/*
+ * 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.
+ */
+
+site = new File( basedir, 'target/site/checkstyle.html' )
+assert site.exists();
+assert site.text.contains( '<a href="./xref/com/example/App.html#L26">' )
+assert site.text.contains( '<a href="./xref-test/com/example/AppTest.html#L32">' )
+
+return true;
diff --git a/src/main/java/org/apache/maven/plugins/checkstyle/AbstractCheckstyleReport.java b/src/main/java/org/apache/maven/plugins/checkstyle/AbstractCheckstyleReport.java
index 3b958ff..f2e4aa0 100644
--- a/src/main/java/org/apache/maven/plugins/checkstyle/AbstractCheckstyleReport.java
+++ b/src/main/java/org/apache/maven/plugins/checkstyle/AbstractCheckstyleReport.java
@@ -389,6 +389,12 @@ public abstract class AbstractCheckstyleReport
     private File xrefLocation;
 
     /**
+     * Location of the XrefTests to link to.
+     */
+    @Parameter( defaultValue = "${project.reporting.outputDirectory}/xref-test" )
+    private File xrefTestLocation;
+
+    /**
      * When using custom treeWalkers, specify their names here so the checks
      * inside the treeWalker end up the the rule-summary.
      *
@@ -743,35 +749,19 @@ public abstract class AbstractCheckstyleReport
         generator.setCheckstyleConfig( results.getConfiguration() );
         if ( linkXRef )
         {
-            String relativePath = PathTool.getRelativePath( getOutputDirectory(), xrefLocation.getAbsolutePath() );
-            if ( StringUtils.isEmpty( relativePath ) )
-            {
-                relativePath = ".";
-            }
-            relativePath = relativePath + "/" + xrefLocation.getName();
-            if ( xrefLocation.exists() )
-            {
-                // XRef was already generated by manual execution of a lifecycle
-                // binding
-                generator.setXrefLocation( relativePath );
-            }
-            else
+            initializeXrefLocation( generator );
+            if ( generator.getXrefLocation() == null && results.getFileCount() > 0 )
             {
-                // Not yet generated - check if the report is on its way
-                for ( ReportPlugin report : (Iterable<ReportPlugin>) getProject().getReportPlugins() )
-                {
-                    String artifactId = report.getArtifactId();
-                    if ( "maven-jxr-plugin".equals( artifactId ) || "jxr-maven-plugin".equals( artifactId ) )
-                    {
-                        generator.setXrefLocation( relativePath );
-                    }
-                }
+                getLog().warn( "Unable to locate Source XRef to link to - DISABLED" );
             }
 
-            if ( generator.getXrefLocation() == null && results.getFileCount() > 0 )
+            initializeXrefTestLocation( generator );
+            if ( generator.getXrefTestLocation() == null && results.getFileCount() > 0 )
             {
-                getLog().warn( "Unable to locate Source XRef to link to - DISABLED" );
+                getLog().warn( "Unable to locate Test Source XRef to link to - DISABLED" );
             }
+
+            generator.setTestSourceDirectories( getTestSourceDirectories() );
         }
         if ( treeWalkerNames != null )
         {
@@ -780,6 +770,53 @@ public abstract class AbstractCheckstyleReport
         generator.generateReport( results );
     }
 
+    private void initializeXrefLocation( CheckstyleReportGenerator generator )
+    {
+      String relativePath = determineRelativePath( xrefLocation );
+      if ( xrefLocation.exists() || checkMavenJxrPluginIsConfigured() )
+      {
+          // XRef was already generated by manual execution of a lifecycle binding
+          // the report is on its way
+          generator.setXrefLocation( relativePath );
+      }
+    }
+
+    private void initializeXrefTestLocation( CheckstyleReportGenerator generator )
+    {
+      String relativePath = determineRelativePath( xrefTestLocation );
+      if ( xrefTestLocation.exists() || checkMavenJxrPluginIsConfigured() )
+      {
+          // XRef was already generated by manual execution of a lifecycle binding
+          // the report is on its way
+          generator.setXrefTestLocation( relativePath );
+      }
+    }
+
+    private String determineRelativePath( File location )
+    {
+      String relativePath = PathTool.getRelativePath( getOutputDirectory(), location.getAbsolutePath() );
+      if ( relativePath == null || relativePath.trim().isEmpty() )
+      {
+          relativePath = ".";
+      }
+
+      return relativePath + "/" + location.getName();
+    }
+
+    private boolean checkMavenJxrPluginIsConfigured()
+    {
+        for ( ReportPlugin report : (Iterable<ReportPlugin>) getProject().getReportPlugins() )
+        {
+            String artifactId = report.getArtifactId();
+            if ( "maven-jxr-plugin".equals( artifactId ) || "jxr-maven-plugin".equals( artifactId ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     private static ResourceBundle getBundle( Locale locale )
     {
         return ResourceBundle.getBundle( "checkstyle-report", locale, AbstractCheckstyleReport.class.getClassLoader() );
diff --git a/src/main/java/org/apache/maven/plugins/checkstyle/CheckstyleReportGenerator.java b/src/main/java/org/apache/maven/plugins/checkstyle/CheckstyleReportGenerator.java
index aae277d..4f97b48 100644
--- a/src/main/java/org/apache/maven/plugins/checkstyle/CheckstyleReportGenerator.java
+++ b/src/main/java/org/apache/maven/plugins/checkstyle/CheckstyleReportGenerator.java
@@ -71,6 +71,10 @@ public class CheckstyleReportGenerator
 
     private String xrefLocation;
 
+    private String xrefTestLocation;
+
+    private List<File> testSourceDirectories = new ArrayList<>();
+
     private List<String> treeWalkerNames = Collections.singletonList( "TreeWalker" );
 
     private final IconTool iconTool;
@@ -673,9 +677,10 @@ public class CheckstyleReportGenerator
             sink.tableCell();
 
             int line = event.getLine();
-            if ( getXrefLocation() != null && line != 0 )
+            String effectiveXrefLocation = getEffectiveXrefLocation( eventList );
+            if ( effectiveXrefLocation != null && line != 0 )
             {
-                sink.link( getXrefLocation() + "/" + filename.replaceAll( "\\.java$", ".html" ) + "#L"
+                sink.link( effectiveXrefLocation + "/" + filename.replaceAll( "\\.java$", ".html" ) + "#L"
                     + line );
                 sink.text( String.valueOf( line ) );
                 sink.link_();
@@ -690,6 +695,32 @@ public class CheckstyleReportGenerator
         }
     }
 
+    private String getEffectiveXrefLocation( List<AuditEvent> eventList )
+    {
+        String absoluteFilename = eventList.get( 0 ).getFileName();
+        if ( isTestSource( absoluteFilename ) )
+        {
+            return getXrefTestLocation();
+        }
+        else
+        {
+            return getXrefLocation();
+        }
+    }
+
+    private boolean isTestSource( final String absoluteFilename )
+    {
+        for ( File testSourceDirectory : testSourceDirectories )
+        {
+            if ( absoluteFilename.startsWith( testSourceDirectory.getAbsolutePath() ) )
+            {
+                return true;
+            }
+        }
+      
+        return false;
+    }
+
     public SeverityLevel getSeverityLevel()
     {
         return severityLevel;
@@ -750,6 +781,26 @@ public class CheckstyleReportGenerator
         this.xrefLocation = xrefLocation;
     }
 
+    public String getXrefTestLocation()
+    {
+        return xrefTestLocation;
+    }
+
+    public void setXrefTestLocation( String xrefTestLocation )
+    {
+        this.xrefTestLocation = xrefTestLocation;
+    }
+
+    public List<File> getTestSourceDirectories()
+    {
+        return testSourceDirectories;
+    }
+
+    public void setTestSourceDirectories( List<File> testSourceDirectories )
+    {
+        this.testSourceDirectories = testSourceDirectories;
+    }
+
     public Configuration getCheckstyleConfig()
     {
         return checkstyleConfig;
diff --git a/src/test/plugin-configs/custom-plugin-config.xml b/src/test/plugin-configs/custom-plugin-config.xml
index 8b232a1..309762e 100644
--- a/src/test/plugin-configs/custom-plugin-config.xml
+++ b/src/test/plugin-configs/custom-plugin-config.xml
@@ -43,6 +43,7 @@ under the License.
           <linkXRef>true</linkXRef>
           <!-- value not really important, just point to an existing dir -->
           <xrefLocation>${basedir}/target/test-harness/checkstyle/custom</xrefLocation>
+          <xrefTestLocation>${basedir}/target/test-harness/checkstyle/custom</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/dep-resolution-exception-plugin-config.xml b/src/test/plugin-configs/dep-resolution-exception-plugin-config.xml
index b24f49c..d2c0218 100644
--- a/src/test/plugin-configs/dep-resolution-exception-plugin-config.xml
+++ b/src/test/plugin-configs/dep-resolution-exception-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/fail-on-error-plugin-config.xml b/src/test/plugin-configs/fail-on-error-plugin-config.xml
index be98088..06853a1 100644
--- a/src/test/plugin-configs/fail-on-error-plugin-config.xml
+++ b/src/test/plugin-configs/fail-on-error-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/min-plugin-config.xml b/src/test/plugin-configs/min-plugin-config.xml
index ad4af9a..a151bdb 100644
--- a/src/test/plugin-configs/min-plugin-config.xml
+++ b/src/test/plugin-configs/min-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/multi-plugin-config.xml b/src/test/plugin-configs/multi-plugin-config.xml
index 9504a3c..4f3d4f2 100644
--- a/src/test/plugin-configs/multi-plugin-config.xml
+++ b/src/test/plugin-configs/multi-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/no-files-plugin-config.xml b/src/test/plugin-configs/no-files-plugin-config.xml
index be550b8..ad5e125 100644
--- a/src/test/plugin-configs/no-files-plugin-config.xml
+++ b/src/test/plugin-configs/no-files-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/no-rules-plugin-config.xml b/src/test/plugin-configs/no-rules-plugin-config.xml
index 3f2a1e6..b189c75 100644
--- a/src/test/plugin-configs/no-rules-plugin-config.xml
+++ b/src/test/plugin-configs/no-rules-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/no-severity-plugin-config.xml b/src/test/plugin-configs/no-severity-plugin-config.xml
index b1e0e8e..91d5fae 100644
--- a/src/test/plugin-configs/no-severity-plugin-config.xml
+++ b/src/test/plugin-configs/no-severity-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/no-source-plugin-config.xml b/src/test/plugin-configs/no-source-plugin-config.xml
index 6da6307..37a110e 100644
--- a/src/test/plugin-configs/no-source-plugin-config.xml
+++ b/src/test/plugin-configs/no-source-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/test-source-directory-plugin-config.xml b/src/test/plugin-configs/test-source-directory-plugin-config.xml
index 4b06152..2f6defe 100644
--- a/src/test/plugin-configs/test-source-directory-plugin-config.xml
+++ b/src/test/plugin-configs/test-source-directory-plugin-config.xml
@@ -45,6 +45,7 @@ under the License.
           <consoleOutput>false</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <encoding>UTF-8</encoding>
         </configuration>
       </plugin>
diff --git a/src/test/plugin-configs/useFile-plugin-config.xml b/src/test/plugin-configs/useFile-plugin-config.xml
index 49bc07e..b488964 100644
--- a/src/test/plugin-configs/useFile-plugin-config.xml
+++ b/src/test/plugin-configs/useFile-plugin-config.xml
@@ -42,6 +42,7 @@ under the License.
           <consoleOutput>true</consoleOutput>
           <linkXRef>true</linkXRef>
           <xrefLocation>${basedir}/target/site/xref</xrefLocation>
+          <xrefTestLocation>${basedir}/target/site/xref-test</xrefTestLocation>
           <useFile>${basedir}/target/test-harness/checkstyle/useFile/checkstyle-output.txt</useFile>
           <encoding>UTF-8</encoding>
         </configuration>