爬取Testlink关联的bug信息

    笔者之前依赖TestlinkApi开发了一个小工具,详见文章《Testlink批量导入及导出Excel测试案例》,原本以为可以功成身退了,结果上周五给测试组做分享时,有同事提出了新需求:希望批量导出测试案例执行结果时把案例关联的bugId也导出来,后续再用于自动生成测试报告。
    听到这个需求时,笔者微微一笑,内心深处无数个“so easy”的声音飘过,毕竟就一个bugid字段,万能的TestlinkApi肯定可以轻易取到。于是,测试分享会完毕后,笔者以“迅雷不及掩耳盗铃之势”翻了几遍TestlinkApi文档,然而,就在这短短的3分钟时间里,你能想象笔者内心经历了怎样的一番挣扎?“What the hell,TestlinkApi没有提供获取bugId字段的方法?”笔者大喊一声后瘫坐在工位上,心情也犹如过山车般滑到谷底!但是,作为一名有探究精神的Tester,笔者显然不会被眼前的这丁点困难吓退,既然没有捷径可走,那就必须”另谋出路”。于是笔者开始了解决问题的探索之旅,最终定了两个方案:

一、钻研Testlink源码。
二、爬取Testlink”案例关联缺陷”页面的信息。

    依笔者现阶段的水平来看,方案一无疑是往深渊里跳,一来是不熟悉php,学习成本太高,二来是学习成本太高,不熟悉php。但从长远来看,该方案无疑是“通治百病”的,真把源码读懂了,往后就予取予求了。苦于能力问题,笔者“无奈”选择了方案二,因为做的是小工具,那么爬取信息就得有几个前提:

1、爬取信息对工具用户应该是无感知的。
2、爬取信息的效率一定要高,不然谁稀罕用你这个破工具。
3、爬取的信息一定要准,不然又是一堆吐槽。

   在开始编码前,咱们把实现思路捋一捋:首先登录Testlink,然后再跳转到“案例关联缺陷”页面,获取页面html元素,最后解析html获得需要的信息。

Testlink登录页面
Testlink主页

案例关联缺陷页面

   登录Testlink,Tester们最先想到的肯定是selenium了,但要使用户无感知,我们就不能跳个浏览器出来,不然用工具的人内心肯定一万句“靠,我就用个破工具,你给我跳出个浏览器,几个意思???”庆幸的是HtmlUnit Driver有效地解决了咱们的难题,而且相比Firefoxdriver等,其真的做到了更快(不敢说更准)。

//HtmlUnit Driver示例代码
WebDriver dr = new HtmlUnitDriver();
dr.get(url);
dr.findElement(By.name("tl_login")).clear();    //用户名输入框
dr.findElement(By.name("tl_login")).sendKeys(userName); 
dr.findElement(By.name("tl_password")).clear(); //密码输入框
dr.findElement(By.name("tl_password")).sendKeys(password);
dr.findElement(By.name("login_submit")).click();

   如果按照传统的自动化测试思维,编码者肯定是“死板”地按照以下的思路来实现:自动登录Testlink,然后自动点击各个链接一步一步地跳转到“案例关联缺陷”页面,再提取页面html元素。如果你无视用户的吐槽而选择firefoxdriver或chromedriver来实现需求,笔者无话可说。但如果你用htmlunitdriver还这样做的话,一首凉凉送给你,因为htmlunitdriver对javascript的支持真的不够好,你可能都获取不到页面跳转的链接,也就是说死活跳不到“案例关联缺陷”页面。换个思路:登录Testlink后,直接根据url跳转到目标页面不就简单多了?然而“坑爹”的Testlink并不会让你的想法顺利实现,因为无论你在Testlink主页操作任何功能,getCurrentUrl()返回的永远都是 http://testlink-*********/index.php,所幸良心的Testlink开发者给探究者们留下了一条通往光明的小道:光标停留在 Bugs per Test Case (All Executions) ,我们非常清楚地看到了一行url。

Bugs per Test Case (All Executions)

   那么接下来的事情就简单了,根据不同的计划id跳转到相应的页面,然后使用getPageSource()方法获取页面元素进行解析即可。
   通篇文章的卖了不少关子,接下来上核心代码,有兴趣的童鞋可以去尝试。
   pom.xml文件配置



    4.0.0

    htmlunit
    driver
    1.0-SNAPSHOT

    
    
        net.sourceforge.htmlunit
        htmlunit
        2.15
    

     
         org.seleniumhq.selenium
         selenium-java
         2.45.0
     

    
        org.jsoup
        jsoup
        1.7.2
    
    

//获取 案例关联缺陷页面的html元素
public static String driver(String url,String userName,String password,String planId){

        String html;
        try {
            WebDriver dr = new HtmlUnitDriver();
            dr.get(url);

            dr.findElement(By.name("tl_login")).clear();
            dr.findElement(By.name("tl_login")).sendKeys(userName);
            dr.findElement(By.name("tl_password")).clear();
            dr.findElement(By.name("tl_password")).sendKeys(password);

            dr.findElement(By.name("login_submit")).click();

            System.out.println("---------------------登录Testlink成功---------------------");

            //计划Id不一样,前半部分一样
            dr.get("http://testlink-dev.yiguanjinrong.com/lib/results/resultsBugs.php?type=1&format=0&tplan_id=" + planId);
            html = ascii2Native(dr.getPageSource()); //获取页面元素,然后再提取缺陷
            //System.out.println("html:\n"+ html);

            dr.quit();//退出

            return html;
        }catch (Exception e){
            System.out.println(e.getMessage());
            return  null;
        }
    }
/*
*提取案例及缺陷信息存到List
*数组元素格式为:案例名称,GYL-1859_[关闭] 
*/
    public static List content(String htmlPageSource){
        List list = new ArrayList();

        String pattern = "tableData\\['tl_table_bugs_per_test_case'\\] = (.*)";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(htmlPageSource);

        if(m.find()){
            String caseRelateBugstr = m.group(1);
            //System.out.println("完整截取:\n"+caseRelateBugstr);
            String caseRelateBugstrSub = caseRelateBugstr.substring(2,caseRelateBugstr.length()-2);
            //System.out.println("非完整截取:\n"+caseRelateBugstrSub);

            String array[] = caseRelateBugstrSub.split("],\\[");
            List demoList = Arrays.asList(array);
            String str1;
            String pattern1 = "<\\\\/a>(.*)";
            Pattern r1 = Pattern.compile(pattern1);

            for (String str:demoList) {
                //System.out.println(str);
                StringBuffer buffer = new StringBuffer();
                str1 = "";
                Document doc = Jsoup.parse(str.replace("\"",""));
                str1= doc.text().replace(" : <\\/b>","_").replace(" ","");
                //System.out.println(str1);
                String array1[] = str1.split(":");
                for(int i=0;i 0){ //存在_[符号
                        Matcher m1 = r1.matcher(array1[i]);
                        if(m1.find())
                            buffer.append(m1.group(1)+" ");
                        else
                            buffer.append(array1[i]+" ");
                    }
                }
                list.add(buffer.toString());
            }
            return list;
        }else{
            return null;
        }
    }

   至此,大功告成,结合《Testlink批量导入及导出Excel测试案例》小工具,最终导出缺陷信息如下。

Testlink小工具

执行结果导出模板

你可能感兴趣的:(爬取Testlink关联的bug信息)