淘宝商城(天猫)高级技术专家.3年研发+3年性能测试调优/系统测试+4年团队管理与测试架构、研发系统实践. 新舞台新气象, 深化测试基础架构及研发架构,希望能在某个技术领域成为真正的技术大牛。欢迎荐才http://bbs.51testing.com/viewthread.php?tid=120496&extra=&page=1 .邮件: jianzhao.liangjz@alibaba-inc.com,MSN:liangjianzhao@163.com.微博:http://t.sina.com.cn/1674816524

发布新日志

  • 很久没写blog了

    2017-12-06 13:37:46

    需要系统地梳理下今年的一些思考。
    战略、战术都需要勤快....
  • 测试工程师日常工作需要关注的问题

    2013-03-23 10:48:33

       在互联网公司追求价值最大化、成本最低化的今日,很多互联网公司开始提倡高的开发测试比率,工程师都有必要提升自己的贡献、产能,我们也需要将一些问题融入到工作中,在做中寻找答案。 
        跳出自己的小圈子,甚至跳出测试角色,解决业务痛点、研发体系痛点,在解决问题中成长才是王道。
     
     业务角度
       1 
    业务痛点是什么? 通过方案来解决? 推进难度是什么?里程碑是什么?
       2 
    目前的业务指标是多少? PV/UV、转化率
       3 
    这个业务关联的系统都是那些?他们的边界是什么?测试难点在哪里?
       4 
    未来的规划是怎样的? 这个版图里面我们还缺哪一块 
       
      
     技术角度
       1  
    这个工具、框架、系统的技术原理是什么?
       2 解决方案的
    技术难度与创新点体现在哪里
       3 
    与公司级、业界的优秀解决方案差异在哪里? 为什么要做这个东西?
       4 
    这个被测系统的测试难度、边界在哪里?
       5 
    某个问题比较突出,比如MR job性能慢、算法测试如何定义标准,你打算怎么解决?
       6 
    某一类测试和另外一类测试的本质区别在哪里? 比如PC 应用和无线应用区别在哪里?
       7 实施某个方案后的
    纵向、横向对比的数据是怎么样的?
       
      
     流程
       1  
    经常出现的问题是什么? 抽象出共性的东西? 和相关部门一起推进了?效果如何?
       2  
    和开发测试形成的流程有哪些?效果如何?推进难度有哪些?
       3  
    流程改进前后的效果对比数据是怎么样的?

      
     团队
       1 
    团队培养的案例?
       2 
    团队梯度建设及氛围建设的案例?
       3 
    团队培养的思路是怎么样的?
       4 
    团队的痛点是怎么样的?
       5 
    和相同类型的业务、研发团队合作的方式是怎么样的? 和兄弟公司沟通情况如何?
  • maven job命令行执行外部shell

    2012-03-08 11:02:17

     目前编译环境是

    [maven3@inc-platform-dev-144-9 hudson-2.0.1_win]$ mvn -v

    Apache Maven 3.0.3 (r1075438; 2011-03-01 01:31:09+0800)

    Maven home: /home/maven3/apache-maven-3.0.3

    Java version: 1.6.0_25, vendor: Sun Microsystems Inc.

    Java home: /usr/alibaba/install/jdk1.6.0_25/jre

    Default locale: en_US, platform. encoding: ISO-8859-1

     

     

    ) hudson.maven.agent.Main

     

     

    增加callShell函数的2个版本。

     

        //see http://www.devdaily.com/java/java-exec-processbuilder-process-2

        //fixed exec linux shell hang

        //多线程版

        private static int  callShell_mt(String cmd) throws IOException,

        InterruptedException {

           List commands = new ArrayList();

           System.out

                  .print(" ***warning!only support shell!callShell start by liangjz.*** ");

           commands.add("/bin/sh");

           commands.add("-c");

           commands.add(cmd);

           SystemCommandExecutor commandExecutor = new SystemCommandExecutor(commands);

            int shellExitStatus = commandExecutor.executeCommand();

            // stdout and stderr of the command are returned as StringBuilder objects

            StringBuilder stdout = commandExecutor.getStandardOutputFromCommand();

            System.out.println("The numeric result of the command was: " + shellExitStatus);

            System.out.println(stdout);

            return shellExitStatus;

        }

        private static int callShell(String cmd) throws IOException,

               InterruptedException {

           List commands = new ArrayList();

           System.out

                  .print(" ***warning!support shell!may be waiting  long time ,please!!callShell start by liangjz.*** ");

           commands.add("/bin/sh");

           commands.add("-c");

           commands.add(cmd);

           ProcessBuilder pb = new ProcessBuilder(commands);

           pb.redirectErrorStream(true); // use this to capture messages sent to

                                       // stderr

           Process shell = pb.start();

           InputStream shellIn = shell.getInputStream(); // this captures the

                                                     // output from the

                                                     // command

           int shellExitStatus = shell.waitFor(); // wait for the shell to finish

                                              // and get the return code

     

           // at this point you can process the output issued by the command

           // for instance, this reads the output and writes it to System.out:

           int c;

           while ((c = shellIn.read()) != -1) {

               System.out.write(c);

           }

           // close the stream

           try {

               shellIn.close();

           } catch (IOException ignoreMe) {

     

           }

           System.out.print(" *** callShell End by liangjz,return  " + shellExitStatus);

           return shellExitStatus;

        }

     

     

     

     

    //launch根据mvn命令行传递入的参数才触发调用外部shell.

     

    public static int launch(String[] args) throws NoSuchMethodException,

               IllegalAccessException, NoSuchRealmException,

               InvocationTargetException, ClassNotFoundException {

           // ClassWorld world = ClassWorldAdapter.getInstance( launcher.getWorld()

           // );

     

           ClassWorld world = launcher.getWorld();

     

           Set builtinRealms = new HashSet(world.getRealms());

           boolean callShell = false;

           int callShellRet=-1;

           try {

               System.out.println("----- hudson.maven.agent.Main.launch start by  liangjz----");

               String libs = null;

               String workspace=null;

               String apps=null;

                            String crid="0";

               StringBuilder sb=new StringBuilder();

               sb.append("'");

               for (int i = 0; i < args.length; i++) {

                  //System.out.println("arg" + i + "=" + args[i]);

                  if (args[i].startsWith("-DlibsOrder")) {

                      String[] tmpArr = args[i].split("=");

                      if (tmpArr.length == 2) {

                              callShell = true;

                         libs = tmpArr[1];

                      }

                  }else if(args[i].startsWith("-Dapps")){

                      String[] tmpArr = args[i].split("=");

                      if (tmpArr.length == 2) {

                         apps = tmpArr[1];

                      }

                  }else if(args[i].startsWith("-DWORKSPACE")){

                      String[] tmpArr = args[i].split("=");

                      if (tmpArr.length 查看(2564) 评论(0) 收藏 分享 管理

  • 彻底删除hudson job的方法

    2012-03-08 10:56:47

    官方hudson2.0.1删除job,并没有删除各次build的历史记录。本次改动hudson代码删除在master上的配置文件及各个还残留build记录的 slave上的build记录。

     

    )   hudson.model.AbstractProject.performDelete()

     

    修改为获取所有的build记录上的Node并执行删除操作。

     

    @Override

        protected void performDelete() throws IOException, InterruptedException {

            // prevent a new build while a delete operation is in progress

            makeDisabled(true);

           //modify by liangjz

           //FilePath ws = getWorkspace();

           //if(ws!=null) {       

            /*

                Node n = getLastBuiltOn();

                getScm().processWorkspaceBeforeDeletion(this, ws, on);

                if(on!=null)

                    on.getFileSystemProvisioner().discardWorkspace(this,ws);

                 */

             Map<Node,FilePath>  nfMap = getAllBuiltOn();

             for(Map.Entry<Node,FilePath> entry:nfMap.entrySet())

             {

                 Node n=entry.getKey();

                 FilePath fp=entry.getValue();

                     getScm().processWorkspaceBeforeDeletion(this, fp, n);

                     if(n!=null)

                         n.getFileSystemProvisioner().discardWorkspace(this,fp);

                 }            

            //}

            super.performDelete();

       }

     

    二)hudson.model.Job 获取所有的曾经build过的节点及workspace目录

     

    public Map<Node,FilePath> getAllBuiltOn() {

            // where was it built on?

           List allBuild = getAllBuild();

           Map<Node,FilePath> map=new HashMap<Node,FilePath>();

            Set<Node> nodes=new HashSet<Node>();

            for(Object o: allBuild){

            AbstractBuild b=(AbstractBuild) o;

            Node n= b.getBuiltOn();          

            if(!nodes.contains(n)){

                 FilePath ws=b.getWorkspace();

                 if(ws!=null){

                     map.put(n,ws);

                     nodes.add(n);

                 }

            }           

            }    

            return map;   

    }

     

    三)  Hudson.FileSystemProvisioner

     

    此处需要实现序列化。并且各个slave重新下载slave.jar且重连。

     

    discardWorkspace 加入激活slave删除文件夹的功能。

     

    public static final class Default extends FileSystemProvisioner implements   Serializable {

            /**

     

           public void prepareWorkspace(AbstractBuild<?, ?> build, FilePath ws, TaskListener listener) throws IOException, InterruptedException {

            }

             

            public void discardWorkspace(AbstractProject<?, ?> project, FilePath ws) throws IOException, InterruptedException {

            //add by liangjz,递归删除文件参考ZFSProvisioner

            ws.act(new FileCallable<Void>() {

                    public Void invoke(File f, VirtualChannel channel) throws IOException {

                        if(f!=null){

                           Util.deleteRecursive(f);

                        }                      

                        return null;

                    }

                });

            }

     

     

     

  • 保持工作热情的一点看法

    2011-05-19 08:10:22

      迈入工作10年生涯,有团队邀请我结合实际案例简单聊聊"工作热情",附上我自己的理解,希望能对大家有所帮助。像很多成长课程一样,本文也是知易行难,实践是消化的唯一之道。

    一 热情的正反表现

    正:

    冲劲十足,执行力强
    自我驱动、要性强
    坚持如初,有感染力、激情四射

    反:

    被动接受任务,分外工作
    安于现状
    冷却,平淡


    你身边的榜样特质又是怎么样的呢?

    二热情来源

    1做事获取成就感,收获成长,自我鼓励、他人肯定,长期正反馈
    2做自己喜欢做并且擅长的事情
    3挖掘工作中乐趣,保持好奇心、新鲜感,了解底层原理、实现细节
    4适当危机感,持续高标准自我要求,把事情做到极致
    5明确阶段性目标,把握节奏,好心态

    三 热情消退的方式

    1经常性挫折,心累,很有无力感
    2缺乏反馈,不受重视
    3单纯重复性、事务性工作
    4目标过高或者安于现状,自我定位过高,过多比较、计较心

    四保持热情的一些做法

    和上述消退呼应。

    1 不逃避问题,寻求支持,借用团队力量,点滴进步、沉淀到量变导致质变
    2从不同角色、角度获取尽早反馈,管理上司
    3 换角度思考、思维创新,交流碰撞,开拓思路,反思深度、广度是否够
    4目标跳一跳就够着,分解到可执行,调整心态,做好持久战准备
    5适当自我调节,他人低谷
    6 重复N次变成习惯

     

  • 范用户体验相关BLOG

    2011-01-08 13:48:08

      寻找前端质量改进技术和工具时,陆续爬到的一些网站。
    欢迎补全:)
    一 公司
    阿里巴巴http://www.aliued.com/
    阿里巴巴http://www.aliued.cn/
    支付宝:http://ued.alipay.com/
    淘宝http://ued.taobao.com/
    口碑 http://ued.koubei.com/
    阿里妈妈 http://ued.alimama.com/
    阿里软件http://www.alisoftued.com/
    雅虎 http://www.uedblog.com/
    D2技术论坛:http://www.d2forum.org/
    19楼 http://blog.19ued.com/
    杭州网易 http://ucd.blog.163.com/
    网易http://www.ued163.com/
    腾讯CDC http://cdc.tencent.com/
    腾讯ISD http://isd.tencent.com/?cat=7
    腾讯无线 http://wsd.tencent.com/
    百度范用户体验 http://www.baiduux.com/
    百度无线 http://mux.baidu.com/
    百度有啊技术http://www.youalab.com/
    搜狐http://ued.sohu.com/
    第九城市 http://www.the9ued.com/
    盛大 http://www.sndaued.com/blog/
    携程 http://ued.ctrip.com/blog/
    UCD大社区 http://ucdchina.com/
    视角同盟 http://www.visionunion.com/interface.jsp
    移动http://mdchina.org/
    UED: http://uecom.org/
    交互设计 http://alite.aliued.cn/
    人机界面 http://www.chinaui.com/
    http://www.bbon.cn/
    二 个人
    玉伯 http://lifesinger.org/blog/
    完颜 http://www.smbey0nd.com/category/mobile-web/frontend/
    泽飞 http://www.planabc.net/
    大熊 http://www.thedaxiong.com/
    http://blog.sharkui.com/
    http://dimcolor.com/blog/
    陈成 http://www.chencheng.org/blog/
    阿里人http://www.aliren.org/?p=7
    IT民工 http://www.fool2fish.cn/?cat=5
    付琦 http://www.imf7.com/archives/category/web
    前端之路 http://www.simcn.com/category/html_css_javascript
    http://www.anbuyu.com/

  • 国外测试专家BLOG

    2011-01-08 13:01:32

      从《测试之美》附录爬虫式找到的一些质量保证领域专家BLOG。欢迎在外企的朋友帮忙补充。

    微软测试专家BLOG http://msdn.microsoft.com/en-us/testing/bb880947.aspx
    jennitta andrea  twitter:http://twitter.com/jennitta_andrea
    性能测试scott barber:http://www.perftestplus.com/presentations.htm

    rex black: http://www.rbcs-us.com/blog

    adamchristian:http://www.adamchristian.com

    isaac clerencia: facebook/titter

    john.d.cook: http://www.johndcook.com/blog/category/software-development/

    敏捷测试lisacrispin: http://lisacrispin.com/wordpress/

    过程改进 adam goucher: http://adam.goucher.ca/?page_id=538

    Matthew Heusser
    : http://www.informit.com/authors/bio.aspx?a=49E9EE57-4D25-45DF-A5F5-BFD45F95E894

    karennjohnson :http://www.karennjohnson.com/

    remko roncon: http://el-tramo.be/

    lida wilinson: http://www.practicalqa.com/

  • 探索性测试及基于模型测试工具集

    2010-12-02 08:51:54

    一 探索性测试相关工具集:

    .NET pex: http://www.infoq.com/cn/news/2008/07/Pex

    Visual stidio2010 MTM: http://blog.csdn.net/quicknet/archive/2010/06/20/5682001.aspx

    ET进度管理工具:http://sessiontester.openqa.org

     

    二 MBT工具集

     

    Ms spec-explorer: http://www.infoq.com/cn/news/2009/11/spec-explorer-2010

    开源 http://mbt.tigris.org/doc.html

    C#写的:http://nmodel.codeplex.com/

     

    ET难点在于创新性的测试思维及平衡计划性与随机性,

    MBT难点在于对领域知识抽象能力及建模。

    更多工具待实践挖掘。

  • tomcat url编解码处理方法

    2010-10-04 07:58:12

    Tomcat6安装目录/conf/server.conf 默认的connector配置如下,

     

    <Connector port="8080" protocol="HTTP/1.1"

                   connectionTimeout="20000"

                   redirectPort="8443"  />

     

    默认情况下其URIEncoding =”ISO8859-1”

    为了确保web客户端和服务器编解码正常,在客户端肯定是utf8编码的情况下,处理方式有2

     

    1)      tomcat connector采用默认配置URIEncoding =”ISO8859-1”

     

    client端编码:

    URLEncoder.encode(description,"UTF-8");

     

    server端解码:(接收到的为ISO8859-1编码的字符串)

    String description = request.getParameter("description");

    decDescription = new String(description.getBytes("ISO8859-1"), "UTF-8");

    2)      修改tomcat connector 配置URIEncoding =”UTF-8”

     

    client:

    URLEncoder.encode(description,"UTF-8");

     

    Server端:

    String description = request.getParameter("description");

    //此处接收到的description即为UTF-8格式了。

  • 应用maven/hudson实施jmeter性能自动化2

    2010-05-22 01:48:57

     

    1.1       部署hudson插件以及配置

     

    参考:http://www.theserverlabs.com/blog/2009/04/23/performance-tests-with-jmeter-maven-and-hudson/

     

    下载http://wiki.hudson-ci.org/display/HUDSON/Performance+Plugin 插件,取代jmeter插件。

           配置好maven 目标,post-build处,勾选:

    Archive the artifacts: jmeter-result/*.html  这里是发布html格式报告。

    Publish performance test result report: google_search*.xml。这里将解析jmeter原始的xml响应数据。

     

     

    1.2       生成结果

     

    执行立即生成,将产生归档的html信息及 详细的请求信息、趋势图等。

     

                如上建立在hudson成功部署的基础上。


    1.3       Jmeter java sampler额外处理

     

    google code下载的附件:jmeter-support-jars-1.0\jmeter-2.3.jar已经涵盖jmeter2.32目录lib/ext/ApacheJMeter_java.jar, ApacheJMeter_core.jar的类。

     

    maven-jmeter-plugin-1.0.jar 没可自定义classpath的属性点。 最简单的办法是把所有依赖到的CLASS加入到环境变量CLASSPATH内。

     

    执行时无需copy实现java smaplerjar jmeter/ lib/ext/目录下。

    优雅的实现,参考:http://my.opera.com/mateamargo/blog/2007/09/27/running-junitsampler-with-maven

    去改写http://jmeter-maven-plugin.googlecode.com/svn/trunk/ 原理是动态调用 URLClassLoader. addURL将路径加入CLASSPATH变量。

    可以用mvn install 安装部署入本地库,也可参考google做法手工加载。

     

      (字数超长了:),分2节发布。

     

     

  • 应用maven/hudson实施jmeter性能自动化

    2010-05-22 01:35:45

    参考

    http://code.google.com/p/jmeter-maven-plugin/wiki/HOWTOUsePlugin

     

     

    从如上url下载maven plugindepenent 先按原文细致执行。

    mvn deploy:deploy-file -DgroupId=org.apache.jmeter -DartifactId=jmeter -Dversion=2.3 -Dpackaging=jar -Dfile=jmeter-2.3.jar -DpomFile=jmeter-2.3.pom -Durl=file://<repo dir>

     

    如上命令是把jar 部署到本地maven reposity库。我个人机器repo dir: "C:\Documents and Settings\jianzhao.liangjz\.m2\repository"

    命令行实际执行如下:

    mvn deploy:deploy-file -DgroupId=org.apache.jmeter -DartifactId=jmeter -Dversion=2.3 -Dpackaging=jar -Dfile=jmeter-2.3.jar -DpomFile=jmeter-2.3.pom -Durl=file://"C:\Documents and Settings\jianzhao.liangjz\.m2\repository"

     

      按原文配置后,对maven工程实施  Mvn clean install 出现多个错误,控制台上错误提示可能误导人。

    在工程目录: target/jmeter/jmeter.log提供真正价值的异常信息。如:

    jmeter.save.SaveService: Conversion error com.thoughtworks.xstream.converters.ConversionException: org/apache/commons/logging/LogFactory : org/apache/commons/logging/LogFactory

     

    源代码可参考:http://jmeter-maven-plugin.googlecode.com/svn/trunk/src/main/java/org/apache/jmeter/JMeterMojo.java

     

     调整细节如下:

           

    1.0       前提部署好maven/jmeter环境

    D:\src\netty_websocket>mvn -version

    Apache Maven 2.2.1 (r801777; 2009-08-07 03:16:01+0800)

    Java version: 1.6.0_11

    Java home: D:\devtools\jdk1.6.0_11\jre

    Default locale: zh_CN, platform. encoding: GBK

    OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

     

    D:\src\netty_websocket>  jmeter -v

    Copyright (c) 1998-2008 The Apache Software Foundation

    Version 2.3.2 r665936

     

    1.1        增加Pom.xml 依赖

    <dependency>

                          <groupId>commons-logging</groupId>

                            <artifactId>commons-logging</artifactId>

                            <version>1.0.4</version>

         </dependency>

        

       <dependency>

          <groupId>logkit</groupId>

                    <artifactId>logkit</artifactId>

                    <version>1.2</version>

        </dependency>

     

                  <dependency>

                           <groupId>org.apache.jmeter</groupId>

                           <artifactId>maven-jmeter-plugin</artifactId>

                           <version>1.0</version>

                  </dependency>

          

    1.2       Maven mvn.bat调整

    Maven工程bin/Mvn.bat 运行参数增加CLASSPATH指示器。

     

    %MAVEN_JAVA_EXE% %MAVEN_OPTS% -classpath %CLASSWORLDS_JAR%;"C:\Documents and Settings\jianzhao.liangjz\.m2\repository\commons-logging\commons-logging\1.0.4\commons-logging-1.0.4.jar";"C:\Documents and Settings\jianzhao.liangjz\.m2\repository\logkit\logkit\1.0.1\logkit-1.0.1.jar"  "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" "-Dmaven.home=%M2_HOME%" org.codehaus.classworlds.Launcher %MAVEN_CMD_LINE_ARGS%

     

    1.3       拷贝upgrade.properties 到工程bin/目录下

    拷贝jmeter/bin下文件upgrade.properties 到如 D:\src\netty_websocket\bin 目录下

    1.4       创建一个jmx文件

    badboy录制google 搜索过程,另存jmeter文件为google_search.jmx

    放到D:\src\netty_websocket\src\test\jmeter 目录下

    1.5       执行命令生成XML报告

    可以mvn jmeter:jmeter,也可 mvn verify

     

    结果文件在D:\src\netty_websocket\target\jmeter-reports\ google_search*.xml

     

    1.6       生成html报告(可选)

    参考 http://jlorenzen.blogspot.com/2008/03/a

    Automated Performance Tests using JMeter and Maven

     

    ·  Under your project create the directory: src/test/jmeter and src/test/resources

    ·  Copy the jmeter.properties file from the JMeter bin folder to src/test/jmeter.

    ·  Update the property jmeter.save.saveservice.output_format in the jmeter.properties file from csv to xml.

    ·  Copy the files jmeter-results-detail-report_21.xsl and jmeter-results-report_21.xsl from the JMeter extras folder to src/test/resources

    .  pom.xml add

     

    <plugin>
                   <groupId>org.codehaus.mojo</groupId>
                   <artifactId>xml-maven-plugin</artifactId>
                   <version>1.0-beta-2</version>
                   <executions>
                       <execution>
                       <phase>pre-site</phase>
                       <goals>
                           <goal>transform</goal>
                       </goals>
                       </execution>
                   </executions>
                   <configuration>
                       <transformationSets>
                           <transformationSet>
                               <dir>${project.build.directory}/jmeter-reports</dir>
                               <stylesheet>src/test/resources/jmeter-results-detail-report_21.xsl</stylesheet>
                               <outputDir>${project.build.directory}/site/jmeter-results</outputDir>
                               <fileMappers>
                                   <fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
                                       <targetExtension>html</targetExtension>
                                   </fileMapper>
                               </fileMappers>
                           </transformationSet>
                       </transformationSets>
                   </configuration>
               </plugin>  

     

    <>

  • JAVA应用监控javamelody

    2010-05-09 22:21:56

     

    http://code.google.com/p/javamelody/wiki/Screenshots

    http://wiki.hudson-ci.org/display/HUDSON/Monitoring

    http://code.google.com/p/javamelody/wiki/UserGuide

    http://code.google.com/p/javamelody/wiki/UserGuideAdvanced

     

    另外一款java 应用性能监控工具。

    呵呵,个人体会感觉界面、部署便利性不及jwebap

    本次试验在spring 程序上及hudson上成功。

     

    1.1.1    下载

    http://code.google.com/p/javamelody/downloads/list 下载javamelody-1.15.0.zip

    1.1.2    部署

    将解压后的2jar包放到被监控程序的 lib/目录下

    修改web.xml: 在最前面加入

     

           <filter>

                    <filter-name>monitoring</filter-name>

                    <filter-class>net.bull.javamelody.MonitoringFilter</filter-class>

            </filter>

            <filter-mapping>

                    <filter-name>monitoring</filter-name>

                    <url-pattern>/*</url-pattern>

            </filter-mapping>

            <listener>

                    <listener-class>net.bull.javamelody.SessionListener</listener-class>

            </listener>

    1.1.3    启动应用

    启动被监控应用。

    1.1.4    执行用户请求

    1.1.5    监控web应用

    http://host:port/context/monitoring 可以获取javamelody

      

     

    1.1.6    部署hudson plugin

    http://hudson-ci.org/download/plugins/ 下载。

    放在hudson/plugins目录下。

    http://host:port/hudson/monitoring 可以查看到性能数据。

     

  • 配置huson执行分布式任务

    2010-05-08 13:12:41

    参考:http://qa.taobao.com/?p=6145

          http://wiki.hudson-ci.org/display/HUDSON/Distributed+builds

     

    默认安装hudson即为master模式,在master部署大量job时,部署slave可提高jobs执行效率。

    Hudson的分布式任务并不需要在slave 上也部署一套hudson环境,而是在建立masterslave之间的连接后master发指令让slave 执行。

     

    试验过程的环境:从http://wiki.hudson-ci.org/display/HUDSON/Cppcheck+Plugin 下载cppcheck.hpi 及源代码,部署好了cppcheck插件。hudson服务器(master)搭建在xen虚拟机上,访问路径:http://192.168.56.101:8080/hudson 任务执行的客户端为windows宿主机。

    1.1.1    建立masterslave 之间连接

    windows上打开浏览器,输入http://192.168.56.101:8080/hudson/computer/

     

    点击新建节点:名称windows_node_cppcheck_parser,选择Dumb Slave

     

    填写必要信息:

    namewindows_node_cppcheck_parser

    Remote fs root: d:/cppcheckxml  -----------------à这里指slave执行任务时,slave 存放被解析文件,包括代码、配置的目录。

    Usage : leave this machine for tied jobs only

    Launch methodlaunch slave agents via jnlp

    点击save配置信息。

     

    点击

    http://192.168.56.101:8080/hudson/computer/windows_node_cppcheck_parser/进入slave连接方式页面。

     

    点击launch图标,可以下载slave.jar包。

    点击launch建立windows机器和 Hudson master连接。

     

    或者在下载 slave.jar的当前目录执行命令建立windows Hudson master的连接:

    java -jar slave.jar -jnlpUrl http://192.168.56.101:8080/hudson/computer/windows_node_cppcheck_parser/slave-agent.jnlp

     

    输入http://192.168.56.101:8080/hudson/computer/windows_node_cppcheck_parser/systemInfo 可以看到windows宿主机环境信息。

     

    再输入http://192.168.56.101:8080/hudson/computer/ 可以看到slave概要信息

    1.1.2    建立与slave关联的jobs

    新建一个Build a free-style. software project  的c 任务。

    http://192.168.56.101:8080/hudson/view/All/job/c/configure

    进入配置页面.

     

    选择 tie this project to a node 绑定到刚才的windows_node_cppcheck_parser节点。

     

     

    选择publish cppcheck results, 输入 *cppcheck*.xml.

    点击立即生成,通过 http://192.168.56.101:8080/hudson/job/c/1/console 看到错误提示:

     

    Parsing has been canceled. No cppcheck test report file(s) were found with the pattern '*cppcheck*.xml' relative to 'd:\cppcheckxml\workspace\c'.

     

    windows宿主机的d:\cppcheckxml\workspace\c 目录放cppcheck源码附带的cppcheck输出内容的testcppcheck1.xml testcppcheck2.xml文件。 再点击立即生成,http://192.168.56.101:8080/hudson/job/c/2/cppcheckResult/可以看到成功解析cppcheck结果。 

    http://192.168.56.101:8080/hudson/job/c/2/console 可看到 Building remotely on windows_node_cppcheck_parser 字样。 

    http://192.168.56.101:8080/hudson/computer/windows_node_cppcheck_parser/ 可以看到slave和项目关联。 

     

    ps:图片偶就不贴了,麻烦

  • java web应用性能监控工具jwebap

    2010-04-27 12:52:28

    性能测试中,我们经常希望一个平台能拦截、profile、分析性能数据,现实在一点点逼近. Jwebap

     

     效果图 http://www.jwebap.org/detect/console/?null

     官方文档:http://www.jwebap.org/index_zh.htm

     作者blog: http://leadyu.javaeye.com/

     

    Jwebap是无代码侵入、需要修改web.xml配置文件的java应用监控工具,轻易获取jdbc 调用/http调用、方法调用耗时及是否有jdbc泄露。 核心原理:应用asm 字节码操作框架实现动态monitor

       另外一个工具:http://jamonapi.sourceforge.net/

    1.1.1    下载

    http://sourceforge.net/projects/jwebap/files/

    1.1.2    部署

    解压后的jwebap_0.6.1.jar, tracer_0.6.1.jar jwebap_0.6.1_all\lib目录下jar复制到jboss-4.2.2.GA\server\default\lib 目录下。

     



    修改tracer_0.6.1.jar/META-INF/plugin.xml文件,红色为修改项:

    <?xml version="1.0" encoding="UTF-8"?>

    <plugin>

           <!--component-->

           <component name="HttpComponent" type="org.jwebap.plugin.tracer.http.HttpComponent">

                  <component-param>

                         <name>trace-filter-active-time</name>

                         <value>-1</value>

                         <description>(ms) timings filter's over time</description>

                  </component-param>

                  <component-param>

                         <name>trace-max-size</name>

                         <value>1000</value>

                         <description>max over-time trace size</description>

                  </component-param>

           </component>

           <component name="MethodComponent" type="org.jwebap.plugin.tracer.method.MethodComponent">

                  <component-param>

                         <name>trace-filter-active-time</name>

                         <value>-1</value>

                         <description>(ms) timings filter's over time</description>

                  </component-param>

                  <component-param>

                         <name>trace-max-size</name>

                         <value>1000</value>

                         <description>max over-time trace size</description>

                  </component-param>

                  <component-param  style="longtext">

                         <name>detect-clazzs</name>

                         <value>

                         com.ali.*;

                         </value>

                         <description>

                         package name and class name that monitored by MethodComponent,

                         e.g.: 'test.*;test.Test' , divided by ';'

                         </description>

                  </component-param>

           </component>

           <component name="JdbcComponent" type="org.jwebap.plugin.tracer.jdbc.JdbcComponent">

                  <component-param>

                         <name>trace-filter-active-time</name>

                         <value>-1</value>

                         <description>(ms) timings filter's over time</description>

                  </component-param>

                  <component-param>

                         <name>trace-max-size</name>

                         <value>1000</value>

                         <description>max over-time trace size</description>

                  </component-param>

                  <component-param  style="longtext">

                         <name>connection-listener</name>

                         <value>

                  org.jwebap.plugin.tracer.http.ServletOpenedConnectionListener;org.jwebap.plugin.tracer.method.MethodOpenedConnectionListener

                         </value>

                         <description>Connection Listener</description>

                  </component-param>

                  <component-param  style="longtext">

                         <name>driver-clazzs</name>

                         <value>org.apache.commons.dbcp.BasicDataSource</value>        

                         <!--

                         <value>com.mysql.jdbc.Driver</value>

                         -->

                         <description>

     

                         </description>

                  </component-param>

           </component>

          

    </plugin>

     

    修改好后重新替换入jar。如下是监控spring.war应用的操作过程。

     

    修改jwebap.xml放到jboss-4.2.2.GA\server\default\deploy\spring.war\WEB-INF

    <?xml version="1.0" encoding="UTF-8"?>

    <jwebap>

           <!--plugins-->

           <plugin name="Tracer" ref="${ABSOLUTE_PATH}/tracer_0.6.1.jar"/>

    </jwebap>

     

    ${ABSOLUTE_PATH} 是内置的变量,不必修改

     

    参考jwebap_0.6.1_all\bin\web-example.xml 修改jboss-4.2.2.GA\server\default\deploy\spring.war\WEB-INF\web.xml

     

    <!-- begin jwebap-->

           <context-param>

                  <param-name>jwebap-config</param-name>

                  <param-value>/WEB-INF/jwebap.xml</param-value>

           </context-param>

           <listener>    

                  <listener-class>org.jwebap.startup.JwebapListener</listener-class>     

           </listener>

           <filter>

                  <filter-name>PageDetectFilter</filter-name>

                  <filter-class>org.jwebap.plugin.tracer.http.DetectFilter</filter-class>

                  <init-param>

                         <param-name>excludeUrls</param-name>

                         <param-value>/detect;/detect/*;*.js;*.jpg;*.htm;*.html;*.gif;*.png;*.css;*.swf</param-value>

                  </init-param>

           </filter>

           <filter-mapping>

                  <filter-name>PageDetectFilter</filter-name>

                  <url-pattern>/*</url-pattern>

           </filter-mapping>

     

           <servlet>

                  <servlet-name>detect</servlet-name>

                  <servlet-class>org.jwebap.ui.controler.JwebapServlet</servlet-class>  

           </servlet>

     

           <servlet-mapping>

                  <servlet-name>detect</servlet-name>

                  <url-pattern>/detect/*</url-pattern>

           </servlet-mapping>

          

           <!-- end jwebap-->

     

    有一点特别注意的是,在被监控的程序如spring.war目录jboss-4.2.2.GA\server\default\deploy\spring.war\WEB-INF\lib加入数据库驱动程序如commons-dbcp.jar,否则无法获取jdbc  trace数据。

     

     

    1.1.3    启动应用及拦截

    启动jboss

    执行应用操作,ie 输入

    http://localhost:8080/spring/detect/console/?null 可以看到jwebap监控效果

    jdbc traces:

     

    http监控

     

     

    Method 监控

     

    1.1.4    已知限制及应用场合

      更多讨论可以在javaeye论坛搜索 jwebap

     

      对于普通的web程序,jwebap支持不错。可以考虑内部系统开发性能优化时应用。

     

    Webx工程只能监控jdbc调用,对于方法和http请求无法拦截.

  • 可与jprofiler/yourkit媲美的java诊断工具Visualvm

    2010-04-21 21:47:35

    http://zorufa876.javaeye.com/blog/625649

     

    一度我曾以为在java profile领域,很难有工具能超越jprofiler yourkit

    相比较jprofiler/ youkit 优势:

    1)      开源免费

    2)      性能开销比jprofiler小很多. kylin性能优化项目中,jprofiler性能损耗大,而visualvm基本不受影响。

    3)      被监控端无需额外安装agent

     劣势:

             没有jprofiler那样直观地树状展现方法调用栈。

     

     由于visualvm远程监控比本地监控少很多功能,所以visualvm建议安装在linux服务器端。

    Visualvm 要求在jdk1.6_07上。

    1.1.1    下载visualvm

           不用jdk 自带的,因为jdk自带的滞后。从https://visualvm.dev.java.net/download.html 下载。

    1.1.2    在被监控服务器上安装visualvm

           先部署好java 6以上环境。

           大部分应用都在linux上,所以visualvm安装在linux目录。

     

    1.1.3    Windows机器上安装xming,输出linux图形化界面

    主要是将linux display定向到windows xming server上。Xming使用请参考http://www.51testing.com/?uid-13997-action-viewspace-itemid-99183

     

     

     

     

    linux shell

     export DISPLAY=windows ip:0

    ./visualvm &

    如:

     

    1.1.4    安装插件

    Tools->plugin

     

     

    1.1.5    设置java 允许jmx 访问

     少这个步骤,则cpu sample会无数据。

      可以设置java jmx选项为无验证。

    -Dcom.sun.management.jmxremote.ssl=false     -Dcom.sun.management.jmxremote.authenticate=false

     

       也可以:

    [admin@QA-145-1 ~]$ ps -ef|grep java

    admin    32289 32281 99 14:06 pts/7    00:09:21 /usr/alibaba/java/bin/java -Dprogram.name=run.sh -server -Xms2g -Xmx2g -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseCompressedOops -XX:+DoEscapeAnalysis -XX:+AggressiveOpts -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Djboss.server.home.dir=/home/admin/kylin/deploy/jboss_server -Djboss.server.home.url=file:/home/admin/kylin/deploy/jboss_server -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl -Dorg.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces.parsers.XML11Configuration -Dcom.sun.management.config.file=/home/admin/kylin/deploy/conf/jmx/jmx_monitor_management.properties -Dapplication.codeset=GBK -Ddatabase.codeset=ISO-8859-1 -Ddatabase.logging=false -Djava.endorsed.dirs=/usr/alibaba/jboss/lib/endorsed -classpath /usr/alibaba/jboss/bin/run.jar:/usr/alibaba/java/lib/tools.jar org.jboss.Main

     

    [admin@QA-145-1 ~]$ cat  /home/admin/kylin/deploy/conf/jmx/jmx_monitor_management.properties |grep -v '#'

    com.sun.management.jmxremote.port=2009

    com.sun.management.jmxremote.ssl=false

    com.sun.management.jmxremote.authenticate=true

    com.sun.management.jmxremote.password.file=/home/admin/kylin/deploy/conf/jmx/jmx_monitor_users.properties

    com.sun.management.jmxremote.access.file=/home/admin/kylin/deploy/conf/jmx/jmx_monitor_roles.properties

    [admin@QA-145-1 ~]$ cat  /home/admin/kylin/deploy/conf/jmx/jmx_monitor_users.properties |grep -v '#'

    monitor monitor

    control control1

     

    [admin@QA-145-1 ~]$ cat  /home/admin/kylin/deploy/conf/jmx/jmx_monitor_roles.properties |grep -v '#'

    monitor   readonly

    control   readwrite

     

    1.1.6    采样cpu 或者memory对象

    点击sample cpu sample检查哪些方法耗时多。

     

     

    Memory sample: 检查哪些类占内存多

     

    这里点击settings设置过滤规则。

     

    1.1.7    安装jconsole plugin

    点击'Add JAR/Folder'按钮,

           添加JDK_HOME/demo/management/JTop/JTop.jar

     

    参考:

    http://zzxanadu.javaeye.com/blog/600183

     

    1.1.8    安装eclipse 插件

     

    https://visualvm.dev.java.net/eclipse-launcher.html

     

    下载解压到eclipse安装目录。

     

     

    运行应用程序,弹出的launcher 选择visualvm,将激活visualvm.

  • 定制 findbugs规则

    2010-04-04 15:51:41

    这类文章极少,字节码操作需要对becl库及jvm 字节码操作有一定常识。参考:

    http://blog.csdn.net/lywybo/archive/2010/03/01/5335748.aspx

    http://javadevelopmentforthemasses.blogspot.com/2008/09/custom-findbugs-detectors-and-maven.html

    https://www.ibm.com/developerworks/cn/java/j-findbug2/

     

    ibm介绍的原理实用,但配置过时;支付宝朋友写的message.xml/findbugs.xml不够详细且有笔误。

     

    1.1       准备

    下载findbugs: http://sourceforge.net/projects/findbugs/files/findbugs/1.3.9/findbugs-1.3.9.zip/download

     

    修改build.xml ,去除所有的validate依赖。执行ant 编译。

    eclipse引入findbugs工程

     

    1.2       实现类

    直接在findbugs目录中增加类

     

    package edu.umd.cs.findbugs.detect;

    import org.apache.bcel.classfile.Code;

    import edu.umd.cs.findbugs.BugInstance;

    import edu.umd.cs.findbugs.BugReporter;

    import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;

     

    /**

     * @author bo

     * 这个规则类用于判断System.outSystem.error这种情况

     */

    public class ForbiddenSystemClass extends OpcodeStackDetector {

     BugReporter bugReporter;

     

     public ForbiddenSystemClass(BugReporter bugReporter) {

      this.bugReporter = bugReporter;

     }

     

     /**

      * visit方法,在每次进入字节码方法的时候调用

      * 在每次进入新方法的时候清空标志位

      */

     @Override

     public void visit(Code obj) {

      super.visit(obj);

     }

     

     /**

      * 每扫描一条字节码就会进入sawOpcode方法

      *

      * @param seen  字节码的枚举值

      */

     @Override

     public void sawOpcode(int seen) {

      if (seen == GETSTATIC) {

       if (getClassConstantOperand().equals("java/lang/System")

               && (getNameConstantOperand().equals("out") || getNameConstantOperand().equals("error"))) {

        BugInstance bug = new BugInstance(this, "ALP_SYSTEMCLASS", NORMAL_PRIORITY).addClassAndMethod(this)

                .addSourceLine(this, getPC());

        bug.addInt(getPC());

        bugReporter.reportBug(bug);

       }

      }

     }

    }

    1.3       修改etc目录配置文件findbugs.xmlmessage.xml

    不支持中文注释。

    findbugs.xml 增加内容。

    <Detector class="edu.umd.cs.findbugs.detect.ForbiddenSystemClass" 

       speed="fast"

         reports="ALP_SYSTEMCLASS"

         hidden="false" />

     

    <BugPattern abbrev="LIANGJZFORBIDDENSYSTEMCALSS" type="ALP_SYSTEMCLASS" category="EXPERIMENTAL"  />

     

     

    Message.xml增加:

     

    <Detector class="edu.umd.cs.findbugs.detect.ForbiddenSystemClass">

       <Details>

        <![CDATA[

        <p>category:detector find System.out/System.error

        <p>please use log4j

        ]]>

       </Details>

      </Detector>

     

    <BugPattern type="ALP_SYSTEMCLASS">

        <ShortDescription>short desc:System.out/error</ShortDescription>

        <LongDescription>class={0},method {1}long desc:System.out,please use log4j</LongDescription>

        <Details>

      <![CDATA[

        <p>detail info see log4j document</p>

      ]]>

        </Details>

      </BugPattern>

     

     

     

    1.4       findbugs图形化界面测试

    点击bin/finbugs.bat,打开扫描的.class目录。看到扫描带 System.out 或者System.error.class放到experimental类错误时,验证成功。

     

    1.5       替换eclipse findbugs-plugin.jar文件

    winrar打开

    D:\devtools\eclipse_3.5.1\plugins\edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821\findbugs-plugin.jar message.xml,findbugs.xml,z加入二进制的edu.umd.cs.findbugs.detect. ForbiddenSystemClass

     

    重启elipse,还需要确保experimental类的错误能在findbugs窗口展现: windows->preferences->java->findbugs->reporter configuration上的experimental选项勾上。

     

     

     执行findbugs扫描.class,看到结果出现..

     

  • 对cppcheck做简单扩展支撑非线程安全函数静态扫描

    2010-04-03 22:49:19

     
      下载 http://sourceforge.net/projects/cppcheck/files/cppcheck/1.42/cppcheck-1.42.tar.gz/download
    1 风格类检查函数放在checkdangerousfunctions.h  checkdangerousfunctions.cpp中
    2 目前只支持gets/scanf/mktemp函数。原来的实现方式为了增加一个非线程安全函数,需要增多>=3个文件
    3 修改头文件checkdangerousfunctions.h

    #define MAX_FUNCS_NUM 200
    #define MAX_FUNC_LEN 48
    extern const char  dangerous_funcs[MAX_FUNCS_NUM][MAX_FUNC_LEN];

    class CheckDangerousFunctions : public Check
    {
    private:
        /** Error Messages.. */
     
     
        void dangerousFunctionnotsafethread(const Token *tok);
     
        bool isDangerousFunction(const Token * tok);

        void getErrorMessages()
        {
           ...
            dangerousFunctionnotsafethread(0);
          ...
        }

    }

    4 实现实现文件checkdangerousfunctions.cpp:

    #include "checkdangerousfunctions.h"
    #include <string.h>
    //---------------------------------------------------------------------------
    const char dangerous_funcs[MAX_FUNCS_NUM][MAX_FUNC_LEN]={"gets (", "asctime (","getc_unlocked (", "getutxid (", "setgrent (", "basename (","getchar_unlocked (", "getutxline (",
        "setkey (", "catgets (" }; //其他更多继续

    ...

    void CheckDangerousFunctions::dangerousFunctions()
    {
        for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
        {
            if( isDangerousFunction(tok))
           {
                dangerousFunctionnotsafethread(tok);
          }
        }
    }
    //---------------------------------------------------------------------------
    bool CheckDangerousFunctions::isDangerousFunction(const Token * tok)
    {
      bool isMatch=false;
      for (int i=0;i <MAX_FUNCS_NUM  &&  ( false !=strcmp(dangerous_funcs[i],"") ) ;i++)
      {
        if (Token::simpleMatch(tok,dangerous_funcs[i]))
        {
           isMatch=true;
           break;
        }
      }
      return isMatch;
    }


    void CheckDangerousFunctions::dangerousFunctionnotsafethread(const Token *tok)
    {
        std::cout<<"token="<< tok->str()<<std::endl;
        std::string funcname="dangerousFunction";
        std::string str_tip="Found \'";
        funcname.append(tok->str());
        str_tip.append(tok->str());
        str_tip.append("\'. You should use ");
        str_tip.append(tok->str());
        str_tip.append("_s instead.for b2bqa");
        const std::string c_func(funcname);
        const std::string c_tip(str_tip);
        reportError(tok, Severity::style, c_func, c_tip);
    }
    ...

    5 应用
    编译
    make;
    执行
    ./cppcheck -s 文件或者目录

    cpplint(http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py)则在扩展方面更好些。


  • selenium 和webdriver_入门实践

    2010-04-01 20:38:01

       我们一直非常强调建立以底层为核心的分层自动化测试体系,虽然web ui自动化在破页、美感方面不值得投入,但是由于目前大量业务逻辑在web ui,所以合适的web ui测试自动比率也是非常关键的。


      watir设计理念和selenium有很大差异。watir便于测试工程师快速上手,对ie支持非常好;而selenium擅长浏览器兼容性。

       参考:

    http://code.google.com/p/meimei/wiki/SeleniumUsage

    http://blog.csdn.net/shendl/archive/2009/03/08/3969750.aspx

    http://blog.csdn.net/shendl/archive/2009/03/08/3969750.aspx

    http://www.ibm.com/developerworks/cn/java/j-lo-selenium/

    http://www.onlymarshall.com/tag/selenium/

    扩展http://xace.javaeye.com/blog/579722

     

    http://code.google.com/p/selenium/downloads/list下载selenium-server-standalone-2.0a2.jar selenium-server-standalone-2.0a2.jar

     

    Webdriver 是对selenium的一个封装,更加友好。Selenium2.0已经把webdriver合并进去。

     执行http://code.google.com/p/selenium/wiki/GettingStarted 代码出错。

    1        webdriver错误:

    Exception in thread "main" org.openqa.selenium.WebDriverException: Cannot find firefox binary in PATH. Make sure firefox is installed.

     解决办法:指定firefox执行文件入系统属性。

         System.setProperty("webdriver.firefox.bin","D:/Program Files/Mozilla Firefox/firefox.exe");

            WebDriver driver = new FirefoxDriver();

           

    2        解决selenium 错误:

     

    下载样例代码http://www.ibm.com/developerworks/cn/java/j-lo-selenium/

    Selenium server需要在java1.5+环境下执行。

    启动selenium server

    java -jar selenium-server-standalone-2.0a2.jar。运行java selenium rc 有错

     

    java.lang.RuntimeException: Could not start Selenium session: Failed to start new browser session: java.lang.RuntimeException: Firefox 3 could not be found in the path!

    Please add the directory containing ''firefox.exe'' to your PATH environment

    variable, or explicitly specify a path to Firefox 3 like this:

    *firefox3c:\blah\firefox.exe

     

      解决办法:指定firefox执行文件路径。

            selenium = new DefaultSelenium("localhost", 4444, "*firefox3 D:/Program Files/Mozilla Firefox/firefox.exe",

                    "http://www.baidu.com");

     

  • 基于规则的svn diff分析结果差异提升code review效率思路

    2010-03-16 21:25:31

       在某些类型的项目中,比如增强安全、更换底层api的项目,修改涉及大量文件,有较多的更改都是相对机械、有规律的。

     如果能够将不符合特定正则表达式的差异结果梳理出,作为重点code review的内容,将提升code review效率。

     甚至更勇敢点,扫描源码文件发现符合规则的行直接更换为新行,该部份代码编写工作都省却了。

     自动化比较的动作本质是对如下几个操作做封装.

    1) 列举svn url下所有的文件

       [liangjz@b2b_plat_1367 cnmarket_bops_security_dev]$ svn list  http://svn/repos/ali_cn/bops/ezra/branches/20100222_cnmarket_bops_security_dev/bops-deploy/templates/topic/screen

    sTTopic.vm

    ...

    2) 对每个文件都获取修订记录

    [liangjz@b2b_plat_1367 cnmarket_bops_security_dev]$ svn log http://svn/repos/ali_cn/bops/ezra/branches/20100222_cnmarket_bops_security_dev/bops-deploy/templates/topic/screen/sTTopic.vm  --stop-on-copy
    ------------------------------------------------------------------------
    r193523 | wb_chao.qian | 2010-02-26 09:15:44 +0800 (??, 2010-02-26) | 1 DD
    r192077 | bruce.fany | 2010-02-22 12:55:08 +0800 (ò?, 2010-02-22) | 1 DD

    3) 比较基线及最新的修订记录

    [liangjz@b2b_plat_1367 cnmarket_bops_security_dev]$ svn diff -r 192077:193523  http://svn/repos/ali_cn/bops/ezra/branches/20100222_cnmarket_bops_security_dev/bops-deploy/templates/topic/screen/sTTopic.vm
    Index: sTTopic.vm
    ===================================================================
    --- sTTopic.vm  (°?±? 192077)
    +++ sTTopic.vm  (°?±? 193523)
    @@ -214,6 +214,7 @@
                    <input type="hidden" name="picname" value="" />
    +                     $xyz.hiddenField
             <tr>
                            <td colspan="6" class="f10"><strong>?ù±?D??¢</strong></td>

     我们需要对+或者-开头的差异内容做大量的字符操作分析。这个是难度最大的,思路一般是结合正则表达式及字符串回溯、前移。

     自动化svn操作用java实现的话,有2种方式

    1) 借用svnkit 包。不需要svn 客户端

    2) 采用java Runtime.exec() api直接执行svn 客户端命令,需要依赖svn 客户端

     上述机械操作应用的范围窄,但是较大减少人肉操作:)

     

  • 提高测试范围判定准确度思路__复杂度、依赖关系系数做参考

    2010-02-26 00:14:15

     

    1应用javancss/metric jdepent度量java代码复杂度、依赖关系

    2 复杂度变化大的函数,基于风险策略确保被执行. 被执行可用emma或者clover工具度量

    3 建立度量数据趋势图,可集成在hudson持续集成环境上更加直观
1611/9123456789>
Open Toolbar