您的位置:首页 > 其它

Jmeter动态加载测试类

2016-06-29 15:14 399 查看
继上篇文章《Jmeter+H2Database动态部署JAR包到代理端》实现了测试业务jar包的动态部署后,再不重启代理端Jmeter的情况下,jar的变化内容仍无法自动加载到Jmeter内存,所以还是不能实现一次启动,动态更新的目的。

 

因为,Jmeter在启动的时候会自动加载lib目录下的jar包,如果不重启,目录下更新的jar包也不能加载到内存。所以,要实现类的动态加载,必须在Jmeter测试类中实现业务类的重载。

 

即在Jmeter测试类中的setupTest()方法中要自定义代码实现业务类的加载。

 

此处以一个简单例子说明实现过程:

编写要被测业务类:TransDemo.java

package perftest.jmeter.trans;

 

public
class
TransDemo {

        

         public String action(){

                   Stringstr =
"action1st.";

                   System.out.println(str);

                   return
str;

         }

 

         public
void
init() {

                   System.out.println("testingstart....");

         }

 

         public
void
end() {

                   System.out.println("testingover!!!!");

        

         }

}

 

将其导出为perftest-trans.jar,将这个包放到jmeter/lib目录以外的地方。如:c:/perftest-trans.jar (不能放在Jmeter/lib目录下)。

编写Jmeter测试类:TransDemoActions.java

package perftest.jemter.action;
 
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
 
public
class
TransDemoActions extends AbstractJavaSamplerClient{
    SampleResultresult=
null
;
   
    public Class<?>trans =
null;
    Arguments    params=
null
;
    Method  methodInit=
null
;
    Method  methodAction=
null
;
    Method  methodEnd=
null
;
    MyClassLoader  classLoader=
null;
    Object   newTrans=
null
;
    /**
     * 自定义类加载方法
     * @param jarpath
     * @param classpath
     */
    public
void
loadClass(String[] jarpath,Stringclasspath){   

        URL[]  urls= new  URL[] {};
        classLoader =
new
MyClassLoader(urls,null);
       
        try {
       
        for(String  jar:jarpath){
            classLoader.addJar(new File(jar.trim()).toURI().toURL());
            System.out.println("load jar file : "+jar.trim());
        }
           
            trans =
classLoader.loadClass(classpath);
            System.out.println("load class file : "+classpath);
            methodInit =
trans.getDeclaredMethod("init");
            methodAction =
trans.getDeclaredMethod("action");
            methodEnd =
trans.getDeclaredMethod("end");       
            boolean  accessible =
methodInit.isAccessible(); 
            if(accessible ==false){
                methodInit.setAccessible(true);
            }
           
            newTrans =
trans.newInstance(); 
        } catch (Exceptione) {
            e.printStackTrace();
        }
    }
    /**
     * 自定义jmeter外部参数
     */
    public Arguments  getDefaultParameters() {
        Arguments  params=
new   
Arguments();      
        params.addArgument("TRANS_JARPATH","c:/perftest-trans.jar");
        params.addArgument("TRANS_CLASSPATH","perftest.jmeter.trans.TransDemo");
        returnparams;
    }
   
    public
void   
setupTest(JavaSamplerContext arg0) {
        try {          
           loadClass(arg0.getParameter("TRANS_JARPATH").split(","),arg0.getParameter("TRANS_CLASSPATH"));           
            //通过反射调用TestDemo的init()方法,下同
            methodInit.invoke(newTrans);          
           
        }catch(IllegalAccessException   e) {
            e.printStackTrace();
        }catch(IllegalArgumentException   e) {
            e.printStackTrace();
        }catch(InvocationTargetException  e) {
            e.printStackTrace();
        }
    }
 
   
    @Override
    public SampleResult    runTest(JavaSamplerContextarg0) {
        try {
            methodAction.invoke(newTrans);
        }catch(IllegalAccessException  e) {
            e.printStackTrace();
        }catch(IllegalArgumentException   e) {
            e.printStackTrace();
        }catch(InvocationTargetException   e) {
            e.printStackTrace();
        }
        returnresult;
    }
   
    public
void   
teardownTest(JavaSamplerContext
arg0) {
        try {
            methodEnd.invoke(newTrans);
        }catch(IllegalAccessException   e) {
            e.printStackTrace();
        }catch(IllegalArgumentException   e) {
          
b21d
  e.printStackTrace();
        }catch(InvocationTargetException    e) {
            e.printStackTrace();
        }catch (Exceptione) {
            e.printStackTrace();
        }
    }
    /**
     * 自定义内部类实现动态加载class
     * @author
     *
     */
    static
class
MyClassLoader extends URLClassLoader {
 
        public MyClassLoader(URL[]urls) {
            super(urls);
        }
 
        public MyClassLoader(URL[]urls, ClassLoader
parent) {
            super(urls,parent);
        }
 
        public
void
addJar(URL url) {
            this.addURL(url);
        }
   }
}

 

将其导出为perftest-actons.jar,并将它放入<jmeterPath>/lib/ext下,在Jmeter启动时可以自动发现这个测试类: perftest.jemter.action.TestDemoActons 。

 

启动Jmeter,建立测试计划和添加线程组及“Java请求”

线程组大小设置为1,线程循环次数设置2:即一个虚拟用户进行2次迭代。

运行测试

运行测试可以看到System.out.println的输出结果:



修改被测业务类TransDemo的action()方法

public String action(){

                   //此处修改打印输出字符

                   String   str =
"actionsecond.";

                   System.out.println(str);

                   return
str;

         }

重新将TransDemo.class打包为perftest-trans.jar,并覆盖前面的c:/perftest-trans.jar

 

重新运行测试

在不关闭和重启Jmeter的情况下,再次执行测试,可以看到输出信息已经改变为“action seconde.”:

 


小结:

所以要实现类的动态加载,必须在Jmeter测试类AbstractJavaSamplerClient(java请求)中使用URLClassLoader实现被测业务类的重新加载,并使用invoke()方法调用业务方法。

 

自此,通过《Jmeter+H2Database动态部署JAR包到代理端》及本篇可以为分布式测试中的众多代理端实现被测业务(jar)包的实时更新及业务测试类(class)的热加载。

 

再也不用重启100+台Jmeter代理端而烦恼了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: