【问题标题】:Executing a Java jar file from within a SoapUI groovy script not working从 SoapUI groovy 脚本中执行 Java jar 文件不起作用
【发布时间】:2014-08-28 18:32:55
【问题描述】:

我是 SoapUI 和 Groovy 的新手,所以请原谅这篇文章,因为它已经在 Stackoverflow 中发布了很多次,但是我找不到修复方法。

SoapUI 版本:4.5.2

如果你们不介意,我有两个问题:

  1. 我有一个可执行的 jar 文件,我将它放在 \bin\ext 目录中,还有另一个 jar,它被认为是 jar 中代码中的依赖 jar,所以我希望它会在那里引用。我在 Stackoverflow 中找到的应该执行这个 jar 的 groovy 代码如下,但由于我在 SoapUI 目录中的任何地方都看不到任何输出,所以它不起作用。

代码如下:

def command = "java -jar UpdateAppIdXMLRequest.jar file.xml"
def process = command.execute()
process.waitFor()

def output = process.in.text
log.info output
  1. 这个 jar 创建了 25 个 xml 文件,这些文件应该能够被 SoapUI 拾取,并将它们作为 TestSteps 放入同一个项目中。在我的 java 代码中,我将这些文件放在什么路径中?

这是我 jar 中的代码:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

class UpdateAppIdXMLRequest {

    static main(args) {

        try {

          SAXBuilder builder = new SAXBuilder();
          File xmlFile = new File("c:\\file.xml");

          Document doc = (Document) builder.build(xmlFile);
          Element rootNode = doc.getRootElement();

          // Create loop to create 25 testStepApps
          for (int i = 1; i < 26; i++) {

              // Get current AppID, incrementAppID and update the ApplicationNumber attribute value for next test script.
              int appID = Integer.parseInt(rootNode.getAttributeValue("ApplicationNumber"));
              appID++;
              String appIDValue = Integer.toString(appID);
              rootNode.getAttribute("ApplicationNumber").setValue(appIDValue);

              XMLOutputter xmlOutput = new XMLOutputter();

              // Create new XML file with next AppID
              xmlOutput.setFormat(Format.getPrettyFormat());
              xmlOutput.output(doc, new FileWriter("c:\\testStepApp" + i + ".xml"));

              // xmlOutput.output(doc, System.out);

              // System.out.println("File updated!");
          }
        } catch (IOException io) {
          io.printStackTrace();
        } catch (JDOMException e) {
          e.printStackTrace();
        }
    }
}

任何帮助/指导将不胜感激。

谢谢。

【问题讨论】:

  • 我不知道您的 jar 在做什么,所以当您执行 groovy 测试步骤时,您在打印 log.info output 时在此测试步骤的 Log Output 选项卡中看到了什么?
  • 感谢您的回复。正如我所说,我对 groovy 了解不多,但是,我正在阅读 log.info 命令采用“输出”参数的代码,该参数定义在这行代码的正上方。这不正确吗?再次感谢。
  • 我没有说代码错了。为了帮助您,我想知道 groovy 脚本在执行时打印的日志。 log.info 打印Log Output 选项卡中的信息,该选项卡就在 SOAPUI 内常规测试步骤窗口的后面。有人可以帮助您的其他可能性是您分享.jar 代码。
  • 感谢您的回复。在 SOAPUI 日志输出中,我得到了以下信息:Tue Sep 02 06:55:22 CDT 2014:INFO:我在上面的原始帖子中将代码包含在我的 jar 中。再次感谢您提供的任何帮助。问候。
  • 嗨@Melinda,您可以直接使用 groovy 测试步骤完成所有这些操作,并且不需要使用 .jar(您可以避免在 /bin/ext 库中包含 jar 代码,重新编译代码如果您进行一些更改等...)。我会在几分钟内准备并解释一个帖子作为答案。

标签: groovy soapui


【解决方案1】:

为此,我建议您直接使用 groovy 测试步骤而不是 jar,这样您就具有更大的灵活性,并且您不必在每次必须更改某些内容时重新编译 jar。

所以,为了实现你的目标,首先你需要在你的项目里面创建一个TestCase,在里面创建一个SOAP Test StepGroovy Test Step是这样的:

我将使用SOAP Test Step 来创建其他测试步骤(创建测试步骤需要wsdl:operation 等等,并且更容易复制直接创建的测试步骤)。

Groovy Test Step 中,我将放置必要的代码来完成如下所示的工作:

import com.eviware.soapui.support.XmlHolder
import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory

// read your request template
def requestFile = new File("C:/file.xml");
// parse it as xml
def requestXml = new XmlHolder(requestFile.text)

// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the testStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("Template");

