You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Extent Report时无法从其他类获取logger.info信息的技术求助

Hey there! Let's fix that Extent Report logging issue you're dealing with. It sounds like your logger.info() messages from NewTest1 and NewTest2 aren't showing up in the HTML report generated by your Reports class in the testng package. Let's walk through the common missteps and solutions step by step.

First, let's address the core problem

Extent Report doesn't automatically capture generic logger.info() calls from other classes unless you explicitly bind those logs to an active ExtentTest instance. Most folks run into issues because they either:

  • Create separate ExtentReports instances in each test class (instead of a shared singleton)
  • Use regular Java loggers instead of Extent's native logging methods
  • Fail to link test classes to the main report instance properly

Step 1: Fix your Reports class (use a singleton + ThreadLocal)

You need a centralized way to manage the ExtentReports instance and track individual test cases across threads. Here's a corrected version:

package testng;

import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.reporter.ExtentSparkReporter;

public class Reports {
    // Singleton ExtentReports instance (only one report created)
    private static ExtentReports extent;
    // ThreadLocal to handle parallel test execution safely
    private static ThreadLocal<ExtentTest> testThread = new ThreadLocal<>();

    // Initialize the report once
    public static void initReport() {
        if (extent == null) {
            ExtentSparkReporter sparkReporter = new ExtentSparkReporter("test-output/ExtentReport.html");
            extent = new ExtentReports();
            extent.attachReporter(sparkReporter);
            
            // Add system info if needed
            extent.setSystemInfo("Environment", "QA");
            extent.setSystemInfo("Tester", "Sandeep");
        }
    }

    // Create a test node for each test method
    public static void createTest(String testName) {
        ExtentTest test = extent.createTest(testName);
        testThread.set(test);
    }

    // Get the active test instance for logging
    public static ExtentTest getActiveTest() {
        return testThread.get();
    }

    // Finalize and save the report
    public static void flushReport() {
        if (extent != null) {
            extent.flush();
        }
    }
}

Step 2: Update your test classes (NewTest1/NewTest2)

Instead of using a generic logger, use the ExtentTest instance from your Reports class to log directly to the report. Here's an example for NewTest1:

package testng;

import org.testng.annotations.Test;

public class NewTest1 {

    @Test
    public void sampleTest1() {
        // Log directly to the active Extent Test node
        Reports.getActiveTest().info("Starting sampleTest1 in NewTest1");
        
        // Your test logic here...
        
        Reports.getActiveTest().pass("sampleTest1 executed successfully");
    }
}

Step 3: Add a TestNG Listener to automate lifecycle steps

To avoid manually initializing the report and creating test nodes, use an ITestListener to hook into TestNG's test lifecycle. This keeps your test classes clean:

package testng;

import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;

public class ExtentTestListener implements ITestListener {

    @Override
    public void onStart(ITestContext context) {
        // Initialize report when the test suite starts
        Reports.initReport();
    }

    @Override
    public void onTestStart(ITestResult result) {
        // Auto-create a test node using the method name
        Reports.createTest(result.getMethod().getMethodName());
    }

    @Override
    public void onTestSuccess(ITestResult result) {
        Reports.getActiveTest().pass("Test passed: " + result.getMethod().getMethodName());
    }

    @Override
    public void onTestFailure(ITestResult result) {
        Reports.getActiveTest().fail("Test failed: " + result.getMethod().getMethodName() + "\n" + result.getThrowable());
    }

    @Override
    public void onFinish(ITestContext context) {
        // Flush report when the test suite ends
        Reports.flushReport();
    }
}

Step 4: Register the listener in your testng.xml

Make sure TestNG uses your listener to tie everything together:

<suite name="Extent Report Suite">
    <listeners>
        <listener class-name="testng.ExtentTestListener"/>
    </listeners>
    <test name="Sample Tests">
        <classes>
            <class name="testng.NewTest1"/>
            <class name="testng.NewTest2"/>
        </classes>
    </test>
</suite>

If you really need to use logger.info()

If you want to keep using your existing logger (like Log4j or java.util.logging), you can bind it to Extent Report by adding a log adapter. Add this to your Reports.initReport() method:

import com.aventstack.extentreports.logging.LogConfigurator;
import java.util.logging.Logger;

// Inside initReport()
LogConfigurator logConfigurator = new LogConfigurator();
logConfigurator.setConfig("log4j2.xml"); // Path to your log config
logConfigurator.configure();

// Bind your logger to the active ExtentTest
Logger testLogger = Logger.getLogger(NewTest1.class.getName());
com.aventstack.extentreports.ExtentLogger.createLogger(testLogger, Reports.getActiveTest());

This way, your regular logger.info() calls will automatically show up in the Extent Report.

内容的提问来源于stack exchange,提问作者Sandeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:25:16