Re: [testng-users] PDF Listener for Testng

338 views
Skip to first unread message

Cédric Beust ♔

unread,
May 10, 2013, 11:42:25 AM5/10/13
to testng...@googlegroups.com
Hi Jeff,

Let me know if you ever make this available online somewhere (e.g. github) and I'll be happy to link to it from the TestNG doc.


-- 
Cédric



On Fri, May 10, 2013 at 7:26 AM, Jeff White <jeffl...@gmail.com> wrote:
I needed, recently, to add the ability to create PDF reports (rather than the emailable-report) to send to managers at the company where I work. I happened upon a discusion Cedric Beust had regarding the matter (See http://markmail.org/message/qc6dbd4zbd6dxgqr).   Thierry Janaudy wrote the code found in Cedric's reply.
 
It is great code but I needed to tweak it a little for my use in WebDriver (GUI based) tests of a GWT application. It adds a chart at the top to display success/failure/skip percent, some additional stats (See attached screenshots) . It also shows any steps/messages you may want to send via the Report.log method.
 
 
 
 
 
To use it, I added  a listener in my projects testng.xml file as follows:
 
 
My testng.xml file:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite
    name="Smoke Test Suite"
    verbose="10" >
 <listeners>
  <listener class-name="com.hc1.testautomation.lib.Reports"/>
  <listener class-name="com.hc1.testautomation.lib.PDFListener"/>
 </listeners> 
    <test name="Smoke Test Suite" >
        <classes>
            <class name="com.hc1.testautomation.tests.smoketests.SmokeTests" >
                <methods>
     <include name="CreateNewOrganization"/>
     <include name="EditOrganization"/>
     <include name="ValidateNewEditedOrganization"/>
                </methods>
            </class>
            <!-- com.hc1.testautomation.smoketests.SmokeTests -->
        </classes>
    </test>
</suite>


CODE (Also attached):

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

    }
}

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to testng...@googlegroups.com.
Visit this group at http://groups.google.com/group/testng-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Message has been deleted
Message has been deleted

Jeff White

unread,
May 13, 2013, 4:22:59 PM5/13/13
to testng...@googlegroups.com, ced...@beust.com

Hi Cedric,

 

You can find them here:  https://github.com/whitejeffreyl/JeffWhite/tree/master/testng.  And I added a Reports.java listener (as well) which programmatically controls the report process (generating the PDF) and emails out the report after it is finished.
 
 
 
Jeff

mythri sg

unread,
Dec 30, 2013, 1:53:30 AM12/30/13
to testng...@googlegroups.com
Hi Jeff, 

Thanks for sharing PDF listener :)

I need one modification in report. I want one extra column under FAILED TESTS. I tried, but I am getting java.lang.ArrayIndexOutOfBoundsException.

Please help me on this.

Thanks in advance,
Mythri
Reply all
Reply to author
Forward
0 new messages