如何生成 PDF 格式的 TestNG 报告?

发布于 2024-11-05 19:09:02 字数 181 浏览 1 评论 0原文

我只是查看来自我的测试框架的 TestNG 报告,它们都是 HTML 或 XML。有人知道如何生成PDF报告吗? (我正在使用 Maven 项目)。

从文档中,我需要实现 org.testng.IReporter,但是有人对此有任何了解吗?

干杯,

I was just looking at the TestNG reports coming from my test framework and they are all HTML or XML. Anyone know how to generate PDF reports? (I'm using a Maven project).

From the documentation, I need to implement org.testng.IReporter, but has anyone got any knowledge on that?

Cheers,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

网名女生简单气质 2024-11-12 19:09:02

有关 testng-users 邮件列表的此讨论包含一个附件这是生成 PDF 报告的记者的来源。

This discussion on the testng-users mailing-list contains an attachment which is the source of a reporter that generates PDF reports.

烟柳画桥 2024-11-12 19:09:02

我也遇到了和你一样的麻烦。
但现在我可以截屏并生成 pdf。
我用过: http://code.google.com/p/selenium-java-evidence< /a>

示例代码如下:

测试类:

public class MantisTest {

/**
 * Create a Selenium attribute
 */
static Selenium selenium = null;
/**
 * Create a SeleniumServer attribute
 */
SeleniumServer server = null;
/**
 * Create a list to put each evidence
 */
List<SeleniumEvidence> evidence = null;
/**
 * String that will be showed if a exception occurs
 */
String exception = null;

/**
 * Constructor of the class
 */
public MantisTest() {
}

/**
 * Execute all code bellow and override the setup method in JUnit test case
 */
@BeforeClass(alwaysRun = true)
public void setUp() throws Exception {

    // create a new instance of selenium to interact with the page
    selenium = new DefaultSelenium("localhost", 4444, "*firefox3",
            "http://www.mantisbt.org/");

    // create a new instance of selenium server to init the server
    server = new SeleniumServer();

    // create a new instance of the selenium evidence list
    evidence = new ArrayList<SeleniumEvidence>();

    // init the selenium server
    server.start();

    // init the selenium
    selenium.start();
}

/**
 * The test case
 * 
 * @throws Exception
 */
@Test
public void testLogin() throws Exception {

    /*
     * The code need a try-catch block to catch the evidence when a error
     * occurs
     */
    try {
        selenium.windowMaximize();
        selenium.open("/demo/login_page.php");
        //selenium.captureScreenshot("screen-shots/"
        //      + System.currentTimeMillis() + ".jpg");
        evidence.add(new SeleniumEvidence(
                "Access the first page and click in 'Login Anonysmously'",
                selenium.captureEntirePageScreenshotToString("")));
        Assert.assertEquals("Login", selenium.getText("//td[1]"));
        Assert.assertEquals(selenium.getTitle(), "MantisBT DEMO site9");
    } catch (Exception e) {
        /*
         * Here is necessary catch one evidence and the exception string
         */
        evidence.add(new SeleniumEvidence("An exception occured", selenium
                .captureEntirePageScreenshotToString("screen-shots/"
                        + System.currentTimeMillis() + ".png")));
        exception = e.fillInStackTrace().getMessage();
    } finally {
        // In the finally block the report is created
        GenerateEvidenceReport.generatePDFEvidence(evidence,
                "ExampleEvidence", "Elias Nogueira",
                "Selenium Evidence Test", exception);
    }
}

/**
 * The test case
 * 
 * @throws Exception
 */
@Test
public void testLogin2() throws Exception {

    /*
     * The code need a try-catch block to catch the evidence when a error
     * occurs
     */
    try {
        selenium.windowMaximize();
        selenium.open("/demo/login_page.php");
        //selenium.captureScreenshot("screen-shots/"
        //      + System.currentTimeMillis() + ".jpg");
        evidence.add(new SeleniumEvidence(
                "Access the first page and click in 'Login Anonysmously'",
                selenium.captureEntirePageScreenshotToString("")));
        Assert.assertEquals("Login", selenium.getText("//td[1]"));
        Assert.assertEquals(selenium.getTitle(), "MantisBT DEMO site9");
    } catch (Exception e) {
        /*
         * Here is necessary catch one evidence and the exception string
         */
        evidence.add(new SeleniumEvidence("An exception occured", selenium
                .captureEntirePageScreenshotToString("screen-shots/"
                        + System.currentTimeMillis() + ".png")));
        exception = e.fillInStackTrace().getMessage();
    } finally {
        // In the finally block the report is created
        GenerateEvidenceReport.generatePDFEvidence(evidence,
                "ExampleEvidence", "Elias Nogueira",
                "Selenium Evidence Test", exception);
    }
}

/**
 * Execute all the code below when test case get completed
 */
@AfterClass(alwaysRun = true)
public void tearDown() {
    selenium.stop();
    server.stop();
}

}

testng.xml

<suite verbose="0" name="Default suite">
<listeners>
    <listener class-name="com.googlecode.seleniumjavaevidence.test.ReportListener" />
</listeners>

<test verbose="2" name="Default test" preserve-order="false">
    <classes>
        <class name="com.googlecode.seleniumjavaevidence.test.MantisTest" />
    </classes>
</test>
</suite>

监听类

package com.googlecode.seleniumjavaevidence.test;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.TestListenerAdapter;
import org.testng.internal.Utils;
import org.testng.reporters.HtmlHelper;


/**
 * This class implements an HTML reporter for individual tests.
 */
public class ReportListener extends TestListenerAdapter {
  private static final Comparator<ITestResult> NAME_COMPARATOR= new NameComparator();
  private static final Comparator<ITestResult> CONFIGURATION_COMPARATOR= new ConfigurationComparator();

  private ITestContext m_testContext = null;

  private File file = new File("screen-shots");

    @Override
    public void onTestFailure(ITestResult result) {
        Reporter.setCurrentTestResult(result);
        System.out.println(file.getAbsolutePath());
        Reporter.log("123456789");
        Reporter
                .log("<a href=\"../../screen-shots/failure/"+ result.getName() + ".png\"><img src=\"../../screen-shots/failure/"+ result.getName() + ".png\" alt=\"Selenium Screenshot\" title=\"Selenium Screenshot\" width=\"200\" height=\"200\"><br></a>");
        Reporter.log("987654321");
        // Reporter.log("screenshot saved at " + file.getAbsolutePath()
        // + "\\reports\\" + result.getName() + ".jpg");
        // Reporter.log("<a href='"+file.getAbsolutePath() +"\\failure\\"+
        // result.getName() + ".jpg' hight='100' width='100'/> </a>");
        MantisTest.selenium.captureScreenshot(file.getAbsolutePath()
                + "\\failure\\" + result.getName() + ".png");
        Reporter.setCurrentTestResult(null);
    }

  @Override
  public void onStart(ITestContext context) {
    m_testContext = context;
  }

  @Override
  public void onFinish(ITestContext context) {
    generateLog(m_testContext, 
                null /* host */,
                m_testContext.getOutputDirectory(),
                getConfigurationFailures(),
                getConfigurationSkips(),
                getPassedTests(), 
                getFailedTests(),
                getSkippedTests(), 
                getFailedButWithinSuccessPercentageTests());
  }

  private static String getOutputFile(ITestContext context) {
    return context.getName() + ".html";
  }

  public static void generateTable(StringBuffer sb, String title, 
      Collection<ITestResult> tests, String cssClass, Comparator<ITestResult> comparator)
  {
    sb.append("<table width='100%' border='1' class='invocation-").append(cssClass).append("'>\n")
      .append("<tr><td colspan='4' align='center'><b>").append(title).append("</b></td></tr>\n")    
      .append("<tr>")
      .append("<td><b>Test method</b></td>\n")
      .append("<td><b>Instance</b></td>\n")
      .append("<td width=\"10%\"><b>Time (seconds)</b></td>\n")
      .append("<td width=\"30%\"><b>Exception</b></td>\n")
      .append("</tr>\n");

    if (tests instanceof List) {
      Collections.sort((List<ITestResult>) tests, comparator);
    }

    // User output?
    String id = "";
    Throwable tw = null;

    for (ITestResult tr : tests) {
      sb.append("<tr>\n");

      // Test method
      ITestNGMethod method = tr.getMethod();

      sb.append("<td title='").append(tr.getTestClass().getName()).append(".")
        .append(tr.getName())
        .append("()'>")
        .append("<b>").append(tr.getName()).append("</b>");

      // Test name
      String testName = method.getTestClass().getTestName();
      if (testName != null) {
        sb.append("<br>").append("Test class:" + testName);
      }

      // Method description
      if (! Utils.isStringEmpty(method.getDescription())) {
        sb.append("<br>").append("Test method:").append(method.getDescription());
      }

      Object[] parameters = tr.getParameters();
      if (parameters != null && parameters.length > 0) {
        sb.append("<br>Parameters: ");
        for (int j = 0; j < parameters.length; j++) {
          if (j > 0) sb.append(", ");
          sb.append(parameters[j] == null ? "null" : parameters[j].toString());
        }
      }

      //
      // Output from the method, created by the user calling Reporter.log()
      //
      {
        List<String> output = Reporter.getOutput(tr);
        if (null != output && output.size() > 0) {
          sb.append("<br/>");
          // Method name
          String divId = "Output-" + tr.hashCode();
          sb.append("\n<a href=\"#").append(divId).append("\"")
            .append(" onClick='toggleBox(\"").append(divId).append("\", this, \"Show output\", \"Hide output\");'>")
            .append("Show output</a>\n")
            .append("\n<a href=\"#").append(divId).append("\"")
            .append(" onClick=\"toggleAllBoxes();\">Show all outputs</a>\n")
            ;

          // Method output
          sb.append("<div class='log' id=\"").append(divId).append("\">\n");
          for (String s : output) {
            sb.append(s).append("<br/>\n");
          }
          sb.append("</div>\n");
        }
      }

      sb.append("</td>\n");

      // Instance
      Object instance = tr.getInstance();
      String instanceString = instance != null ? instance.toString() : " ";
      sb.append("<td>").append(instance).append("</td>");

      // Time
      long time = (tr.getEndMillis() - tr.getStartMillis()) / 1000;
      String strTime = new Long(time).toString();
      sb.append("<td>").append(strTime).append("</td>\n");

      // Exception
      tw = tr.getThrowable();
      String stackTrace = "";
      String fullStackTrace = "";

      id = "stack-trace" + tr.hashCode();
      sb.append("<td>");

      if (null != tw) {
        String[] stackTraces = Utils.stackTrace(tw, true);
        fullStackTrace = stackTraces[1];
        stackTrace = "<div><pre>" + stackTraces[0]  + "</pre></div>";

        sb.append(stackTrace);
        // JavaScript link
        sb.append("<a href='#' onClick='toggleBox(\"")
        .append(id).append("\", this, \"Click to show all stack frames\", \"Click to hide stack frames\")'>")
        .append("Click to show all stack frames").append("</a>\n")
        .append("<div class='stack-trace' id='" + id + "'>")
        .append("<pre>" + fullStackTrace + "</pre>")
        .append("</div>")
        ;
      }

      sb.append("</td>\n").append("</tr>\n");
    }

    sb.append("</table><p>\n");

  }

  private static String arrayToString(String[] array) {
    StringBuffer result = new StringBuffer("");
    for (int i = 0; i < array.length; i++) {
      result.append(array[i]).append(" ");
    }

    return result.toString();
  }

  private static String HEAD =
    "\n<style type=\"text/css\">\n" +
    ".log { display: none;} \n" +
    ".stack-trace { display: none;} \n" +
    "</style>\n" +
    "<script type=\"text/javascript\">\n" +
      "<!--\n" +
      "function flip(e) {\n" +
      "  current = e.style.display;\n" +
      "  if (current == 'block') {\n" +
      "    e.style.display = 'none';\n" +
      "    return 0;\n" +
      "  }\n" +
      "  else {\n" +
      "    e.style.display = 'block';\n" +
      "    return 1;\n" +
      "  }\n" +
      "}\n" +
      "\n" +
      "function toggleBox(szDivId, elem, msg1, msg2)\n" +
      "{\n" +
      "  var res = -1;" +
      "  if (document.getElementById) {\n" +
      "    res = flip(document.getElementById(szDivId));\n" +
      "  }\n" +
      "  else if (document.all) {\n" +
      "    // this is the way old msie versions work\n" +
      "    res = flip(document.all[szDivId]);\n" +
      "  }\n" +
      "  if(elem) {\n" +
      "    if(res == 0) elem.innerHTML = msg1; else elem.innerHTML = msg2;\n" + 
      "  }\n" +
      "\n" +
      "}\n" +
      "\n" +
      "function toggleAllBoxes() {\n" +
      "  if (document.getElementsByTagName) {\n" +
      "    d = document.getElementsByTagName('div');\n" +
      "    for (i = 0; i < d.length; i++) {\n" +
      "      if (d[i].className == 'log') {\n" +
      "        flip(d[i]);\n" +
      "      }\n" +
      "    }\n" +
      "  }\n" +
      "}\n" +
      "\n" +
      "// -->\n" +
      "</script>\n" +
      "\n";

  public static void generateLog(ITestContext testContext, 
      String host,
      String outputDirectory,
      Collection<ITestResult> failedConfs,
      Collection<ITestResult> skippedConfs,
      Collection<ITestResult> passedTests, 
      Collection<ITestResult> failedTests,
      Collection<ITestResult> skippedTests, 
      Collection<ITestResult> percentageTests)
  {
    StringBuffer sb = new StringBuffer();
    sb.append("<html>\n<head>\n")
      .append("<title>TestNG:  ").append(testContext.getName()).append("</title>\n")
      .append(HtmlHelper.getCssString())
      .append(HEAD)
      .append("</head>\n")
      .append("<body>\n");

    Date startDate = testContext.getStartDate();
    Date endDate = testContext.getEndDate();
    long duration = (endDate.getTime() - startDate.getTime()) / 1000;
    int passed = 
      testContext.getPassedTests().size() +
      testContext.getFailedButWithinSuccessPercentageTests().size();
    int failed = testContext.getFailedTests().size();
    int skipped = testContext.getSkippedTests().size();
    String hostLine = Utils.isStringEmpty(host) ? "" : "<tr><td>Remote host:</td><td>" + host
        + "</td>\n</tr>";

    sb
    .append("<h2 align='center'>").append(testContext.getName()).append("</h2>")
    .append("<table border='1' align=\"center\">\n")
    .append("<tr>\n")
//    .append("<td>Property file:</td><td>").append(m_testRunner.getPropertyFileName()).append("</td>\n")
//    .append("</tr><tr>\n")
    .append("<td>Tests passed/Failed/Skipped:</td><td>").append(passed).append("/").append(failed).append("/").append(skipped).append("</td>\n")
    .append("</tr><tr>\n")
    .append("<td>Started on:</td><td>").append(testContext.getStartDate().toString()).append("</td>\n")
    .append("</tr>\n")
    .append(hostLine)
    .append("<tr><td>Total time:</td><td>").append(duration).append(" seconds (").append(endDate.getTime() - startDate.getTime())
      .append(" ms)</td>\n")
    .append("</tr><tr>\n")
    .append("<td>Included groups:</td><td>").append(arrayToString(testContext.getIncludedGroups())).append("</td>\n")
    .append("</tr><tr>\n")
    .append("<td>Excluded groups:</td><td>").append(arrayToString(testContext.getExcludedGroups())).append("</td>\n")
    .append("</tr>\n")
    .append("</table><p/>\n")
    ;

    sb.append("<small><i>*****Changed*******(Hover the method name to see the test class name)</i></small><p/>\n");
    if (testContext.getFailedConfigurations().size() > 0) {
      generateTable(sb, "FAILED CONFIGURATIONS", failedConfs, "failed", CONFIGURATION_COMPARATOR);
    }
    if (testContext.getSkippedConfigurations().size() > 0) {
      generateTable(sb, "SKIPPED CONFIGURATIONS", skippedConfs, "skipped", CONFIGURATION_COMPARATOR);
    }
    if (failed > 0) {
      generateTable(sb, "FAILED TESTS", testContext.getFailedTests().getAllResults(), "failed", NAME_COMPARATOR);
    }
    if (testContext.getFailedButWithinSuccessPercentageTests().size() > 0) {
      generateTable(sb, "FAILED TESTS BUT WITHIN SUCCESS PERCENTAGE",
          percentageTests, "percent", NAME_COMPARATOR);
    }
    if (testContext.getPassedTests().size() > 0) {
      generateTable(sb, "PASSED TESTS", passedTests, "passed", NAME_COMPARATOR);
    }
    if (skippedTests.size() > 0) {
      generateTable(sb, "SKIPPED TESTS", skippedTests, "skipped", NAME_COMPARATOR);
    }

    sb.append("</body>\n</html>");

    Utils.writeFile(outputDirectory, getOutputFile(testContext), sb.toString());
  }

  private static void ppp(String s) {
    System.out.println("[TestHTMLReporter] " + s);
  }

  private static class NameComparator implements Comparator<ITestResult> {
    public int compare(ITestResult o1, ITestResult o2) {
      String c1 = o1.getMethod().getMethodName();
      String c2 = o2.getMethod().getMethodName();
      return c1.compareTo(c2);
    }

  }

  private static class ConfigurationComparator implements Comparator<ITestResult> {
    public int compare(ITestResult o1, ITestResult o2) {
      ITestNGMethod tm1= o1.getMethod();
      ITestNGMethod tm2= o2.getMethod();
      return annotationValue(tm2) - annotationValue(tm1);
    }

    private static int annotationValue(ITestNGMethod method) {
      if(method.isBeforeSuiteConfiguration()) {
        return 10;
      }
      if(method.isBeforeTestConfiguration()) {
        return 9;
      }
      if(method.isBeforeClassConfiguration()) {
        return 8;
      }
      if(method.isBeforeGroupsConfiguration()) {
        return 7;
      }
      if(method.isBeforeMethodConfiguration()) {
        return 6;
      }
      if(method.isAfterMethodConfiguration()) {
        return 5;
      }
      if(method.isAfterGroupsConfiguration()) {
        return 4;
      }
      if(method.isAfterClassConfiguration()) {
        return 3;
      }
      if(method.isAfterTestConfiguration()) {
        return 2;
      }
      if(method.isAfterSuiteConfiguration()) {
        return 1;
      }

      return 0;
    }
  }

}

I was having the same trouble as yours.
But now I am able to take screen shots and generate pdfs.
I used: http://code.google.com/p/selenium-java-evidence

The sample code is like this:

Test Class:

public class MantisTest {

/**
 * Create a Selenium attribute
 */
static Selenium selenium = null;
/**
 * Create a SeleniumServer attribute
 */
SeleniumServer server = null;
/**
 * Create a list to put each evidence
 */
List<SeleniumEvidence> evidence = null;
/**
 * String that will be showed if a exception occurs
 */
String exception = null;

/**
 * Constructor of the class
 */
public MantisTest() {
}

/**
 * Execute all code bellow and override the setup method in JUnit test case
 */
@BeforeClass(alwaysRun = true)
public void setUp() throws Exception {

    // create a new instance of selenium to interact with the page
    selenium = new DefaultSelenium("localhost", 4444, "*firefox3",
            "http://www.mantisbt.org/");

    // create a new instance of selenium server to init the server
    server = new SeleniumServer();

    // create a new instance of the selenium evidence list
    evidence = new ArrayList<SeleniumEvidence>();

    // init the selenium server
    server.start();

    // init the selenium
    selenium.start();
}

/**
 * The test case
 * 
 * @throws Exception
 */
@Test
public void testLogin() throws Exception {

    /*
     * The code need a try-catch block to catch the evidence when a error
     * occurs
     */
    try {
        selenium.windowMaximize();
        selenium.open("/demo/login_page.php");
        //selenium.captureScreenshot("screen-shots/"
        //      + System.currentTimeMillis() + ".jpg");
        evidence.add(new SeleniumEvidence(
                "Access the first page and click in 'Login Anonysmously'",
                selenium.captureEntirePageScreenshotToString("")));
        Assert.assertEquals("Login", selenium.getText("//td[1]"));
        Assert.assertEquals(selenium.getTitle(), "MantisBT DEMO site9");
    } catch (Exception e) {
        /*
         * Here is necessary catch one evidence and the exception string
         */
        evidence.add(new SeleniumEvidence("An exception occured", selenium
                .captureEntirePageScreenshotToString("screen-shots/"
                        + System.currentTimeMillis() + ".png")));
        exception = e.fillInStackTrace().getMessage();
    } finally {
        // In the finally block the report is created
        GenerateEvidenceReport.generatePDFEvidence(evidence,
                "ExampleEvidence", "Elias Nogueira",
                "Selenium Evidence Test", exception);
    }
}

/**
 * The test case
 * 
 * @throws Exception
 */
@Test
public void testLogin2() throws Exception {

    /*
     * The code need a try-catch block to catch the evidence when a error
     * occurs
     */
    try {
        selenium.windowMaximize();
        selenium.open("/demo/login_page.php");
        //selenium.captureScreenshot("screen-shots/"
        //      + System.currentTimeMillis() + ".jpg");
        evidence.add(new SeleniumEvidence(
                "Access the first page and click in 'Login Anonysmously'",
                selenium.captureEntirePageScreenshotToString("")));
        Assert.assertEquals("Login", selenium.getText("//td[1]"));
        Assert.assertEquals(selenium.getTitle(), "MantisBT DEMO site9");
    } catch (Exception e) {
        /*
         * Here is necessary catch one evidence and the exception string
         */
        evidence.add(new SeleniumEvidence("An exception occured", selenium
                .captureEntirePageScreenshotToString("screen-shots/"
                        + System.currentTimeMillis() + ".png")));
        exception = e.fillInStackTrace().getMessage();
    } finally {
        // In the finally block the report is created
        GenerateEvidenceReport.generatePDFEvidence(evidence,
                "ExampleEvidence", "Elias Nogueira",
                "Selenium Evidence Test", exception);
    }
}

/**
 * Execute all the code below when test case get completed
 */
@AfterClass(alwaysRun = true)
public void tearDown() {
    selenium.stop();
    server.stop();
}

}

testng.xml

<suite verbose="0" name="Default suite">
<listeners>
    <listener class-name="com.googlecode.seleniumjavaevidence.test.ReportListener" />
</listeners>

<test verbose="2" name="Default test" preserve-order="false">
    <classes>
        <class name="com.googlecode.seleniumjavaevidence.test.MantisTest" />
    </classes>
</test>
</suite>

Listener class

package com.googlecode.seleniumjavaevidence.test;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.TestListenerAdapter;
import org.testng.internal.Utils;
import org.testng.reporters.HtmlHelper;


/**
 * This class implements an HTML reporter for individual tests.
 */
public class ReportListener extends TestListenerAdapter {
  private static final Comparator<ITestResult> NAME_COMPARATOR= new NameComparator();
  private static final Comparator<ITestResult> CONFIGURATION_COMPARATOR= new ConfigurationComparator();

  private ITestContext m_testContext = null;

  private File file = new File("screen-shots");

    @Override
    public void onTestFailure(ITestResult result) {
        Reporter.setCurrentTestResult(result);
        System.out.println(file.getAbsolutePath());
        Reporter.log("123456789");
        Reporter
                .log("<a href=\"../../screen-shots/failure/"+ result.getName() + ".png\"><img src=\"../../screen-shots/failure/"+ result.getName() + ".png\" alt=\"Selenium Screenshot\" title=\"Selenium Screenshot\" width=\"200\" height=\"200\"><br></a>");
        Reporter.log("987654321");
        // Reporter.log("screenshot saved at " + file.getAbsolutePath()
        // + "\\reports\\" + result.getName() + ".jpg");
        // Reporter.log("<a href='"+file.getAbsolutePath() +"\\failure\\"+
        // result.getName() + ".jpg' hight='100' width='100'/> </a>");
        MantisTest.selenium.captureScreenshot(file.getAbsolutePath()
                + "\\failure\\" + result.getName() + ".png");
        Reporter.setCurrentTestResult(null);
    }

  @Override
  public void onStart(ITestContext context) {
    m_testContext = context;
  }

  @Override
  public void onFinish(ITestContext context) {
    generateLog(m_testContext, 
                null /* host */,
                m_testContext.getOutputDirectory(),
                getConfigurationFailures(),
                getConfigurationSkips(),
                getPassedTests(), 
                getFailedTests(),
                getSkippedTests(), 
                getFailedButWithinSuccessPercentageTests());
  }

  private static String getOutputFile(ITestContext context) {
    return context.getName() + ".html";
  }

  public static void generateTable(StringBuffer sb, String title, 
      Collection<ITestResult> tests, String cssClass, Comparator<ITestResult> comparator)
  {
    sb.append("<table width='100%' border='1' class='invocation-").append(cssClass).append("'>\n")
      .append("<tr><td colspan='4' align='center'><b>").append(title).append("</b></td></tr>\n")    
      .append("<tr>")
      .append("<td><b>Test method</b></td>\n")
      .append("<td><b>Instance</b></td>\n")
      .append("<td width=\"10%\"><b>Time (seconds)</b></td>\n")
      .append("<td width=\"30%\"><b>Exception</b></td>\n")
      .append("</tr>\n");

    if (tests instanceof List) {
      Collections.sort((List<ITestResult>) tests, comparator);
    }

    // User output?
    String id = "";
    Throwable tw = null;

    for (ITestResult tr : tests) {
      sb.append("<tr>\n");

      // Test method
      ITestNGMethod method = tr.getMethod();

      sb.append("<td title='").append(tr.getTestClass().getName()).append(".")
        .append(tr.getName())
        .append("()'>")
        .append("<b>").append(tr.getName()).append("</b>");

      // Test name
      String testName = method.getTestClass().getTestName();
      if (testName != null) {
        sb.append("<br>").append("Test class:" + testName);
      }

      // Method description
      if (! Utils.isStringEmpty(method.getDescription())) {
        sb.append("<br>").append("Test method:").append(method.getDescription());
      }

      Object[] parameters = tr.getParameters();
      if (parameters != null && parameters.length > 0) {
        sb.append("<br>Parameters: ");
        for (int j = 0; j < parameters.length; j++) {
          if (j > 0) sb.append(", ");
          sb.append(parameters[j] == null ? "null" : parameters[j].toString());
        }
      }

      //
      // Output from the method, created by the user calling Reporter.log()
      //
      {
        List<String> output = Reporter.getOutput(tr);
        if (null != output && output.size() > 0) {
          sb.append("<br/>");
          // Method name
          String divId = "Output-" + tr.hashCode();
          sb.append("\n<a href=\"#").append(divId).append("\"")
            .append(" onClick='toggleBox(\"").append(divId).append("\", this, \"Show output\", \"Hide output\");'>")
            .append("Show output</a>\n")
            .append("\n<a href=\"#").append(divId).append("\"")
            .append(" onClick=\"toggleAllBoxes();\">Show all outputs</a>\n")
            ;

          // Method output
          sb.append("<div class='log' id=\"").append(divId).append("\">\n");
          for (String s : output) {
            sb.append(s).append("<br/>\n");
          }
          sb.append("</div>\n");
        }
      }

      sb.append("</td>\n");

      // Instance
      Object instance = tr.getInstance();
      String instanceString = instance != null ? instance.toString() : " ";
      sb.append("<td>").append(instance).append("</td>");

      // Time
      long time = (tr.getEndMillis() - tr.getStartMillis()) / 1000;
      String strTime = new Long(time).toString();
      sb.append("<td>").append(strTime).append("</td>\n");

      // Exception
      tw = tr.getThrowable();
      String stackTrace = "";
      String fullStackTrace = "";

      id = "stack-trace" + tr.hashCode();
      sb.append("<td>");

      if (null != tw) {
        String[] stackTraces = Utils.stackTrace(tw, true);
        fullStackTrace = stackTraces[1];
        stackTrace = "<div><pre>" + stackTraces[0]  + "</pre></div>";

        sb.append(stackTrace);
        // JavaScript link
        sb.append("<a href='#' onClick='toggleBox(\"")
        .append(id).append("\", this, \"Click to show all stack frames\", \"Click to hide stack frames\")'>")
        .append("Click to show all stack frames").append("</a>\n")
        .append("<div class='stack-trace' id='" + id + "'>")
        .append("<pre>" + fullStackTrace + "</pre>")
        .append("</div>")
        ;
      }

      sb.append("</td>\n").append("</tr>\n");
    }

    sb.append("</table><p>\n");

  }

  private static String arrayToString(String[] array) {
    StringBuffer result = new StringBuffer("");
    for (int i = 0; i < array.length; i++) {
      result.append(array[i]).append(" ");
    }

    return result.toString();
  }

  private static String HEAD =
    "\n<style type=\"text/css\">\n" +
    ".log { display: none;} \n" +
    ".stack-trace { display: none;} \n" +
    "</style>\n" +
    "<script type=\"text/javascript\">\n" +
      "<!--\n" +
      "function flip(e) {\n" +
      "  current = e.style.display;\n" +
      "  if (current == 'block') {\n" +
      "    e.style.display = 'none';\n" +
      "    return 0;\n" +
      "  }\n" +
      "  else {\n" +
      "    e.style.display = 'block';\n" +
      "    return 1;\n" +
      "  }\n" +
      "}\n" +
      "\n" +
      "function toggleBox(szDivId, elem, msg1, msg2)\n" +
      "{\n" +
      "  var res = -1;" +
      "  if (document.getElementById) {\n" +
      "    res = flip(document.getElementById(szDivId));\n" +
      "  }\n" +
      "  else if (document.all) {\n" +
      "    // this is the way old msie versions work\n" +
      "    res = flip(document.all[szDivId]);\n" +
      "  }\n" +
      "  if(elem) {\n" +
      "    if(res == 0) elem.innerHTML = msg1; else elem.innerHTML = msg2;\n" + 
      "  }\n" +
      "\n" +
      "}\n" +
      "\n" +
      "function toggleAllBoxes() {\n" +
      "  if (document.getElementsByTagName) {\n" +
      "    d = document.getElementsByTagName('div');\n" +
      "    for (i = 0; i < d.length; i++) {\n" +
      "      if (d[i].className == 'log') {\n" +
      "        flip(d[i]);\n" +
      "      }\n" +
      "    }\n" +
      "  }\n" +
      "}\n" +
      "\n" +
      "// -->\n" +
      "</script>\n" +
      "\n";

  public static void generateLog(ITestContext testContext, 
      String host,
      String outputDirectory,
      Collection<ITestResult> failedConfs,
      Collection<ITestResult> skippedConfs,
      Collection<ITestResult> passedTests, 
      Collection<ITestResult> failedTests,
      Collection<ITestResult> skippedTests, 
      Collection<ITestResult> percentageTests)
  {
    StringBuffer sb = new StringBuffer();
    sb.append("<html>\n<head>\n")
      .append("<title>TestNG:  ").append(testContext.getName()).append("</title>\n")
      .append(HtmlHelper.getCssString())
      .append(HEAD)
      .append("</head>\n")
      .append("<body>\n");

    Date startDate = testContext.getStartDate();
    Date endDate = testContext.getEndDate();
    long duration = (endDate.getTime() - startDate.getTime()) / 1000;
    int passed = 
      testContext.getPassedTests().size() +
      testContext.getFailedButWithinSuccessPercentageTests().size();
    int failed = testContext.getFailedTests().size();
    int skipped = testContext.getSkippedTests().size();
    String hostLine = Utils.isStringEmpty(host) ? "" : "<tr><td>Remote host:</td><td>" + host
        + "</td>\n</tr>";

    sb
    .append("<h2 align='center'>").append(testContext.getName()).append("</h2>")
    .append("<table border='1' align=\"center\">\n")
    .append("<tr>\n")
//    .append("<td>Property file:</td><td>").append(m_testRunner.getPropertyFileName()).append("</td>\n")
//    .append("</tr><tr>\n")
    .append("<td>Tests passed/Failed/Skipped:</td><td>").append(passed).append("/").append(failed).append("/").append(skipped).append("</td>\n")
    .append("</tr><tr>\n")
    .append("<td>Started on:</td><td>").append(testContext.getStartDate().toString()).append("</td>\n")
    .append("</tr>\n")
    .append(hostLine)
    .append("<tr><td>Total time:</td><td>").append(duration).append(" seconds (").append(endDate.getTime() - startDate.getTime())
      .append(" ms)</td>\n")
    .append("</tr><tr>\n")
    .append("<td>Included groups:</td><td>").append(arrayToString(testContext.getIncludedGroups())).append("</td>\n")
    .append("</tr><tr>\n")
    .append("<td>Excluded groups:</td><td>").append(arrayToString(testContext.getExcludedGroups())).append("</td>\n")
    .append("</tr>\n")
    .append("</table><p/>\n")
    ;

    sb.append("<small><i>*****Changed*******(Hover the method name to see the test class name)</i></small><p/>\n");
    if (testContext.getFailedConfigurations().size() > 0) {
      generateTable(sb, "FAILED CONFIGURATIONS", failedConfs, "failed", CONFIGURATION_COMPARATOR);
    }
    if (testContext.getSkippedConfigurations().size() > 0) {
      generateTable(sb, "SKIPPED CONFIGURATIONS", skippedConfs, "skipped", CONFIGURATION_COMPARATOR);
    }
    if (failed > 0) {
      generateTable(sb, "FAILED TESTS", testContext.getFailedTests().getAllResults(), "failed", NAME_COMPARATOR);
    }
    if (testContext.getFailedButWithinSuccessPercentageTests().size() > 0) {
      generateTable(sb, "FAILED TESTS BUT WITHIN SUCCESS PERCENTAGE",
          percentageTests, "percent", NAME_COMPARATOR);
    }
    if (testContext.getPassedTests().size() > 0) {
      generateTable(sb, "PASSED TESTS", passedTests, "passed", NAME_COMPARATOR);
    }
    if (skippedTests.size() > 0) {
      generateTable(sb, "SKIPPED TESTS", skippedTests, "skipped", NAME_COMPARATOR);
    }

    sb.append("</body>\n</html>");

    Utils.writeFile(outputDirectory, getOutputFile(testContext), sb.toString());
  }

  private static void ppp(String s) {
    System.out.println("[TestHTMLReporter] " + s);
  }

  private static class NameComparator implements Comparator<ITestResult> {
    public int compare(ITestResult o1, ITestResult o2) {
      String c1 = o1.getMethod().getMethodName();
      String c2 = o2.getMethod().getMethodName();
      return c1.compareTo(c2);
    }

  }

  private static class ConfigurationComparator implements Comparator<ITestResult> {
    public int compare(ITestResult o1, ITestResult o2) {
      ITestNGMethod tm1= o1.getMethod();
      ITestNGMethod tm2= o2.getMethod();
      return annotationValue(tm2) - annotationValue(tm1);
    }

    private static int annotationValue(ITestNGMethod method) {
      if(method.isBeforeSuiteConfiguration()) {
        return 10;
      }
      if(method.isBeforeTestConfiguration()) {
        return 9;
      }
      if(method.isBeforeClassConfiguration()) {
        return 8;
      }
      if(method.isBeforeGroupsConfiguration()) {
        return 7;
      }
      if(method.isBeforeMethodConfiguration()) {
        return 6;
      }
      if(method.isAfterMethodConfiguration()) {
        return 5;
      }
      if(method.isAfterGroupsConfiguration()) {
        return 4;
      }
      if(method.isAfterClassConfiguration()) {
        return 3;
      }
      if(method.isAfterTestConfiguration()) {
        return 2;
      }
      if(method.isAfterSuiteConfiguration()) {
        return 1;
      }

      return 0;
    }
  }

}
要走就滚别墨迹 2024-11-12 19:09:02
/*Code below modified from Thierry Janaudy code found in Cedric's reply to a question at 
  http://markmail.org/message/qc6dbd4zbd6dxgqr. This code was modified for my use in 
  WebDriver tests of a GWT application. It even adds a chart at the top to display
  success/failure/skip percent. It also shows any steps/messages you may want to send via
  the Report.log method. Add this as a listener such as in the following :

<listeners>
    <listener class-name="com.hc1.testautomation.lib.Reports"/>
    <listener class-name="com.hc1.testautomation.lib.PDFListener"/>
</listeners>    
                                                                                         */


CODE:

import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.Reporter;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.List;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;


/**
 * PDFListener
 */
public class PDFListener implements ITestListener {
    /**
     * Document
     */
    private Document document = null;

    /**
     * PdfPTables
     */
    PdfPTable statTable = null, chartTable = null, successTable = null, failTable = null, skipTable = null;

    /**
     * throwableMap
     */
    private HashMap<Integer, Throwable> throwableMap = null;

    /**
     * nbExceptions
     */
    private int nbExceptions = 0;

    /**
     * nbTotalTime
     */
    private long nbTotalTime = 0;


    FileOutputStream fop = null;
    File file;


    /**
     * PDFListener
     */
    public PDFListener() {
        log("PDFListener()");

        this.document = new Document();
        this.throwableMap = new HashMap<Integer, Throwable>();
    }


    /**
     * getResults(ITestResult result)
     */
    public ITestResult getResults(ITestResult result){
        return result;
    }



    /**
     * @see org.testng.ITestListener#onTestSuccess(com.beust.testng.ITestResult)
     */
    public void onTestSuccess(ITestResult result) {
        log("onTestSuccess("+result+")");

        if (successTable == null) {
            this.successTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});

        }

        Paragraph p = new Paragraph("PASSED TESTS  -" + result.getMethod().getDescription(), new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.GREEN);
        this.successTable.addCell(cell);

        cell = new PdfPCell(new Paragraph("Class"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Method"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Time (ms)"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Status"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);

        cell = new PdfPCell(new Paragraph(result.getTestClass().toString()));
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph(result.getMethod().toString()));
        this.successTable.addCell(cell);

        long duration = result.getEndMillis()-result.getStartMillis();
        nbTotalTime += duration;
        cell = new PdfPCell(new Paragraph("" + duration));

        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("PASSED"));
        this.successTable.addCell(cell);
        //Change messages to steps for use in GUI based WebDriver tests. 
        // The messages are sent via the org.Testng.Report.log method
        p = new Paragraph("TEST MESSAGES new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        //p = new Paragraph("" + Reporter.getOutput());
        p.setAlignment(Element.ALIGN_LEFT);
        List unorderedList = new List(List.UNORDERED);
        for(String item:Reporter.getOutput(result)){
            unorderedList.add(item);
        }
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.addElement(unorderedList);
        this.successTable.addCell(cell);
    }

    /**
     * @see com.beust.testng.ITestListener#onTestFailure(com.beust.testng.ITestResult)
     */
    public void onTestFailure(ITestResult result) {
        log("onTestFailure("+result+")");

        if (this.failTable == null) {
            this.failTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});
            this.failTable.setTotalWidth(20f);

        }

        Paragraph p = new Paragraph("FAILED TEST -" + result.getMethod().getDescription(), new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.RED);
        this.failTable.addCell(cell);

        cell = new PdfPCell(new Paragraph("Class"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Method"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Time (ms)"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Status"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);

        cell = new PdfPCell(new Paragraph(result.getTestClass().toString()));
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph(result.getMethod().toString()));
        this.failTable.addCell(cell);

        long duration = result.getEndMillis()-result.getStartMillis();
        nbTotalTime += duration;
        cell = new PdfPCell(new Paragraph("" + duration));

        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("FAILED"));
        this.failTable.addCell(cell);   
        p = new Paragraph("Exception", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);

        Throwable throwable = result.getThrowable();
        if (throwable != null) {
            this.throwableMap.put(new Integer(throwable.hashCode()), throwable);
            this.nbExceptions++;
            Paragraph excep = new Paragraph(
                    new Chunk(throwable.toString(), 
                            new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.UNDERLINE)).
                            setLocalGoto("" + throwable.hashCode()));

            p.setAlignment(Element.ALIGN_LEFT);
            cell = new PdfPCell(excep);
            cell.setColspan(4);
            this.failTable.addCell(cell);
        }

        p = new Paragraph("TEST STEPS", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        p = new Paragraph("" + Reporter.getOutput());
        p.setAlignment(Element.ALIGN_LEFT);
        List unorderedList = new List(List.UNORDERED);
        for(String item:Reporter.getOutput(result)){
            unorderedList.add(item);
        }
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.addElement(unorderedList);
        this.failTable.addCell(cell);
    }

    /**
     * @see com.beust.testng.ITestListener#onTestSkipped(com.beust.testng.ITestResult)
     */
    public void onTestSkipped(ITestResult result) {
        log("onTestSkipped("+result+")");
        if (this.skipTable == null) {
            this.skipTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});
            this.skipTable.setTotalWidth(20f);
        }

        Paragraph p = new Paragraph("SKIPPED TESTS  -" + result.getMethod().getDescription(), new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.YELLOW);
        this.skipTable.addCell(cell);

        cell = new PdfPCell(new Paragraph(result.getTestClass().toString() + "." + result.getMethod()));
        cell.setColspan(4);
        this.skipTable.addCell(cell);
    }

    /**
     * @see com.beust.testng.ITestListener#onStart(com.beust.testng.ITestContext)
     */
    public void onStart(ITestContext context) {
        log("onStart("+context+")");
        file = new File("/AutomatedTestsRunReport/SmokeTestReport.pdf");
        // if file doesn't exists, then create it
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            file.delete();
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            PdfWriter.getInstance(this.document, new FileOutputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.document.open();

        Paragraph p = new Paragraph(context.getName() + " TESTNG RESULTS",
                FontFactory.getFont(FontFactory.HELVETICA, 20, Font.BOLD, new Color(0, 0, 255)));

        try {
            this.document.add(p);
            this.document.add(new Paragraph(new Date().toString()));
        } catch (DocumentException e1) {
            e1.printStackTrace();
        }



    }

    /**
     * @see com.beust.testng.ITestListener#onFinish(com.beust.testng.ITestContext)
     */
    public void onFinish(ITestContext context) {
        log("onFinish("+context+")");

        if (statTable == null) {
            this.statTable = new PdfPTable(new float[]{.3f, .2f, .2f, .2f, .3f});   
        }

        if (chartTable == null) {
            this.chartTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});   
        }

        Paragraph p = new Paragraph("STATISTICS", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(5);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);

        cell = new PdfPCell(new Paragraph("Passed"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Skipped"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Failed"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Percent"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Total Time"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);

        int passed = context.getPassedTests().size();
        int skipped = context.getSkippedTests().size();
        int failed = context.getFailedTests().size();
        double total = passed + skipped + failed;
        double percent = ((double)passed/total) * 100;

        cell = new PdfPCell(new Paragraph("" + passed));
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("" + skipped));
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("" + failed));
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("" + percent));
        this.statTable.addCell(cell);   
        cell = new PdfPCell(new Paragraph("" + nbTotalTime));
        this.statTable.addCell(cell);       


        DefaultPieDataset dataSet = new DefaultPieDataset();
        dataSet.setValue("Failed", failed);
        dataSet.setValue("Skipped", skipped);
        dataSet.setValue("Passed", passed);
        p = new Paragraph("Data Chart", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.chartTable.addCell(cell);

    JFreeChart chart = ChartFactory.createPieChart3D(
                "Test Success Rate", dataSet, true, true, false);

    java.awt.Image originalImage = chart.createBufferedImage(500, 300);
    com.lowagie.text.Image image1 = null;
    try {
        image1 = com.lowagie.text.Image.getInstance(originalImage,Color.white);
    } catch (BadElementException e4) {
        e4.printStackTrace();
    } catch (IOException e4) {
        e4.printStackTrace();
    }

        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.addElement(image1);

        this.chartTable.addCell(cell);


        try {
            if (this.statTable != null) {
                log("Added Statistics table");
                this.statTable.setSpacingBefore(15f);
                this.document.add(this.statTable);
                this.statTable.setSpacingAfter(15f);
            }

            if (this.chartTable != null) {
                log("Added chart table");
                this.chartTable.setSpacingBefore(15f);
                this.document.add(this.chartTable);
                this.chartTable.setSpacingAfter(15f);
            }

            if (this.failTable != null) {
                log("Added fail table");
                this.failTable.setSpacingBefore(15f);
                this.document.add(this.failTable);
                this.failTable.setSpacingAfter(15f);
            }

            if (this.successTable != null) {
                log("Added success table");
                this.successTable.setSpacingBefore(15f);
                this.document.add(this.successTable);
                this.successTable.setSpacingBefore(15f);
            }

            if (this.skipTable != null) {
                log("Added skip table");
                this.skipTable.setSpacingBefore(15f);
                this.document.add(this.skipTable);
                this.skipTable.setSpacingBefore(15f);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        p = new Paragraph("EXCEPTIONS SUMMARY",
                FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
        try {
            this.document.add(p);
        } catch (DocumentException e1) {
            e1.printStackTrace();
        }

        Set<Integer> keys = this.throwableMap.keySet();

        assert keys.size() == this.nbExceptions;

        for(Integer key : keys) {
            Throwable throwable = this.throwableMap.get(key);

            Chunk chunk = new Chunk(throwable.toString(),
                    FontFactory.getFont(FontFactory.HELVETICA, 12, Font.BOLD, new Color(255, 0, 0)));
            chunk.setLocalDestination("" + key);
            Paragraph throwTitlePara = new Paragraph(chunk);
            try {
                this.document.add(throwTitlePara);
            } catch (DocumentException e3) {
                e3.printStackTrace();
            }

            StackTraceElement[] elems = throwable.getStackTrace();
            String exception = "";
            for(StackTraceElement ste : elems) {
                Paragraph throwParagraph = new Paragraph(ste.toString());
                try {
                    this.document.add(throwParagraph);
                } catch (DocumentException e2) {
                    e2.printStackTrace();
                }
            }
        }

        this.document.close();
    }

    /**
     * log
     * @param o
     */
    public static void log(Object o) {
        //System.out.println("[JyperionListener] " + o);
    }

    public void onTestStart(ITestResult result) {
        // TODO Auto-generated method stub

    }

    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
        // TODO Auto-generated method stub

    }
}
/*Code below modified from Thierry Janaudy code found in Cedric's reply to a question at 
  http://markmail.org/message/qc6dbd4zbd6dxgqr. This code was modified for my use in 
  WebDriver tests of a GWT application. It even adds a chart at the top to display
  success/failure/skip percent. It also shows any steps/messages you may want to send via
  the Report.log method. Add this as a listener such as in the following :

<listeners>
    <listener class-name="com.hc1.testautomation.lib.Reports"/>
    <listener class-name="com.hc1.testautomation.lib.PDFListener"/>
</listeners>    
                                                                                         */


CODE:

import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.Reporter;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.List;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;


/**
 * PDFListener
 */
public class PDFListener implements ITestListener {
    /**
     * Document
     */
    private Document document = null;

    /**
     * PdfPTables
     */
    PdfPTable statTable = null, chartTable = null, successTable = null, failTable = null, skipTable = null;

    /**
     * throwableMap
     */
    private HashMap<Integer, Throwable> throwableMap = null;

    /**
     * nbExceptions
     */
    private int nbExceptions = 0;

    /**
     * nbTotalTime
     */
    private long nbTotalTime = 0;


    FileOutputStream fop = null;
    File file;


    /**
     * PDFListener
     */
    public PDFListener() {
        log("PDFListener()");

        this.document = new Document();
        this.throwableMap = new HashMap<Integer, Throwable>();
    }


    /**
     * getResults(ITestResult result)
     */
    public ITestResult getResults(ITestResult result){
        return result;
    }



    /**
     * @see org.testng.ITestListener#onTestSuccess(com.beust.testng.ITestResult)
     */
    public void onTestSuccess(ITestResult result) {
        log("onTestSuccess("+result+")");

        if (successTable == null) {
            this.successTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});

        }

        Paragraph p = new Paragraph("PASSED TESTS  -" + result.getMethod().getDescription(), new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.GREEN);
        this.successTable.addCell(cell);

        cell = new PdfPCell(new Paragraph("Class"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Method"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Time (ms)"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Status"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);

        cell = new PdfPCell(new Paragraph(result.getTestClass().toString()));
        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph(result.getMethod().toString()));
        this.successTable.addCell(cell);

        long duration = result.getEndMillis()-result.getStartMillis();
        nbTotalTime += duration;
        cell = new PdfPCell(new Paragraph("" + duration));

        this.successTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("PASSED"));
        this.successTable.addCell(cell);
        //Change messages to steps for use in GUI based WebDriver tests. 
        // The messages are sent via the org.Testng.Report.log method
        p = new Paragraph("TEST MESSAGES new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.successTable.addCell(cell);
        //p = new Paragraph("" + Reporter.getOutput());
        p.setAlignment(Element.ALIGN_LEFT);
        List unorderedList = new List(List.UNORDERED);
        for(String item:Reporter.getOutput(result)){
            unorderedList.add(item);
        }
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.addElement(unorderedList);
        this.successTable.addCell(cell);
    }

    /**
     * @see com.beust.testng.ITestListener#onTestFailure(com.beust.testng.ITestResult)
     */
    public void onTestFailure(ITestResult result) {
        log("onTestFailure("+result+")");

        if (this.failTable == null) {
            this.failTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});
            this.failTable.setTotalWidth(20f);

        }

        Paragraph p = new Paragraph("FAILED TEST -" + result.getMethod().getDescription(), new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.RED);
        this.failTable.addCell(cell);

        cell = new PdfPCell(new Paragraph("Class"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Method"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Time (ms)"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Status"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);

        cell = new PdfPCell(new Paragraph(result.getTestClass().toString()));
        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph(result.getMethod().toString()));
        this.failTable.addCell(cell);

        long duration = result.getEndMillis()-result.getStartMillis();
        nbTotalTime += duration;
        cell = new PdfPCell(new Paragraph("" + duration));

        this.failTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("FAILED"));
        this.failTable.addCell(cell);   
        p = new Paragraph("Exception", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);

        Throwable throwable = result.getThrowable();
        if (throwable != null) {
            this.throwableMap.put(new Integer(throwable.hashCode()), throwable);
            this.nbExceptions++;
            Paragraph excep = new Paragraph(
                    new Chunk(throwable.toString(), 
                            new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.UNDERLINE)).
                            setLocalGoto("" + throwable.hashCode()));

            p.setAlignment(Element.ALIGN_LEFT);
            cell = new PdfPCell(excep);
            cell.setColspan(4);
            this.failTable.addCell(cell);
        }

        p = new Paragraph("TEST STEPS", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.failTable.addCell(cell);
        p = new Paragraph("" + Reporter.getOutput());
        p.setAlignment(Element.ALIGN_LEFT);
        List unorderedList = new List(List.UNORDERED);
        for(String item:Reporter.getOutput(result)){
            unorderedList.add(item);
        }
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.addElement(unorderedList);
        this.failTable.addCell(cell);
    }

    /**
     * @see com.beust.testng.ITestListener#onTestSkipped(com.beust.testng.ITestResult)
     */
    public void onTestSkipped(ITestResult result) {
        log("onTestSkipped("+result+")");
        if (this.skipTable == null) {
            this.skipTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});
            this.skipTable.setTotalWidth(20f);
        }

        Paragraph p = new Paragraph("SKIPPED TESTS  -" + result.getMethod().getDescription(), new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.YELLOW);
        this.skipTable.addCell(cell);

        cell = new PdfPCell(new Paragraph(result.getTestClass().toString() + "." + result.getMethod()));
        cell.setColspan(4);
        this.skipTable.addCell(cell);
    }

    /**
     * @see com.beust.testng.ITestListener#onStart(com.beust.testng.ITestContext)
     */
    public void onStart(ITestContext context) {
        log("onStart("+context+")");
        file = new File("/AutomatedTestsRunReport/SmokeTestReport.pdf");
        // if file doesn't exists, then create it
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            file.delete();
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            PdfWriter.getInstance(this.document, new FileOutputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.document.open();

        Paragraph p = new Paragraph(context.getName() + " TESTNG RESULTS",
                FontFactory.getFont(FontFactory.HELVETICA, 20, Font.BOLD, new Color(0, 0, 255)));

        try {
            this.document.add(p);
            this.document.add(new Paragraph(new Date().toString()));
        } catch (DocumentException e1) {
            e1.printStackTrace();
        }



    }

    /**
     * @see com.beust.testng.ITestListener#onFinish(com.beust.testng.ITestContext)
     */
    public void onFinish(ITestContext context) {
        log("onFinish("+context+")");

        if (statTable == null) {
            this.statTable = new PdfPTable(new float[]{.3f, .2f, .2f, .2f, .3f});   
        }

        if (chartTable == null) {
            this.chartTable = new PdfPTable(new float[]{.3f, .3f, .1f, .3f});   
        }

        Paragraph p = new Paragraph("STATISTICS", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        PdfPCell cell = new PdfPCell(p);
        cell.setColspan(5);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);

        cell = new PdfPCell(new Paragraph("Passed"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Skipped"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Failed"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Percent"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("Total Time"));
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.statTable.addCell(cell);

        int passed = context.getPassedTests().size();
        int skipped = context.getSkippedTests().size();
        int failed = context.getFailedTests().size();
        double total = passed + skipped + failed;
        double percent = ((double)passed/total) * 100;

        cell = new PdfPCell(new Paragraph("" + passed));
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("" + skipped));
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("" + failed));
        this.statTable.addCell(cell);
        cell = new PdfPCell(new Paragraph("" + percent));
        this.statTable.addCell(cell);   
        cell = new PdfPCell(new Paragraph("" + nbTotalTime));
        this.statTable.addCell(cell);       


        DefaultPieDataset dataSet = new DefaultPieDataset();
        dataSet.setValue("Failed", failed);
        dataSet.setValue("Skipped", skipped);
        dataSet.setValue("Passed", passed);
        p = new Paragraph("Data Chart", new Font(Font.TIMES_ROMAN, Font.DEFAULTSIZE, Font.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.setBackgroundColor(Color.LIGHT_GRAY);
        this.chartTable.addCell(cell);

    JFreeChart chart = ChartFactory.createPieChart3D(
                "Test Success Rate", dataSet, true, true, false);

    java.awt.Image originalImage = chart.createBufferedImage(500, 300);
    com.lowagie.text.Image image1 = null;
    try {
        image1 = com.lowagie.text.Image.getInstance(originalImage,Color.white);
    } catch (BadElementException e4) {
        e4.printStackTrace();
    } catch (IOException e4) {
        e4.printStackTrace();
    }

        cell = new PdfPCell(p);
        cell.setColspan(4);
        cell.addElement(image1);

        this.chartTable.addCell(cell);


        try {
            if (this.statTable != null) {
                log("Added Statistics table");
                this.statTable.setSpacingBefore(15f);
                this.document.add(this.statTable);
                this.statTable.setSpacingAfter(15f);
            }

            if (this.chartTable != null) {
                log("Added chart table");
                this.chartTable.setSpacingBefore(15f);
                this.document.add(this.chartTable);
                this.chartTable.setSpacingAfter(15f);
            }

            if (this.failTable != null) {
                log("Added fail table");
                this.failTable.setSpacingBefore(15f);
                this.document.add(this.failTable);
                this.failTable.setSpacingAfter(15f);
            }

            if (this.successTable != null) {
                log("Added success table");
                this.successTable.setSpacingBefore(15f);
                this.document.add(this.successTable);
                this.successTable.setSpacingBefore(15f);
            }

            if (this.skipTable != null) {
                log("Added skip table");
                this.skipTable.setSpacingBefore(15f);
                this.document.add(this.skipTable);
                this.skipTable.setSpacingBefore(15f);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        p = new Paragraph("EXCEPTIONS SUMMARY",
                FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
        try {
            this.document.add(p);
        } catch (DocumentException e1) {
            e1.printStackTrace();
        }

        Set<Integer> keys = this.throwableMap.keySet();

        assert keys.size() == this.nbExceptions;

        for(Integer key : keys) {
            Throwable throwable = this.throwableMap.get(key);

            Chunk chunk = new Chunk(throwable.toString(),
                    FontFactory.getFont(FontFactory.HELVETICA, 12, Font.BOLD, new Color(255, 0, 0)));
            chunk.setLocalDestination("" + key);
            Paragraph throwTitlePara = new Paragraph(chunk);
            try {
                this.document.add(throwTitlePara);
            } catch (DocumentException e3) {
                e3.printStackTrace();
            }

            StackTraceElement[] elems = throwable.getStackTrace();
            String exception = "";
            for(StackTraceElement ste : elems) {
                Paragraph throwParagraph = new Paragraph(ste.toString());
                try {
                    this.document.add(throwParagraph);
                } catch (DocumentException e2) {
                    e2.printStackTrace();
                }
            }
        }

        this.document.close();
    }

    /**
     * log
     * @param o
     */
    public static void log(Object o) {
        //System.out.println("[JyperionListener] " + o);
    }

    public void onTestStart(ITestResult result) {
        // TODO Auto-generated method stub

    }

    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
        // TODO Auto-generated method stub

    }
}
强者自强 2024-11-12 19:09:02

我发现了下面的 Github 插件,它使用简单而且非常好。希望有帮助!

https://github.com/uttesh/pdfngreport

I came across the below plugin Github which is simple to use and pretty good. Hope it helps!

https://github.com/uttesh/pdfngreport

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文