BLOG POSTS
JUnit HTML Report: How to Generate and Use

JUnit HTML Report: How to Generate and Use

JUnit HTML reports provide a visually appealing and comprehensive way to analyze test results from your Java test suites. While JUnit generates basic XML output by default, HTML reports make it much easier to share test results with stakeholders, identify failing tests quickly, and track testing trends over time. In this guide, you’ll learn how to generate professional HTML reports using various tools and plugins, configure them for different build systems, and leverage advanced features for better test reporting in your development workflow.

How JUnit HTML Reports Work

JUnit itself doesn’t generate HTML reports natively – it produces XML output that contains all the test execution data. HTML report generation happens through additional tools that parse this XML and transform it into readable HTML format. The most common approaches include:

  • Maven Surefire Report Plugin for Maven projects
  • Gradle Test Report task for Gradle builds
  • Third-party tools like ExtentReports or Allure Framework
  • CI/CD platforms with built-in report generation

The XML output contains detailed information about test execution including test names, execution times, failure messages, stack traces, and system properties. HTML report generators parse this data and create interactive dashboards showing test statistics, trends, and detailed failure analysis.

Setting Up HTML Reports with Maven

Maven’s Surefire Report Plugin is the most straightforward way to generate HTML reports for Maven projects. Here’s the complete setup:

<project>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <junit.version>5.9.2</junit.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M9</version>
                <configuration>
                    <includes>
                        <include>**/*Test.java</include>
                        <include>**/*Tests.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-report-plugin</artifactId>
                <version>3.0.0-M9</version>
                <configuration>
                    <showSuccess>true</showSuccess>
                    <outputDirectory>${project.build.directory}/surefire-reports</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
    </reporting>
</project>

Generate the reports by running these commands:

mvn clean test
mvn surefire-report:report
mvn site

The HTML reports will be available in target/site/surefire-report.html. For more advanced styling and custom templates, you can configure the plugin with additional parameters:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-report-plugin</artifactId>
    <version>3.0.0-M9</version>
    <configuration>
        <linkXRef>false</linkXRef>
        <showSuccess>true</showSuccess>
        <outputName>junit-report</outputName>
        <reportsDirectories>
            <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
        </reportsDirectories>
    </configuration>
</plugin>

Gradle HTML Report Configuration

Gradle has built-in HTML test reporting that’s enabled by default. Here’s how to customize and enhance it:

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

test {
    useJUnitPlatform()
    
    reports {
        html.enabled = true
        xml.enabled = true
        junitXml.enabled = true
        
        html {
            destination = file("$buildDir/reports/tests/html")
        }
        
        xml {
            destination = file("$buildDir/reports/tests/xml")
        }
    }
    
    testLogging {
        events "passed", "skipped", "failed"
        exceptionFormat "full"
        showStandardStreams = false
    }
    
    finalizedBy jacocoTestReport
}

Run tests and generate reports:

./gradlew clean test
# Reports available at build/reports/tests/test/index.html

For custom report styling, create a CSS file and reference it in your build script:

test {
    reports {
        html {
            enabled = true
            stylesheet = file('src/test/resources/custom-test-report.css')
        }
    }
}

Advanced HTML Reporting with ExtentReports

ExtentReports provides much more sophisticated HTML reports with charts, screenshots, and custom logging. Here’s the implementation:

<dependency>
    <groupId>com.aventstack</groupId>
    <artifactId>extentreports</artifactId>
    <version>5.0.9</version>
</dependency>

Create a test listener to integrate ExtentReports:

import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.reporter.ExtentSparkReporter;
import com.aventstack.extentreports.reporter.configuration.Theme;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestWatcher;

public class ExtentReportExtension implements TestWatcher {
    private static ExtentReports extent;
    private static ThreadLocal<ExtentTest> test = new ThreadLocal<>();
    
    static {
        ExtentSparkReporter htmlReporter = new ExtentSparkReporter("reports/extent-report.html");
        htmlReporter.config().setTheme(Theme.STANDARD);
        htmlReporter.config().setDocumentTitle("Test Execution Report");
        htmlReporter.config().setReportName("JUnit Test Results");
        
        extent = new ExtentReports();
        extent.attachReporter(htmlReporter);
        extent.setSystemInfo("Environment", "Test");
        extent.setSystemInfo("User", System.getProperty("user.name"));
    }
    
    @Override
    public void testSuccessful(ExtensionContext context) {
        test.get().pass("Test passed");
    }
    
    @Override
    public void testFailed(ExtensionContext context, Throwable cause) {
        test.get().fail(cause);
    }
    
