-->

Create extent reports with custom logs

2019-08-20 07:50发布

问题:

Need to print log4j logs in extent reports. HOw can I do that?

回答1:

Try to end the test and flush the report in @AfterMethod and close the report in @AfterTest Method. It worked for me. Try it Like Below Code:

@AfterMethod(alwaysRun=true)
  public void TearDown_AM(ITestResult result) throws IOException
  {
      System.out.println("@After Method");
    try
    { 
        if(result.getStatus()==ITestResult.FAILURE)
        {
            String res = captureScreenshot(Driver, result.getName());
            String image= logger.addScreenCapture(res);
            System.out.println(image);
            String TestCaseName = this.getClass().getSimpleName() + " Test Case Failure and Title/Boolean Value Failed";
            logger.log(LogStatus.FAIL, TestCaseName  + logger.addScreenCapture(res));
            //  logger.log(LogStatus.FAIL, image, this.getClass().getSimpleName() + " Test Case Failure and Title/Boolean Value Failed");
        }
        else if(result.getStatus()==ITestResult.SUCCESS)
        {
            logger.log(LogStatus.PASS, this.getClass().getSimpleName() + " Test Case Success and Title Verified"); 
        }
        else if(result.getStatus()==ITestResult.SKIP)
        {
            logger.log(LogStatus.SKIP, this.getClass().getSimpleName() + " Test Case Skipped");
        }
        report.endTest(logger);
        report.flush();

    }
    catch(Throwable t)
    {
        logger.log(LogStatus.ERROR,t.fillInStackTrace());
    }

  }

@AfterTest(alwaysRun=true)
public void AfterTest()
{
    System.out.println("@After Test");
    Driver.close();
    report.close();
}


回答2:

Firstly, create a class with a synchronized method which returns an instance of ExtentReports:

    public class ExtentManager {
    private static ExtentReports report;

    public static synchronized ExtentReports getInstance() {
        if (report == null) {
            report = new ExtentReports("MyReport.html");
        }

        return report;
    }
}

Secondly, create another class which declares only test related synchronized methods ( & of course, those method must be handled Thread wise). Code snippet:

public class ExtentTestManager {
    static Map<Integer, ExtentTest> extentTestMap = new HashMap<Integer, ExtentTest>();

    private static ExtentReports extent = ExtentManager.getInstance();

    public static synchronized ExtentTest getTest() {
        return extentTestMap.get((int) (long) (Thread.currentThread().getId()));
    }

    public static synchronized void endTest() {
        extent.endTest(extentTestMap.get((int) (long) (Thread.currentThread().getId())));
    }

    public static synchronized ExtentTest startTest(String testName) {
        return startTest(testName, "");
    }

    public static synchronized ExtentTest startTest(String testName, String desc) {
        ExtentTest test = extent.startTest(testName, desc);
        extentTestMap.put((int) (long) (Thread.currentThread().getId()), test);

        return test;
    }
}

Finally, modify your BaseClass accordingly:

public class BaseClass extends TestListenerAdapter {
    public ExtentTest testReporter;

    @BeforeMethod
    public void beforeMethod(Method m) {
        ExtentTestManager.startTest(m.getName(), "This is a simple test.");
    }

    @AfterMethod
    public void afterMethod(ITestResult result) {
        if (result.isSuccess()) {
            ExtentTestManager.getTest().log(LogStatus.PASS, "Test passed");
            ExtentTestManager.getTest().log(LogStatus.PASS, "Run from thread " + Thread.currentThread().getId());
        }
        else if (result.getStatus() == ITestResult.FAILURE) {
            ExtentTestManager.getTest().log(LogStatus.FAIL, "Test failed");
            ExtentTestManager.getTest().log(LogStatus.PASS, "Run from thread " + Thread.currentThread().getId());
        }
        else if (result.getStatus() == ITestResult.SKIP) {
            ExtentTestManager.getTest().log(LogStatus.SKIP, "Test skipped");
            ExtentTestManager.getTest().log(LogStatus.PASS, "Run from thread " + Thread.currentThread().getId());
        }
        ExtentTestManager.endTest();
        ExtentManager.getInstance().flush();
    }

    @AfterSuite
    public void afterSuite() {
        ExtentManager.getInstance().flush();
    }
}

EDIT :

Create a test class (ExampleTest.java) with your test:

public class ExampleTest extends BaseClass{
     @Test
        public void test_01(){
            Assert.assertTrue(false);
        }
        @Test
        public void test_02(){
            Assert.assertTrue(false);
        }
        @Test
        public void test_03(){
            Assert.assertTrue(true);
        }
        @Test
        public void test_04(){
            Assert.assertTrue(false);
        }
}

Required testng.xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="DemoSuite1" parallel="methods" thread-count="2">
    <test name = "Test">
        <classes>
            <class name = "com.extent.demo.ExampleTest" />
        </classes>
    </test>
</suite>