【JTharness4_4_0】【7.如何让harness执行自定义格式的脚本】

来源:互联网 发布:movist for mac 1.4.2 编辑:程序博客网 时间:2024/05/22 08:09

如下表所示,在JavaTestHarness中执行的脚本都必须实现Test接口,并且返回一个Status。这两个类都是com.sun.javatest包下面的,因此开发的时候必须引用javatest.jar这个包。但是实际开发的时候,脚本其实和javatest.jar应该是没有任何关系的,我们应该让他们解耦。

package com.sun.demots.tests.bignum;

import java.io.PrintWriter;

import com.sun.javatest.Status;

import com.sun.javatest.Test;

import com.sun.demoapi.BigNum;

/**

 * A test for com.sun.demoapi.BigNum.add.

 *

 * @test

 * @sources AddTest.java

 * @executeClass com.sun.demots.tests.bignum.AddTest

 */

public class AddTest implements Test

{

    public static void main(String[] args) {

    PrintWriter err = new PrintWriter(System.err, true);

    Test t = new AddTest();

    Status s = t.run(args, null, err);

    s.exit();

    }

   

    public Status run(String[] args, PrintWriter out, PrintWriter err) {

    // save error stream to which to write error messages

    this.err = err;

 

    boolean ok = true;

 

    ok = ok & test("-12345678901234567890", "-12345678901234567890", "-24691357802469135780");

    ok = ok & test("-12345678901234567890",           "-1234567890", "-12345678902469135780");

[…]

    if (ok)

        return Status.passed("OK");

    else

        return Status.failed("one or more test cases failed");

}

 


















1.  自定义脚本的格式

下面设计一种脚本格式,让该脚本与javatest.jar完全没有关系,但是能被harness执行。脚本格式如下:

/**

 * 测试脚本Test1

 * @author jingping.yi

 *

 */

public class Test1 {

    /**

     * 测试脚本执行时执行的方法。

     * @return如果脚本通过,返回trueharness界面中显示绿色;

     *         如果脚本不通过,返回falseharness界面中显示红色

     * @throws Exception如果脚本执行过程抛出异常,则脚本异常,

     *                 harness界面中显示蓝色

     */

    public boolean run() throws Exception{

        […执行过程…]

       return false;

    }

}

如上所示。测试人员只要将测试脚本写在run方法中,然后通过控制返回值true/false或者抛出异常来表示脚本通过/不通过或者执行异常。这种方式和返回Status对象除了没有message,其他的是完全一样的。

2.  实现harness与自定义脚本的中间层

因为harness能处理的还是Status对象,所以我们给仍要给上层返回Status对象。但是下层的脚本只能返回true/false/Exception,所以应该写一个中间层,将true/false/Exception转化成Status对象。这里要用到反射的技术,代码如下:

package com.toast.javatest.script;

 

import java.io.PrintWriter;

 

import com.sun.javatest.Status;

import com.sun.javatest.Test;

 

public class ToastExec implements Test {

    public static void main(String[] args){

        PrintWriter out = new PrintWriter(System.out,true);

        PrintWriter err = new PrintWriter(System.err,true);

        Test t = new ToastExec();

        Status s = t.run(args, err, out);

        s.exit();

    }

 

    /**

     * 要求arg0的第1个参数是完整的带包路径的类名。

     */

    @Override

    public Status run(String[] arg0, PrintWriter arg1, PrintWriter arg2) {

       Status s = null;

       Boolean res = false;

       // 脚本的类名和方法名

       String className = arg0[0];

       String methodName = "run";

       // 使用反射的方式调用脚本的run方法

       try {

           Class executeClass = Class.forName(className);

           java.lang.reflect.Method runMethod = executeClass.getMethod(methodName);

           res = (Boolean) runMethod.invoke(executeClass.newInstance());

          

           // 将执行结果,返回给Harness

            if (res)

                s = Status.passed("执行成功");

            else

                s = Status.failed("执行失败");

       } catch (Exception e) {

           e.printStackTrace();

           s = Status.error("执行过程发生异常,请检查异常信息");

       }

       return s;

    }

}

 

3.  让harness调用中间层

在harness原来的设计中,是让harness直接执行脚本。现在改为让harness去调用中间层(ToastExec),然后中间层(ToastExec)执行脚本,最后将执行结果包装成Status返回给harness。为了达到这个目的,需要更改之前的ToastInterview中的内容。

在配置界面中,当我们选择使用OtherVM on the same computer方式执行脚本的时候,执行的命令是cmd = getOtherVMExecuteCommand();方法的内容如下:

private String getOtherVMExecuteCommand() {

    char fs = File.separatorChar;

    char ps = File.pathSeparatorChar;

 

    StringBuffer sb = new StringBuffer();

    sb.append("com.sun.javatest.lib.ExecStdTestOtherJVMCmd ");

    File jvm = qJVM.getValue();

    sb.append(jvm == null ? "unknown_jvm" : jvm.getPath());

    sb.append(" -classpath $testSuiteRootDir" + fs + "lib" + fs + "jtdemots.jar" + ps

       + "$testSuiteRootDir" + fs + "lib" + fs + "demoapi.jar" + ps

       + "$testSuiteRootDir" + fs + "lib" + fs + "javatest.jar ");

    sb.append("$testExecuteClass $testExecuteArgs");

    return sb.toString();

    }

将红色的那两行改成:

sb.append(" -classpath $testSuiteRootDir" + fs + "lib" +fs + "TOAST.jar" + ps

                   + "$testSuiteRootDir" + fs + "lib" +fs + "javatest.jar" + ps

                   + "$testSuiteRootDir" + fs + "classes ");

sb.append(" com.toast.javatest.script.ToastExec$testExecuteClass $testExecuteArgs");

这样在harness就会将testsuite根目录下的classes目录加进classpath中,并且在执行“java.exe$testExecuteClass $testExecuteArgs”时,就改成了“java.exe com.toast.javatest.script.ToastExec $testExecuteClass$testExecuteArgs”,从直接执行脚本的方式改成了调用中间层执行脚本。

4.  打包执行

将TOAST工程重新打包,放到demoTS\lib下。然后写三个脚本:一个通过,一个失败,一个异常。将java脚本文件拷贝到test目录下,将对应的class连同包路径文件夹拷贝到demoTS\classes下面,。点击run.bat,打开workdir,load配置文件。运行,结果如下所示:

上图失败、通过、异常三份天下的格局证明我们的设计成功了。

5.  更多扩展

用上面这种方式,除了可以执行自定义的java脚本,也可以执行其它任何一种脚本(如C\C++\TXT\python等)。只要有对应的编译执行器就行了。

操作方法就是将中间层(ToastExec)用反射执行java脚本那一段,改成新开一个进程,用第三方的编译执行器执行对应的脚本,然后通过进程的exitCode来判断脚本执行失败还是成功。

原创粉丝点击