how to generate html report if my Junit is not run

2019-04-02 10:37发布

问题:

I worked on a project in which testclasses are run via JunitCore.run(testClasses) not via Ant because I have to run the project even with no ANT framework (so no Testng for the same reason). But I still need to create html and xml reports same as JUNIT/ANT. How to generate them in my case?

Right now I found https://github.com/barrypitman/JUnitXmlFormatter/blob/master/src/main/java/barrypitman/junitXmlFormatter/AntXmlRunListener.java may be used to generate xml report. How do I generate html similar to junit-noframes.html? Are there existing methods to convert the TESTS-TestSuites.xml to junit-noframes.html and how? if not, how to generate the html? I do not even find the standard of the html format.

回答1:

1) Write a test class

import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class MyTest{

    @Test
    public void test(){
        int i=5;
        int j=5;
        assertTrue(i==j);
    }

    @Test
    public void test2(){
        int i=5;
        int j=15;
        assertTrue(i!=j);
    }
}   

2)Create a class which extends RunListner:

import org.junit.runner.Description;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;


public class MyRunListner extends RunListener{
    private int numberOfTestClass;
    private int testExecuted;
    private int testFailed;
    private long begin;

    public MyRunListner(int numberOfTestClass){
        this.setBegin(System.currentTimeMillis());
        this.numberOfTestClass = numberOfTestClass;
    }

    public void testStarted(Description description) throws Exception{
        this.testExecuted += 1;
    }

    public void testFailure(Failure failure) throws Exception{
        this.testFailed += 1;
    }

    /**
     * @return the numberOfTestClass
     */
    public int getNumberOfTestClass(){
        return numberOfTestClass;
    }

    /**
     * @param numberOfTestClass the numberOfTestClass to set
     */
    public void setNumberOfTestClass(int numberOfTestClass){
        this.numberOfTestClass = numberOfTestClass;
    }

    /**
     * @return the testExecuted
     */
    public int getTestExecuted(){
        return testExecuted;
    }

    /**
     * @param testExecuted the testExecuted to set
     */
    public void setTestExecuted(int testExecuted){
        this.testExecuted = testExecuted;
    }

    /**
     * @return the testFailed
     */
    public int getTestFailed(){
        return testFailed;
    }

    /**
     * @param testFailed the testFailed to set
     */
    public void setTestFailed(int testFailed){
        this.testFailed = testFailed;
    }

    /**
     * @return the begin
     */
    public long getBegin(){
        return begin;
    }

    /**
     * @param begin the begin to set
     */
    public void setBegin(long begin){
        this.begin = begin;
    }
}

3) Generate the report.

import java.io.FileWriter;
import java.io.IOException;

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;


public class JUnitTest{

    public static void main(String[] args){
        JUnitTest junit = new JUnitTest();
        junit.runTest();
    }

    public void runTest(){

        try {
            String filePath = "C:/temp";
            String reportFileName = "myReport.htm";
            Class[] myTestToRunTab = {MyTest.class};
            int size = myTestToRunTab.length;
            JUnitCore jUnitCore = new JUnitCore();
            jUnitCore.addListener(new MyRunListner(myTestToRunTab.length));
            Result result = jUnitCore.run(myTestToRunTab);
            StringBuffer myContent = getResultContent(result,size);
            writeReportFile(filePath+"/"+reportFileName,myContent);

        }
        catch (Exception e) {
        }
    }

    private StringBuffer getResultContent(Result result,int numberOfTestFiles){
        int numberOfTest = result.getRunCount();
        int numberOfTestFail = result.getFailureCount();
        int numberOfTestIgnore = result.getIgnoreCount();
        int numberOfTestSuccess = numberOfTest-numberOfTestFail-numberOfTestIgnore;
        int successPercent = (numberOfTest!=0) ? numberOfTestSuccess*100/numberOfTest : 0;
        double time = result.getRunTime();
        StringBuffer myContent = new StringBuffer("<h1>Junit Report</h1><h2>Result</h2><table border=\"1\"><tr><th>Test Files</th><th>Tests</th><th>Success</th>");
        if ((numberOfTestFail>0)||(numberOfTestIgnore>0)) {
            myContent.append("<th>Failure</th><th>Ignore</th>");
        }

        myContent.append("<th>Test Time (seconds)</th></tr><tr");
        if ((numberOfTestFail>0)||(numberOfTestIgnore>0)) {
            myContent.append(" style=\"color:red\" ");
        }
        myContent.append("><td>");
        myContent.append(numberOfTestFiles);
        myContent.append("</td><td>");
        myContent.append(numberOfTest);
        myContent.append("</td><td>");
        myContent.append(successPercent);
        myContent.append("%</td><td>");
        if ((numberOfTestFail>0)||(numberOfTestIgnore>0)) {
            myContent.append(numberOfTestFail);
            myContent.append("</td><td>");
            myContent.append(numberOfTestIgnore);
            myContent.append("</td><td>");
        }

        myContent.append(Double.valueOf(time/1000.0D));
        myContent.append("</td></tr></table>");
        return myContent;
    }

    private void writeReportFile(String fileName,StringBuffer reportContent){
        FileWriter myFileWriter = null;
        try {
            myFileWriter = new FileWriter(fileName);
            myFileWriter.write(reportContent.toString());
        }
        catch (IOException e) {

        }
        finally {
            if (myFileWriter!=null) {
                try {
                    myFileWriter.close();
                }
                catch (IOException e) {

                }
            }
        }
    }

}

4) Finally our report is ready

I hope it helps you!



回答2:

In fact I solved the problem myself in this way:
First I use https://code.google.com/p/reporting-junit-runner/source/browse/trunk/src/junitrunner/XmlWritingListener.java?spec=svn2&r=2 to create TESTS-*.xml Then I write the following code myself to create TEST-SUITE.xml and junit-noframes.html. The idea is make use of API of ANT to create reports without really running test. so far the solution works for me.

      Project project = new Project();
      //a fake project feeding to ANT API so that latter not complain 
      project.setName("dummy"); 
      project.init();

      FileSet fs = new FileSet();
      fs.setDir(new File(reportToDir));
      fs.createInclude().setName("TEST-*.xml");
      XMLResultAggregator aggregator = new XMLResultAggregator();
      aggregator.setProject(project);
      aggregator.addFileSet(fs);
      aggregator.setTodir(new File(reportToDir));
      //create TESTS-TestSuites.xml
      AggregateTransformer transformer = aggregator.createReport(); 
      transformer.setTodir(new File(reportToDir));
      Format format = new Format();
      format.setValue(AggregateTransformer.NOFRAMES);
      transformer.setFormat(format);
      //create junit-noframe.html
      aggregator.execute();