利用TestNG(Java)组建测试——监控Jabber企业聊天平台

1.  实际应用概述

Jabber是一个基于开源XMPP议的企业级即时通讯架构,它的典型商业应用为思科Jabber服务,其为沃尔玛、通用等300多万客户提供企业通讯服务。 而基于TestNG的针对Jabber的实时监控工具,也已经成功应用于基于Jabber的大型企业级产品线上,为这个世界的沟通,贡献力量。

2.   设计思想概述:

针对实际问题,去选用适当的方法 —— 这里仅引用 @项目管理智汇团2014年6月21日的新浪微博:在“寻找解决方案时,记住要从问题出发,而不要从特定的实现方法出发。具体来说,要寻找: 源代码控制工具,而不是SVN; 快速应用程序开发手段,而不是Rubyon Rails;富Internet应用开发框架,而不是Flex;对象关系映射库,而不是Hibernate。”

而这里讨论的实际问题,是在大规模分布式架构的产品线上,如何“稳定、快速、精确的发现和定位某个故障组件”这个实际问题。我们将这个问题分解为1)快速设计测试Case 2)精确定位故障  3)稳定运行

1)     快速设计测试Case:这里笔者所在的测试团队选择TestNG……

a.      比较同样大名鼎鼎的JUnit,TestNG虽然出现较晚,但是却能够包容JUnit的优点和补充JUnit在细化的功能测试方面的不足。尤其是它扩展了JavaAnnotation, 从而使它能提供的针对测试的Annotation十分丰富,如@BeforeSuite@BeforeTest 等等,用这些Annotation作为“积木”来搭建测试Case很快捷。

b.     笔者所在的产品开发敏捷团队,在做产线监控前端的功能测试时,使用的就是TestNG。“我们要站在巨人的肩膀上”,所以运用TestNG将功能测试Case中的典型Case提取出来,成为监控Case,顺理成章。

c.      TestNG的Report类,笔者感觉定制起来也很快捷,这里将在3.2小节中详细叙述。

2)     精确定位故障:利用STAF或cron 这一Linux的内置服务,来分别启动针对不同产线组件的监控程序。这是典型的“分治法”——“就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。”(分治法定义——摘自搜狗百科)

落实到这里阐述的案例,即每个监控子程序(后面会表述为测试PlugIn),只负责它所测试的特定产线的特定组件,而调度程序将这些子测试结果进行汇总,才达成对整个产线集群的完整监控。

3)     稳定运行

a.      前后端分离,利用稳定的后台service来管理监督各个监控子程序的运行, 前端则负责人机界面和测试PlugIn管理。 

b.     利用前端的Html页面+Tomcat server进行各个测试PlugIn的插入和管理——即Management Server。

c.      后端的Staf server利用STAF进行自动化测试分布式运行 (可参考http://www.cnblogs.com/zhangfei/archive/2013/07/03/3169139.html-- 《如何用STAF进行自动化测试分布式运行 》)

d.     后台service和前端server,它们都采用hot standby模式,即1台server挂掉之后,第2台server会接替第1台的管理工作。

这里仅给出Tomcat cluster的冗余配置方法供大家参考:具体可参看 http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html中的“configure hot spare workers” 

            下面是简单的设计框架:

                    

3.  具体实现技术概述

               

3.1 将TestNG的测试suite组装成3.3中STAF可执行的jar文件:

具体 如何利用TestNG来组装包含业务逻辑的实际测试case,这在网上有很多blog和资料可供查询,这里就不累述。在本案例中,笔者重点说的是如何来利用maven的assembly生成可执行jar的技巧:

1.      需要在maven的 pom.xml 中的< plugins > node中,定义:

 

<plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <descriptors>
                            <descriptor>exe.xml</descriptor>
                        </descriptors>
                        <archive>
                            <manifestFile>META-INF/MANIFEST.MF</manifestFile>
                        </archive>
                    </configuration>
 </plugin>

2.      需要定义相应的 maven goal 为:

clean assembly:assembly

 

3.      在exe.xml文件中,定义assembly的参数:

<assembly>
   <id>exe</id>
   <formats>
       <format>jar</format>
   </formats>
   <includeBaseDirectory>false</includeBaseDirectory>
   <dependencySets>
       <dependencySet>
           <outputDirectory></outputDirectory>
           <outputFileNameMapping></outputFileNameMapping>
           <unpack>true</unpack>
           <scope>runtime</scope>
           <includes>
           </includes>
       </dependencySet>
    </dependencySets>
   <fileSets>
       <fileSet>
           <directory>target/classes</directory>
           <outputDirectory></outputDirectory>
       </fileSet>
   </fileSets>
</assembly>


4.      在MANIFEST.MF中,定义该maven项目的主执行类

Main-Class: com.taotao.jabber.cases.MctJarMain

5.      以下是这几个configuration文件的具体位置:


6.      建立一个主程序即com.taotao.jabber.cases.MctJarMain来装载和运行所有的TestNGTest Suite :

public class MctJarMain {
    public static void main(String[] args) throws IOException
    {       
        TestNG tng=new TestNG();
        tng.setOutputDirectory("./testngResult");
        List<Class> listnerClasses = new ArrayList<Class>();

        listnerClasses.add(CustomReporter.class);
        tng.setListenerClasses(listnerClasses);

        Class[] classArray = {com.taotao.jabber.cases.TestPresence.class } ;
        for(int i = 0 ; i< classArray.length ; i ++){
            tng.setTestClasses( new Class[]{ classArray[i] } ) ;
            tng.run();
        }
    }

上述的这个方法,笔者基本上参考了http://left.subtree.org/2008/01/24/creating-executable-jars-with-maven/,如果大家在dependencySets中需要更深入的定制的话,可以进一步查阅。


3.2 定制Report类:

在主程序中,我们用到了CustomReporter这个类,它的作用是在所有TestSuite执行完成后,来对每个组件测试的结果,进行归纳总结。

它的重要输入参数是suites,所有测试后产生的测试结果等信息,都存储在这个List中:

public class CustomReporter implements IReporter{
    @Override
    public void generateReport(List xmlSuites, List suites,
                               String outputDirectory) {
            ISuite suite = (ISuite) suites.get(0) ;
            for( ISuiteResult result : suite.getResults().values()){
                ITestContext context = result.getTestContext();
                IResultMap passedTests = context.getPassedTests();
                IResultMap failedTests = context.getFailedTests();
                IResultMap failedConfigurations = context.getFailedConfigurations();

                // Similar to  if(failedConfigurations.size() > 0 ){...}
                if(failedTests.size() > 0 ){
                    // Print all test stackTrace etc....
                    for( ITestResult r: failedTests.getAllResults()) {
                        printOutErrorDetails(r) ;
                     }
                    exit(1) ;
                }
          } }  }
 
 


3.3利用STAF将每个独立的测试Plugin组装起来:

 最后,我们简单介绍一下STAF在项目中的运用——STAF在这个测试系统中,扮演了 “胶水” 的角色,从而使针对各产品组件的分布式的定时测试成为可能:

1)     利用STAF的监控功能,看管每个测试Plugin所触发的测试jar的进程

2)     利用STAF的定时启动功能,定时触发每个测试Plugin并及时查看测试结果

3)     利用STAF的文件获取功能,查看某个特定的失败了的测试Plugin测试过程的相应log…

 

讲完,希望本博客中的设计思想和技术细节,对大家的学习和工作有所裨益。

觉得好您就点赞,帮助笔者赢取此次“CSDN博客大赛的奖金”。我夏天里的每一根“巧乐滋生”,都源于您的爱!羡慕



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值