Robotium解析xml生成html樣式的報告

第一次寫blog,一直也沒養成寫blog的好習慣,大家將就看,先上效果圖


首先參考http://blog.csdn.net/onepiece2345/article/details/8165241重寫InstrumentationTestRunner 類,之所以沒用android-junit-report-1.5.8.jar是因爲它生成的xml只包含了錯誤信息,而沒有正確信息,爲了實現成功數、成敗數、以及成功率,需要將成功信息也包含在內。

具體的存放位置按自己需要進行調整,我現在是按時間作爲文件名,存在sdcard/KTTestReport下,還有輸出的結點名稱內容都可以根據自身需要進行相應修整,切忌拿來主義不一定適合於 你InstrumentationTestRunner 代碼如下:

public class InstrumentationTestRunner3 extends android.test.InstrumentationTestRunner
{
    private Writer mWriter;
    
    private XmlSerializer mTestSuiteSerializer;
    
    private long mTestStarted;
    
    public void onStart()
    {
        try
        {
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-kk-mm");
            String strTime = sdf.format(d);
            String xmlName = "Test" + strTime + ".xml";
            // 如果被測的應用本身有讀寫sdcard權限的話級可以直接放在sdcard裏面,否則機會失敗,
            // 有測試應用源碼的情況下是可以在AndroidManifest.xml裏添加權限,當然所數情況下是沒有源碼的,
            // 只能放在被測應用的files目錄裏了,這個是不需要權限的
             String SDPath = Environment.getExternalStorageDirectory() + "/";
             String logPath = SDPath + "KTTestReport/";
             File file = new File(logPath);
             if (file.exists()) {
             } else {
             file.mkdirs();
             }
             startJUnitOutput(new FileWriter(new File(file, xmlName)));
            //startJUnitOutput(new FileWriter(new File(getTargetContext().getFilesDir(), xmlName)));
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
        super.onStart();
    }
    
    void startJUnitOutput(Writer writer)
    {
        try
        {
            this.mWriter = writer;
            this.mTestSuiteSerializer = newSerializer(this.mWriter);
            this.mTestSuiteSerializer.startDocument(null, null);
            this.mTestSuiteSerializer.startTag(null, "testsuites");
            this.mTestSuiteSerializer.startTag(null, "testsuite");
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
    
    private XmlSerializer newSerializer(Writer writer)
    {
        try
        {
            XmlPullParserFactory pf = XmlPullParserFactory.newInstance();
            XmlSerializer serializer = pf.newSerializer();
            serializer.setOutput(writer);
            return serializer;
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
        
    }
    
    public void sendStatus(int resultCode, Bundle results)
    {
        super.sendStatus(resultCode, results);
        switch (resultCode)
        {
            case -2:
            case -1:
            case 0:
                try
                {
                    recordTestResult(resultCode, results);
                }
                catch (IOException e)
                {
                    throw new RuntimeException(e);
                }
                
            case 1:
                recordTestStart(results);
        }
    }
    
    void recordTestStart(Bundle results)
    {
        this.mTestStarted = System.currentTimeMillis();
    }
    
    void recordTestResult(int resultCode, Bundle results)
        throws IOException
    {
        float time = (float)(System.currentTimeMillis() - this.mTestStarted) / 1000.0F;
        String className = results.getString("class");
        String testMethod = results.getString("test");
        String stack = results.getString("stack");
        int current = results.getInt("current");
        int total = results.getInt("numtests");
        
        this.mTestSuiteSerializer.startTag(null, "testcase");
        this.mTestSuiteSerializer.attribute(null, "ID", current + "");
        this.mTestSuiteSerializer.attribute(null, "classname", className);
        this.mTestSuiteSerializer.attribute(null, "casename", testMethod);
        // Log.v("myInfor", current + "");
        if (resultCode != 0)
        {
            this.mTestSuiteSerializer.attribute(null, "time", String.format("%.3f", new Object[] {Float.valueOf(time)}));
            this.mTestSuiteSerializer.startTag(null, "result");
            if (stack != null)
            {
                String reason = stack.substring(0, stack.indexOf('\n'));
                String message = "";
                int index = reason.indexOf(':');
                if (index > -1)
                {
                    message = reason.substring(index + 1);
                    reason = reason.substring(0, index);
                }
                this.mTestSuiteSerializer.attribute(null, "message", message);
                this.mTestSuiteSerializer.attribute(null, "type", reason);
                this.mTestSuiteSerializer.attribute(null, "reason", stack);
                this.mTestSuiteSerializer.text("failure");
            }
            this.mTestSuiteSerializer.endTag(null, "result");
        }
        else
        {
            this.mTestSuiteSerializer.attribute(null, "time", String.format("%.3f", new Object[] {Float.valueOf(time)}));
            this.mTestSuiteSerializer.startTag(null, "result");
            this.mTestSuiteSerializer.attribute(null, "message", "pass");
            this.mTestSuiteSerializer.text("success");
            this.mTestSuiteSerializer.endTag(null, "result");
        }
        this.mTestSuiteSerializer.endTag(null, "testcase");
        if (current == total)
        {
            // this.mTestSuiteSerializer.startTag(null, "system-out");
            // this.mTestSuiteSerializer.endTag(null, "system-out");
            // this.mTestSuiteSerializer.startTag(null, "system-err");
            // this.mTestSuiteSerializer.endTag(null, "system-err");
            this.mTestSuiteSerializer.endTag(null, "testsuite");
            this.mTestSuiteSerializer.flush();
        }
    }
    
    public void finish(int resultCode, Bundle results)
    {
        endTestSuites();
        super.finish(resultCode, results);
    }
    
    void endTestSuites()
    {
        try
        {
            this.mTestSuiteSerializer.endTag(null, "testsuites");
            this.mTestSuiteSerializer.endDocument();
            this.mTestSuiteSerializer.flush();
            this.mWriter.flush();
            this.mWriter.close();
            
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }
}


完成後需要修改AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ktplay.sample.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

   <!-- report.jar使用這個<instrumentation
        android:name="com.zutubi.android.junitreport.JUnitReportTestRunner"
        android:targetPackage="被測程序包名" /> --> 
	<instrumentation
        android:name="測試程序包名.InstrumentationTestRunner3"
        android:targetPackage="<span style="font-family: Arial, Helvetica, sans-serif;">被測程序包名</span><span style="font-family: Arial, Helvetica, sans-serif;">" /></span>
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>
然後在run config中將
InstrumentationTestRunner3
配置好,如下圖

萬事具備只欠運行,現在就可以讓你的程序跑起來,最後會生成一個xml,可以打開看看是不是你要的信息,如果不正確可適當修改

接下來就是大家比較關心的html了,我是用dom去解析xml存到list裏然後又拼接的html,方法可能有些笨,如果哪位大神有好的方法還請賜教

 

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DomParseXml
{
    static final String  KTREPORT_XML_DIR = "E:\\KTtestReport\\";
    public List<Report> getReports()
        throws Exception
    {
        List<Report> list = new ArrayList<Report>();
        
        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document document = db.parse(new File(getName(KTREPORT_XML_DIR)));// 把文件解析成DOCUMENT類型,目前先寫死,最後用通配符匹配
        
        Element element = document.getDocumentElement();
        
        NodeList reportNodes = element.getElementsByTagName("testcase");
       
        for (int i = 0; i < reportNodes.getLength(); i++)
        {
            Element reportElement = (Element)reportNodes.item(i);
            Report report = new Report();
            report.setTime(Float.valueOf(reportElement.getAttribute("time")));
            report.setId(Integer.parseInt(reportElement.getAttribute("ID")));
            report.setClassName(reportElement.getAttribute("classname"));
            report.setCaseName(reportElement.getAttribute("casename"));
            
            NodeList childNodes = reportElement.getChildNodes();
            int total = reportNodes.getLength();
       
            for (int j = 0; j < childNodes.getLength(); j++)
            {
                if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE)
                {
                    if ("result".equals(childNodes.item(j).getNodeName()))
                    {
                        report.setResult(childNodes.item(j).getFirstChild().getNodeValue());
                       
                        NamedNodeMap  attributes =  childNodes.item(j).getAttributes();
                        for (int m = 0; m < attributes.getLength(); m++)
                        {
                            Node attribute = attributes.item(m);
                            // 得到屬性名
                            String attributeName = attribute.getNodeName();
                           
                            // 得到屬性值
                            String attributeValue = attribute.getNodeValue();
                            if("message".equals(attributeName))
                            {
                                report.setMessage(attributeValue);
                            }
                            else if("reason".equals(attributeName))
                            {
                                report.setReason(attributeValue);
                            }
                            else if("type".equals(attributeName))
                            {
                                report.setType(attributeValue);
                            }
                           
                        }
                        
                    }
                }
                report.setTotal(total);
                list.add(report);
            }
        }
        return list;
    }
    
    public static String getName(String path)
    {
        List<String> nameList = new ArrayList<String>();
        File file = new File(path);
        if (file.isDirectory())
        {
            File[] dirFile = file.listFiles();
            for (File f : dirFile)
            {
                if (f.isDirectory())
                { 
                    getName(f.getAbsolutePath());
                }
                else
                {
                    if (f.getName().endsWith(".xml") )
                    {
                        nameList.add(f.getAbsolutePath());
                    }
                }                        
            }
        }
        Collections.sort(nameList);
        if(nameList.size()<=0)
        {
            return "";
        }
        return nameList.get(nameList.size()-1);
    }
   public static void main(String[] args)
    {
        String nameString = getName("E:\\KTtestReport\\");
        System.out.println(nameString);
    }
}


拼裝

package xxx.report;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class GenerateHtmlReport
{
    static final String  KTREPORT_HTML_DIR = "E:\\report.html";
    public static void generateReports()
    {
        DomParseXml dom = new DomParseXml();
        List<Report> reports = new ArrayList<Report>();
        int succNum = 0;
        int failNum = 0;
        float totalTime = 0.0f;
        try
        {
            reports = dom.getReports();
            for(Report report :reports)
            {
                //System.out.println(report.getTotal()-report.getSuccessNum());
                if("failure".equals(report.getResult()))
                {
                    failNum++;
                }
                else
                {
                    succNum++;
                }
                totalTime = totalTime+report.getTime();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        writeToHtml(totalTime,succNum,failNum,reports);

    }
    private static void writeToHtml(float totalTime,int succNum,int failNum,List<Report> reports)
    {
        try
        {
            PrintStream out = new PrintStream(new FileOutputStream(KTREPORT_HTML_DIR));
            System.setOut(out);
            System.out.println("<h3 align=left><font color=#0000FF>Robotium Test Report</font></h1>");
             
                StringBuffer str = new StringBuffer();
                str.append("<html>\n");
                str.append("<body>\n");
                str.append("<table border='1px' cellspacing='0px' width='100%'  bordercolor='#000000'>");
                str.append("<tr>Start Time:");
                Date date= new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-kk-mm");
                String strTime = sdf.format(date);
                str.append(strTime);
                str.append("</tr><tr>Status:Pass ");
                str.append(succNum);
                str.append(" Faild ");
                str.append(failNum);
                str.append(" Ratio:");
                str.append(((Float.parseFloat(succNum+"")/(succNum+failNum)*100)/100)*100+"%");
                str.append("</tr><tr>Detail Views</tr>");
                str.append("<tr  bgcolor='#CCCCCC'>\n");
                str.append("<td>\n");
                str.append("TestCase\n");
                str.append("</td>\n");
                str.append("<td>\n");
                str.append("time\n");
                str.append("</td>\n");
                str.append("<td >\n");
                str.append("total\n");
                str.append("</td>\n");
                str.append("<td >\n");
                str.append("passed\n");
                str.append("</td>\n");
                str.append("<td >\n");
                str.append("Faild\n");
                str.append("</td>\n");
                str.append("</tr>\n");
                //第二行
                str.append("<tr bgcolor='B0E0E6'>\n");
                str.append("<td>\n");
                str.append("Summary\n");
                str.append("</td>\n");
                str.append("<td>\n");
                str.append(totalTime+"s"+"\n");
                str.append("</td>\n");
                str.append("<td >\n");
                str.append(reports.size()+"\n");
                str.append("</td>\n");
                str.append("<td >\n");
                str.append(succNum+"\n");
                str.append("</td>\n");
                str.append("<td >\n");
                str.append(failNum+"\n");
                str.append("</td>\n");
                str.append("</tr>\n");
                for (Report b : reports)
                {
                    str.append("<tr");
                   
                    // str.append(" bgcolor='#CD5555'");
                    
                    str.append(">");
                    str.append("<td>\n");
                    str.append(b.getCaseName());
                    str.append("</td>\n");
                    str.append("<td>\n");
                    str.append(b.getTime()+"s");
                    str.append("</td>\n");
                    str.append("<td colspan='3' align='center'>\n");
                    if(!"pass".equals(b.getMessage()))
                    {
                        str.append("<font color='#FF0000'>");
                        str.append(b.getMessage());
                        str.append("</font>");
                    }
                    else
                    {
                        str.append("<font color='#218868'>");
                        str.append(b.getMessage());
                        str.append("</font>");
                    }
                    str.append("</td>\n");
                    str.append("</tr>\n");
                }
                str.append("</table>\n");
                str.append("</body>\n");
                str.append("</html>\n");
                System.out.println(str.toString());
            out.close();
        }
        catch (FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    public static void main(String[] args)
    {
        generateReports();
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章