此示例代码块实施 Process Executor 测试类型,可用于启动任何可执行文件和扩展已发布的 ExtProcessTestLaunchBean 类。
package com.borland.sctm.testlauncher; import java.io.File; import java.io.IOException; import java.util.ArrayList; import com.segue.tm.published.api.testlaunch.ExtProcessTestLaunchBean; import com.segue.tm.published.api.testlaunch.TestLaunchResultDrain; /** * Implements an Silk Central test type that can be used to launch * any executables, for example from a command line. * Extends Silk Central published process test launcher class, * see Silk Central API Specification (in Help -> Documentation) for * further details. */ public class ProcessExecutor extends ExtProcessTestLaunchBean { // test properties that will be set by Silk Central using appropriate setter // methods (bean convention), // property names must conform to property tags used in the XML file /** * Represents property <command> defined in ProcessExecutor.xml. */ private String command; /** * Represents property <arguments> defined in ProcessExecutor.xml. */ private String arguments; /** * Represents property <workingfolder> defined in ProcessExecutor.xml. */ private String workingfolder; /** * Java Bean compliant setter used by Silk Central to forward the command to be * executed. * Conforms to property <command> defined in ProcessExecutor.xml. */ public void setCommand(String command) { this.command = command; } /** * Java Bean compliant setter used by Silk Central to forward the arguments * that will be passed to the command. * Conforms to property <arguments> defined in ProcessExecutor.xml. */ public void setArguments(String arguments) { this.arguments = arguments; } /** * Java Bean compliant setter used by Silk Central to forward the working * folder where the command will be executed. * Conforms to property <workingfolder> defined in * ProcessExecutor.xml. */ public void setWorkingfolder(String workingfolder) { this.workingfolder = workingfolder; } /** * Main plug-in method. See Silk Central API Specification * (in Help > Documentation) for further details. */ @Override public boolean execute(long time, TestLaunchResultDrain context) throws InterruptedException { try { String[] cmd = getCommandArgs(context); File workingDir = getWorkingFolderFile(context); String[] envVariables = getEnviromentVariables(context); int processExitCode = runExternalProcess(cmd, envVariables, workingDir, context.getLog()); boolean outputXmlFound = handleOutputXmlIfExists(context); if (! outputXmlFound && processExitCode != 0) { // if no output.xml file was produced, the exit code indicates // success or failure context.publishMessage(TestLaunchResultDrain.SEVERITY_ERROR, "Process exited with return code " + String.valueOf(processExitCode)); context.updateErrors(1, 0); // set error, test will get status 'failed' } } catch (IOException e) { // prints exception message to Messages tab in Test Run // Results context.publishMessage(TestLaunchResultDrain.SEVERITY_FATAL, e.getMessage()); // prints exception stack trace to 'log.txt' that can be viewed in Files // tab e.printStackTrace(context.getLog()); context.publishErrors(1, 0); return false; // set test status to 'not executed' } return true; } /** * Initializes environment variables to be set additionally to those * inherited from the system environment of the Execution Server. * @param context the test execution context * @return String array containing the set environment variables * @throws IOException */ private String[] getEnviromentVariables(TestLaunchResultDrain context) throws IOException { String[] envVariables = { "SCTM_EXEC_RESULTSFOLDER=" + context.getTempResultsDir().getAbsolutePath(), "SCTM_EXEC_SOURCESFOLDER=" + sourceAccess().getTestContainerRootDir().getAbsolutePath(), }; return envVariables; } /** * Let Silk Central parse the standard report xml file (output.xml) if exists. * See also Silk Central Web Help - Creating a Test Package. A XSD file * can be found in Silk Central Help -> Tools -> Test Package XML Schema * Definition File * @param context the test execution context * @return true if output.xml exists * @throws IOException */ private boolean handleOutputXmlIfExists(TestLaunchResultDrain context) throws IOException { String outputFileName = context.getTempResultsDir().getAbsolutePath() + File.separator + TestLaunchResultDrain.OUTPUT_XML_RESULT_FILE; File outputfile = new File(outputFileName); boolean outputXmlExists = outputfile.exists(); if (outputXmlExists) { context.parseStdResultFile(outputfile); context.publishMessage(TestLaunchResultDrain.SEVERITY_INFO, String.format("output.xml parsed from '%s'", outputFileName)); } return outputXmlExists; } /** * Retrieves the working folder on the Execution Server. If not configured * the results directory is used as working folder. * @param context the test execution context * @return the working folder file object * @throws IOException */ private File getWorkingFolderFile(TestLaunchResultDrain context) throws IOException { final File workingFolderFile; if (workingfolder != null) { workingFolderFile = new File(workingfolder); } else { workingFolderFile = context.getTempResultsDir(); } context.publishMessage(TestLaunchResultDrain.SEVERITY_INFO, String.format("process is exectued in working folder '%s'", workingFolderFile.getAbsolutePath())); return workingFolderFile; } /** * Retrieves the command line arguments specified. * @param context the test execution context * @return an array of command line arguments */ private String[] getCommandArgs(TestLaunchResultDrain context) { final ArrayList<String> cmdList = new ArrayList<String>(); final StringBuilder cmd = new StringBuilder(); cmdList.add(command); cmd.append(command); if (arguments != null) { String[] lines = arguments.split("[\\r\\n]+"); for (String line : lines) { cmdList.add(line); cmd.append(" ").append(line); } } context.publishMessage(TestLaunchResultDrain.SEVERITY_INFO, String.format("executed command '%s'", cmd.toString())); context.getLog().printf("start '%s'%n", cmd.toString()); return (String[]) cmdList.toArray(new String[cmdList.size()]); } }