// loop to create 25 testStep
for(int i = 1; i < 26; i++){
    // xpath expression to get applicationNumber attribute in root node
    def xpathNodeAttr = "/*/@ApplicationNumber";

    // get the root node attribute applicationNumber throught an XPATH
    int appId = Integer.parseInt(requestXml.getNodeValue(xpathNodeAttr));
    // add 1 to appId
    appId++;
    // set the value again in the attribute
    requestXml.setNodeValue(xpathNodeAttr,appId);


    def testStepName = "TestStep_ApplicationNumber_"+ String.valueOf(appId)
    log.info testStepName;
    log.info testStepName.getClass().getName()
    log.info tc.getClass().getName()
    // create a new testStepConfig
    def testStepFactory = new WsdlTestRequestStepFactory();
    def testStepConfig = testStepFactory.createConfig( tsTemplate.getOperation(), testStepName )
    // add the new testStep to TestCase
    def newTestStep = tc.insertTestStep( testStepConfig, -1 )
    // set the request which just create
    newTestStep.getTestRequest().setRequestContent(requestXml.getXml())
}

此代码基本上是将您的java 代码“翻译”为groovy,并添加了创建测试步骤所需的代码。简而言之,这段代码从文件中读取一个请求,并使用该请求在当前测试用例中创建 25 个测试步骤,在每个请求中它只更改根节点的 ApplicationNumber 属性并将其添加 +1。

根据评论进行编辑:

如果您使用REST Request step 而不是SOAP Request Step,则必须更改一些常规代码以在其上使用com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactorygetTestRequest() 方法。因此,如果您有一个带有 POST 方法的 REST 服务,请创建一个带有 REST Request test stepGroovy Test StepTest Case,如下所示:

改用这个 groovy 代码,基本上这个代码和上面的代码是一样的,用REST Request而不是SOAP Request做同样的事情:

import com.eviware.soapui.support.XmlHolder
import com.eviware.soapui.impl.wsdl.teststeps.registry.RestRequestStepFactory

// read your request template
def requestFile = new File("C:/file.xml");
// parse it as xml
def requestXml = new XmlHolder(requestFile.text)

// get the current testCase to add testSteps later
def tc = testRunner.testCase;
// get the testStep as template to create the other requests
def tsTemplate = tc.getTestStepByName("Template");

// loop to create 25 testStep
for(int i = 1; i < 26; i++){
    // xpath expression to get applicationNumber attribute in root node
    def xpathNodeAttr = "/*/@ApplicationNumber";

    // get the root node attribute applicationNumber throught an XPATH
    int appId = Integer.parseInt(requestXml.getNodeValue(xpathNodeAttr));
    // add 1 to appId
    appId++;
    // set the value again in the attribute
    requestXml.setNodeValue(xpathNodeAttr,appId);


    def testStepName = "TestStep_ApplicationNumber_"+ String.valueOf(appId)
    log.info testStepName;
    log.info testStepName.getClass().getName()
    log.info tc.getClass().getName()
    // create a new testStepConfig
    def testStepFactory = new RestRequestStepFactory();
    def testStepConfig = testStepFactory.createConfig( tsTemplate.getTestRequest(), testStepName )
    // add the new testStep to TestCase
    def newTestStep = tc.insertTestStep( testStepConfig, -1 )
    // set the request which just create
    newTestStep.getTestRequest().setRequestContent(requestXml.getXml())
}

希望这会有所帮助。

【讨论】:

  • 天哪!太感谢了。我感谢您的帮助,更重要的是您的时间。我会试一试,希望这能帮助我们在 SoapUI 中工作的 QA 人员。因为他不是开发人员,所以我试图用 Java 编写一些代码来帮助他。再次感谢。
  • 运行 REST 应用程序出现问题。这是错误:发生错误[没有方法签名:com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestRequestStepFactory.createConfig() 适用于参数类型:(com.eviware.soapui.impl.rest.RestResource , java.lang.String) 值:[com.eviware.soapui.impl.rest.RestResource@ad74f1, TestStep_ApplicationNumber_65244040] 可能的解决方案:createConfig(com.eviware.soapui.impl.wsdl.WsdlOperation, java.lang.String), createConfig(com.eviware.soapui.impl.wsdl.WsdlRequest, java.lang.String)],详见错误日志
  • 我以为您使用的是 SOAP 测试请求,因为您处理的是 xml 请求,但是您使用的是 REST 资源,因此您需要一种不同的方式来创建测试步骤,因为我的代码是创建 SOAP测试请求。我更新了答案以添加与 REST 请求而不是 SOAP 请求一起使用的 groovy 代码,看看它。希望这次能实现你的目标:)
  • 非常感谢。我希望 SoapUI 有智能感知来帮助新用户找到其他使用方法。我当然感谢你所有的时间和帮助。值得赞赏。周末愉快。
  • 是的,在 SOAPUI 中的 groovy 脚本中的智能感知会很棒!尝试一下并给我反馈。也祝你周末愉快。
猜你喜欢
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多