    @Override
    public void testDisabled(ExtensionContext context, Optional<String> reason) {
        test.get().skip("Test disabled: " + reason.orElse("No reason"));
    }
    
    public static void createTest(String testName) {
        ExtentTest extentTest = extent.createTest(testName);
        test.set(extentTest);
    }
    
    public static void flushReports() {
        extent.flush();
    }
}

Use the extension in your test classes:

@ExtendWith(ExtentReportExtension.class)
public class SampleTest {
    
    @BeforeEach
    void setUp() {
        ExtentReportExtension.createTest("Sample Test Case");
    }
    
    @AfterAll
    static void tearDown() {
        ExtentReportExtension.flushReports();
    }
    
    @Test
    void testAddition() {
        int result = 2 + 3;
        assertEquals(5, result);
    }
}

Comparison of HTML Report Tools

Tool Setup Complexity Customization Features Performance Impact Best For
Maven Surefire Low Limited Basic reporting Minimal Simple Maven projects
Gradle Built-in None Medium Good visual design Minimal Gradle projects
ExtentReports Medium High Charts, screenshots, logs Low Professional reporting
Allure Framework High Very High Timeline, trends, attachments Medium Enterprise projects
JaCoCo with reports Medium Medium Coverage + test results Low Coverage analysis

Real-World Use Cases and Examples

Here are practical scenarios where HTML reports prove particularly valuable:

Continuous Integration Pipeline: When running tests on a VPS or dedicated server, HTML reports provide immediate visibility into test failures without digging through logs.

# Jenkins Pipeline Example
pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'mvn clean test'
            }
            post {
                always {
                    publishHTML([
                        allowMissing: false,
                        alwaysLinkToLastBuild: true,
                        keepAll: true,
                        reportDir: 'target/site',
                        reportFiles: 'surefire-report.html',
                        reportName: 'JUnit Report'
                    ])
                }
            }
        }
    }
}

Multi-module Maven Projects: Aggregate reports across modules for comprehensive testing overview:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-report-plugin</artifactId>
    <version>3.0.0-M9</version>
    <configuration>
        <aggregate>true</aggregate>
        <linkXRef>false</linkXRef>
    </configuration>
    <reportSets>
        <reportSet>
            <reports>
                <report>report</report>
            </reports>
        </reportSet>
        <reportSet>
            <id>aggregate</id>
            <inherited>false</inherited>
            <reports>
                <report>report</report>
            </reports>
        </reportSet>
    </reportSets>
</plugin>

Integration with Test Categories: Generate separate reports for different test types:

@ExtendWith(ExtentReportExtension.class)
@Tag("integration")
public class IntegrationTest {
    
    @Test
    @Tag("database")
    void testDatabaseConnection() {
        // Database integration test
    }
    
    @Test
    @Tag("api")
    void testApiEndpoint() {
        // API integration test
    }
}

Best Practices and Common Pitfalls

Performance Considerations: HTML report generation can slow down build times, especially with large test suites. Use these optimizations:

  • Generate reports only in CI/CD pipelines, not during local development
  • Configure parallel test execution to reduce overall runtime
  • Use build profiles to conditionally enable detailed reporting
  • Implement report archiving to prevent disk space issues
<profiles>
    <profile>
        <id>detailed-reports</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <parallel>methods</parallel>
                        <threadCount>4</threadCount>
                        <reportFormat>xml</reportFormat>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Security and Accessibility: When hosting reports on web servers, implement proper access controls:

# Apache .htaccess example for report directory
AuthType Basic
AuthName "Test Reports"
AuthUserFile /path/to/.htpasswd
Require valid-user

# Nginx configuration
location /reports {
    auth_basic "Test Reports";
    auth_basic_user_file /etc/nginx/.htpasswd;
    try_files $uri $uri/ =404;
}

Common Issues and Solutions:

  • Missing test results: Ensure XML output is generated before HTML conversion
  • Encoding problems: Set UTF-8 encoding in build configuration
  • Large report files: Implement report rotation and cleanup strategies
  • Browser compatibility: Test reports across different browsers, especially in corporate environments

Integration with Code Coverage: Combine JUnit reports with JaCoCo for comprehensive analysis:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.8</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

HTML reports transform raw test data into actionable insights that improve development workflows. Whether you’re using basic Maven/Gradle reporting or advanced tools like ExtentReports, the key is choosing the right level of detail for your team’s needs while maintaining build performance. For more information about JUnit 5 features, check the official JUnit 5 User Guide.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked