本主题概述了与 SOAtest 和 Virtualize 的可扩展性(脚本)功能及其各种应用程序有关的问题。章节目录:
了解可扩展性功能
SOAtest&Virtualize 可扩展性功能使您可以应用自定义脚本(使用 Java、JavaScript、Oracle Nashorn、Groovy 或 Jython)来执行任何对 SOAtest&Virtualize 有用的特定功能。它还支持实现 JSR 223“Java 平台脚本”规范的其他脚本引擎。此功能使您能够在不学习特定于应用程序的语言的情况下,根据您的特定需求自定义 SOAtest 和 Virtualize。
如果使用 SOAtest,则还可以使用脚本来自定义使用 RuleWizard 创建的规则。有关此特性的详情,请参阅 RuleWizard 用户指南。
设置脚本环境
如果使用的是 Jython 脚本,可以在首选项面板的脚本选项卡中指定一个 Jython 路径变量。无需设置此变量即可使用 Jython 脚本支持。Jython 路径指定了一个目录列表,用于搜索尚未包含在 Jython 中的 python 模块。使用操作系统默认的路径分隔符(Windows 为“;”,Linux 和 macOS 为“:”)分隔多个目录路径。如果设置了 Jython 路径,则需要重新启动 SOAtest 或 Virtualize 才能使更改生效。
如果您使用 Java 编写脚本,并且想使用 SOAtest 重新编译修改后的 Java 文件,请参阅 SOAtest 中的 Eclipse Java 项目以获取有关如何在脚本上设置环境的详细信息。
指定脚本
要从提供脚本选项的 SOAtest 或 Virtualize GUI 控件定义脚本,请执行以下操作:
- 如果您的 Java 类来自 Eclipse 工作空间中的 Java 项目,则将 Java 项目添加到 classpath 中。
- 在语言框中,指示脚本将使用的语言。
- 在大文本字段中定义要实现的脚本。
- 关于 Java 方法,请在类字段中指定合适的类。注意,您选择的类必须位于 classpath 上(可以点击修改 Classpath 链接,然后在显示的首选项页面中指定)。如果想在修改和编译 Java 文件之后重新加载类,请点击重新加载类。
- 针对其他脚本,可以使用现有文件作为方法的源代码,也可以在 SOAtest 或 Virtualize 工具中创建方法。
- 若要使用现有文件,请启用文件并点击浏览。从打开的文件选择器中选择文件,然后点击 OK 完成选项。
- 若要在 SOAtest 或 Virtualize中从头开始创建方法,请启用文本并将代码键入、剪切或粘贴到相应文本框中。
- 若要选择合法且可运行的特定脚本,请右键点击文件或文本字段(点击要用来指定脚本的一个),然后选择评估。SOAtest 或 Virtualize 将报告找到的任何问题。
使用脚本模板
如果使用 Jython 或 JavaScript 创建脚本,您可以在 SOAtest 或 Virtualize 首选项面板的脚本模板字段中指定一个脚本模板。该字段中指定的任何代码都将用作与该字段关联语言中的内联脚本的默认代码。这对于设置默认输入和通用全局变量非常有用。
脚本模板适用于扩展工具、SOAP 服务和脚本 SOAP 输入中使用的脚本。
与 SOAtest 和 Virtualize 进行交互
如果需要脚本与 SOAtest 或 Virtualize 程序进行交互,可以使用 SOAtest 或 Virtualize 可扩展性 API 进行交互。例如,您可以使用 SOAtest 或 Virtualize 可扩展性 API 将脚本的结果发送到 SOAtest 或 Virtualize 消息窗口,或将特定值传递给特定的 SOAtest 或 Virtualize。
您可以访问 Parasoft > 帮助或帮助 > 帮助内容(取决于您的安装程序),然后查找标题为 Parasoft SOAtest Extensibility API(适用于 SOAtest)或 Parasoft Virtualize Extensibility API(适用于 Virtualize)的手册,以获取扩展框架 API 的文档。
访问所需 Jar 文件
如果您的 Java 代码使用可扩展性 API,并且您想在 SOAtest 环境中编译代码,请使用 Java 项目向导。该向导将创建一个新的 Eclipse Java 项目,该项目可以访问 Extensibility API。详情请参阅在 SOAtest 中使用 Eclipse Java 项目。如果要在 SOAtest 环境外编译代码,则需要以下 jar 文件:
- com.parasoft.api.jar
- webking.jar(仅当您将从 soaptest. api 或 webking. api 包访问类时才需要)
这些 jar 文件位于 <INSTALL-DIR>\eclipse\plugins\com.parasoft.ptest.libs.web_<VERSION>\root
目录中。
- 针对 XPath 处理,还需要
org.apache.xpath.XPathAPI
类。该类位于 xalan.jar 中。 - 针对 ISO 8583 相关的脚本,还需要
org.jpos.iso.*
中的类,如ISOMsg
、BaseChannel
、ISOChannel
和ISOPackager
。这些类位于 jpos.jar 中。
设置上下文类加载器
扩展工具在类加载器中运行。某些 API(如 JNDI)对上下文类加载器较为敏感。在某些情况下,您的代码必须在执行特定 API 调用之前显式设置上下文类加载器。更多信息,请参阅 http://wiki.eclipse.org/Context_Class_Loader_Enhancements#Technical_Solution。
脚本变量
您可以在 SOAtest 和 Virtualize 脚本中声明和使用变量。
变量声明必须以关键字 "var"
开头,后跟等号 "="
,最后是变量值。每个变量必须在单独的一行中声明。变量可在脚本中的任何位置声明,变量声明后可立即使用。要为现有变量分配新值,需要 "re-declare"
该变量。
在脚本中引用变量的方式如下:${varName}
。
SOAtest 的脚本示例:
----------------------------- var TestHome=C:\functional-tests\src\test\soatest\tests\LoadTests var ReportHome=C:\LoadTestReports var minutes = 1 var scenario = "Linear Increase" var test=echo open ${TestHome}\${test}.tst loadtest -minutes ${minutes} -report ${ReportHome}/%d/${test}/${test}.rpt -xml${ReportHome}/%d/${test}/${test}.xml -html ${ReportHome}/%d/${test} ${scenario} -----------------------------
Jython 语法着色
可使用 PyDev 插件(http://www.pydev.org/)为扩展工具启用 Jython 语法着色。该插件必须配置有 Jython 解释器,才能实现代码自动补全等高级功能。更多详情,请参阅 http://www.pydev.org/manual_101_interpreter.html。
通过脚本访问数据源
如果使用 SOAtest,可以通过在工具配置面板顶部选择数据源,然后启用使用数据源,使脚本可以使用数据源。
如果使用 Virtualize,在脚本的其他方法中或在脚本的任何方法中,将数据源的值存储到变量“x”中,并加上一行:
x = context.getValue("Data Source Name", "Column Name")
有关脚本的更多信息,请参阅扩展框架 API 文档。选择 Parasoft > 帮助或帮助 > 帮助内容(取决于您的安装程序),然后查找标题为 Parasoft SOAtest Extensibility API(适用于 SOAtest)或 Parasoft Virtualize Extensibility API(适用于 Virtualize)的手册。
SOAtest 示例与注意事项
例如,假设您有一个与下图类似的测试:
表格数据源的名称为数据源名称。图中未展示以下值得注意的情况:
- 数据源名称表中有一列标注为列名。
- XML 数据库中有一列标注为测试 1:结果。
- XML 数据库和可写数据源属于标注为生成数据源的数据源。
要让脚本使用其中一个数据源,请在扩展工具配置面板顶部选择数据源,然后启用使用数据源。
注意
打开旧文件(在 SOAtest 6.1 之前创建)时,请注意浏览器数据库工具列名会自动转换为“Extracted:xyz”,其中“xyz”是您指定的列名。这为引用“Extracted:xyz”的旧脚本提供了支持。您可以将浏览器数据库中的列名改为“xyz”或“abc”。
有关脚本的更多信息,请参阅扩展框架 API 文档。选择 Parasoft > 帮助或帮助 > 帮助内容(取决于您的安装程序),然后查找名为“Parasoft SOAtest Extensibility API”的手册。
SOAtest 可扩展性示例
访问、操纵和存储数据
扩展工具的典型用法之一是从数据源访问数据,操纵数据,然后将其动态存储在 XML 数据库或可写数据源中。在本脚本示例中,我们定义了一个名为 getKeywords 的方法,在该方法中,我们从名为“Books”的数据源访问数据,数据源列名为“keywords”。然后,我们将返回该字符串的 XML 表示形式,这样就可以将该脚本的输出发送到 XML 数据库。
请注意,从扩展工具访问数据源需要进行额外配置。详情请参阅前面部分。
在以下示例中,方法将两个参数作为输入:
- Object 输入:代表从上一个测试用例传递给该方法的输入。例如,如果我们将扩展工具与 SOAP 客户端工具的 SOAP 响应相链接,Object 输入将是一个代表 SOAP 响应的字符串。
- ExtensionToolContext 上下文:通过 getValue 方法,可以从扩展工具访问数据源。该方法可与 Context 接口公开的其他方法一起使用,以便在脚本和其他工具之间共享数据源值。
Jython 示例 1
from soaptest.api import * def getKeywords(input, context): title = context.getValue("Books", "keywords") return SOAPUtil.getXMLFromString([title])
Jython 示例 2
def methodName(): # code
def methodName(input): # code
def methodName(input, context): # code
在上述示例中,“input”指:
- 通过与该扩展工具连锁的工具输出传递的数据。例如,SOAP 客户端的响应 SOAP 消息封套,或
- 该扩展工具 Input 区域中显示的数据。 可在扩展工具界面的底部找到。
在绝大多数情况下,您可以假定传递给“input”变量的值是一个原始的 Jython 字符串。
一般来说,“context”变量由 SOAtest 动态决定,它将是可扩展性 API 中 Context 类的一个实例。就扩展工具而言,上下文将是该特定工具的 ExtensionToolContext 实例(与测试套件中的其他扩展工具相比)。
JavaScript 示例
var SOAPUtil = Packages.soaptest.api.SOAPUtil function getKeywords(input, context) { title = context.getValue("Books", "keywords") return SOAPUtil.getXMLFromString([title]) }
Java 示例
package examples; import soaptest.api.*; import com.parasoft.api.*; public class Keyword { public Object getKeywords(Object input, ExtensionToolContext context) throws com.parasoft.data.DataSourceException { String[] titles = new String[1]; titles[0] = context.getValue("Books", "keywords"); return SOAPUtil.getXMLFromString(titles); } }
注意
像本示例这样的 Java 代码必须在 SOAtest 之外编译。您需要确保 Java 编译器的 Classpath 中包含 SOAtest jar 文件,以便访问 SOAtest Extensibility API 中的包,尤其是 webking.jar
和 com.parasoft.api.jar
。
此 Keyword 示例的源代码和编译后的类文件可在 <INSTALL-DIR>/build/examples
获取。<INSTALL-DIR>/build
文件夹已在 SOAtest 的 Classpath 中,因此您可以在测试套件中使用该 Keyword 示例。您也可以将自己的 Java 类文件放在这里,以便在 SOAtest 中使用 Java 类。除了使用 <INSTALL-DIR>/build
文件夹外,另一种方法是使用首选项中的系统属性选项卡添加类文件。
将文件内容读入字符串
要使用 Jython 脚本将文件内容读入字符串,可以使用以下方法:
from java.lang import * from java.io import * from soaptest.api import * def getContents(input, context): contents = StringBuffer() reader = BufferedReader(FileReader(File("c:\Documents and Settings\jhendrick\Desktop\test.txt"))) line = String() while line != None: line = reader.readLine() if line != None: contents.append(line) contents.append(System.getProperty("line.separator")) reader.close() return contents.toString()
定义自定义断言
下面是一个 Java 脚本示例,可在 XML 断言器工具中用作自定义断言。该脚本从数据源获取一个值,将该值与响应值一起打印,并根据响应值是否包含数据源值返回一个 boolean 值。
package examples; import com.parasoft.api.*; public class Comparison { //Compares a value from a database data source to a value returned in a SOAP response public boolean compareToDatabase(Object input, ScriptingContext context) throws com.parasoft.data.DataSourceException { //Gets values from database data source named "Books" String value = context.getValue("Books", "Book"); //Prints database data source values along with SOAP response values in a message to the console Application.showMessage("Value from database is " + value + ".\nValue from SOAP response is " + input.toString() + "."); //Verifies that the SOAP response value contains the database data source value return input.toString().contains(value); } }
使用提取值进行字符串操作
下面是一个 Jython 脚本示例,该脚本从不同来源(数据库、测试套件变量和环境变量)中提取值,用于字符串操作,例如使用“+”运算符进行连接...
from soaptest.api import * from com.parasoft.api import * # Gets a value from a data bank (line 10) or test suite variable (line 11), # appends an environment variable value to the front of that value, # and returns the modified value. Be sure to comment out line 11 # when using line 10 and vice versa. def getModifiedString(context): #value = context.getValue("Generated Data Source", "columnName") value = context.getValue("testSuiteVariableName") environmentVariableValue = context.getEnvironmentVariableValue("environmentVariableName") modifiedString = environmentVariableValue + value return modifiedString
这个示例针对的是一个相当特殊的用例,但仍然使用了 SOAtest 可扩展性 API 中的一些常用方法。
访问窗口或框架的文件
以下示例用于在 Web 场景中将扩展工具链接到浏览器回放工具。
getDocument 的重载方式如下:
getDocument(); // gets the document for the main window getDocument(String windowName); // gets the document for the window with the specified window name getDocument(String windowName, String frameName); // gets the document for a frame within a window
例如,以下代码可获取主窗口中名为“mainPane”的区域中的内容。然后,它会使用文档获取所选框架的标题文本。
var Application = Packages.com.parasoft.api.Application; var WebBrowserUtil = Packages.webking.api.browser2.WebBrowserUtil; function getFrameDocument(input, context) { var document = input.getDocument("", "mainPane"); var titles = document.getElementsByTagName("title"); var title = titles.item(0); var value = WebBrowserUtil.getTrimmedText(title); Application.showMessage("title: " + value); return value; }
特定语言提示
Java
- 在任何脚本类字段中指定 Java 类时,必须指定 classpath 上的已编译类。您可以点击修改 Classpath 链接,然后在显示的首选项页面中指定。
- 如果您使用的类是包的一部分,您需要指定完整的包名称以及类名称(例如,
java.lang.String
)。 - 如果您的某个脚本使用的类已在 SOAtest 或 Virtualize 中更改并重新编译,SOAtest 或 Virtualize 将重新加载该类,并在您调用方法时使用最新的类构建对象。对于包名以下列前缀之一开头的任何类,SOAtest 和 Virtualize 不会以这种方式运行:
- sun.
- com.sun.
- org.omg.
- javax.
- sunw.
- java.
- com.parasoft.
- webtool.
- wizard.
- 如需手动指示 SOAtest 或 Virtualize 重新加载已修改并重新编译的类,请点击重新加载类。
JavaScript
- “旧版”SOAtest 或 Virtualize JavaScript 模拟基于 FESI 实现。建议使用 Oracle Nashorn 等其他脚本引擎。详情请参阅:
- 您可以从 JavaScript 方法或 JavaScript 工具中调用 classpath 上的 Java 类和方法。
例如,如果您正在使用 Nashorn 并想要在 JavaScript 中调用 Application.report()(通过 SOAtest 或 Virtualize 可扩展性 API),则需要将其引用为
Java.type("com.parasoft.api.Application"): var Application = Java.type("com.parasoft.api.Application") Application.report("Message", "Result Window")
如果您决定使用旧版引擎(不推荐)并想要在 JavaScript 中调用 Application.report()(通过 SOAtest 或 Virtualize 可扩展性 API),则需要将其引用为
Packages.com.parasoft.api.Application.report()
。您也可以在名称前加上Packages
和 Java 类所在包的名称进行引用,如下var Application = Packages.com.parasoft.api.Application Application.report("Message", "Result Window")
- 如需检查指定的脚本是否合法且可运行(或在方法框中添加方法条目),请右键点击文件或文本字段(点击用于指定脚本的字段),然后选择评估。
Jython
有关 Jython(与 Java 集成的 Jython 实现)的详细信息,包括如何编写 Jython 以及如何从 Jython 内部调用 Java 类的信息,请访问 http://www.jython.org。
- 如果使用的是 Jython 脚本,可以在首选项面板的脚本选项卡中指定 Jython 路径变量。无需设置此变量即可使用 Jython 脚本支持。Jython 路径指定了一个目录列表,用于搜索尚未包含在 Jython 中的 python 模块。使用操作系统默认的路径分隔符(Windows 为“;”,Linux 和 macOS 为“:”)分隔多个目录路径。如果设置了 Jython 路径,则需要重新启动 SOAtest 或 Virtualize 才能使更改生效。
- 如需检查指定的脚本是否合法且可运行(或在方法框中添加方法条目),请右键点击文件或文本字段(点击用于指定脚本的字段),然后选择评估。
Groovy
下面是一个 Groovy 脚本示例:
import com.parasoft.api.*; boolean customAssertion(Object input, ScriptingContext context) { String value = context.getValue("Books", "title"); Application.showMessage("Value from data source is " + value) Application.showMessage("Value from SOAP response is " + input.toString()) return input.toString().contains(value); }
JSR 223 脚本语言
您可以配置 SOAtest 和 Virtualize 以识别任何实施 JSR 223“Scripting for the Java Platform”规范的脚本引擎。Oracle Nashorn 默认可用,也可添加其他引擎。
Oracle Nashorn JavaScript
Oracle Nashorn ECMAScript 引擎包含在 Java 中,默认可用。下面是一个 Oracle Nashorn 脚本示例:
var Application = Java.type("com.parasoft.api.Application") function customAssertion(input, context) { value = context.getValue("Books", "title"); Application.showMessage("Value from data source is " + value) Application.showMessage("Value from SOAP response is " + input.toString()) return input.toString().contains(value); }
Mozilla Rhino JavaScript
Mozilla Rhino 是 Java 运行时所包含的原始 ECMAScript 引擎。它是 Oracle Nashorn 的前身,后者在 Java 8 中取代了 Mozilla Rhino。9.10 之前的 SOAtest 和 Virtualize 版本与 Java 7 一起提供,其中包括 Mozilla Rhino。使用 Mozilla Rhino 引擎保存在早期版本 SOAtest 和 Virtualize 中的脚本,现在可在加载了 Mozilla 兼容性扩展的新 Oracle Nashorn 中运行。兼容性扩展由 Oracle 作为 Nashorn 的一部分提供,旨在实现上述目的。通过加载兼容性扩展,脚本将继续像以前一样运行,但运行时的性能显著提高。
最初使用 Mozilla Rhino 保存的脚本现在会在语言选择框中显示 JavaScript(兼容 Mozilla Rhino),表明脚本将使用 Nashorn 运行,但使用 Mozilla 兼容性扩展。如果创建一个新脚本,JavaScript(兼容 Mozilla Rhino)选项将不可用;您只能看到 JavaScript(Oracle Nashorn),它不会加载 Mozilla 兼容扩展。如果在这种情况下需要加载兼容性扩展,只需在脚本顶部添加
load("nashorn:mozilla_compat.js");
即可。更多详情,请参阅 https://wiki.openjdk.java.net/display/Nashorn/Rhino+Migration+Guide#RhinoMigrationGuide-Compatibility-script。
由于 Oracle Nashorn 是 Mozilla Rhino 的替代品,因此不建议使用 Mozilla Rhino。不过,Mozilla Rhino 与其他任何兼容 JSR 223 的脚本引擎一样,可用于 SOAtest 和 Virtualize(请参阅其他 JSR 223 脚本语言)。Mozilla Rhino 包含两个 jar 文件,必须添加到首选项面板(系统属性下)的 classpath 中:Rhino js.jar and js-engine.jar.详情请参阅 https://wiki.openjdk.java.net/display/Nashorn/Using+Rhino+JSR-223+engine+with+JDK8。
也可在 maven 中央仓库找到预编译的 jar:
http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.mozilla%22%20a%3A%22rhino%22
- http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22rhino-js-engine%22
其他 JSR 223 脚本语言
要使用其他 JSR 223 脚本语言,可将相应引擎的脚本引擎添加到 classpath 中(前往 Parasoft 首选项面板,在系统属性部分添加)。
例如,您可以添加实现 JSR 223 的 JRuby 脚本引擎。方法是在 http://jruby.org/ 下载 JRuby,然后将 jruby.jar 添加到 classpath 中。
下面是一个 JRuby 脚本示例:
require 'java' Application = com.parasoft.api.Application def doSomething(input, context) Application.showMessage("hello world") end
其他可扩展资源
有关如何创建和应用执行自定义脚本的扩展工具的详细信息,请参阅用于自定义脚本的扩展工具。 有关如何使用脚本扩展 SOAtest 的分步演示,请参阅使用脚本扩展 SOAtest。