本主题概述了与 SOAtest 和 Virtualize 的可扩展性(脚本)功能及其各种应用程序有关的问题。本章包含:
了解可扩展性功能
SOAtest&Virtualize 可扩展性功能使您可以应用自定义脚本(使用 Java、JavaScript、Oracle Nashorn、Groovy 或 Jython)来执行任何对 SOAtest&Virtualize 有用的特定功能。它还支持实现 JSR 223“Java 平台脚本”规范的其他脚本引擎。此功能使您能够在不学习特定于应用程序的语言的情况下,根据您的特定需求自定义 SOAtest 和 Virtualize。
如果使用 SOAtest,则还可以使用脚本来自定义使用 RuleWizard 创建的规则。有关此特性的详情,请查阅 RuleWizard 用户指南。
设置脚本环境
如果使用的是 Jython 脚本,则可能需要在 Preferences 面板的 Scripting 选项卡中指定 jython.home 和 jython.path 变量。这两个变量都用于定位 Jython 模块,不导入任何 Jython 模块的 Jython 代码可以在无需设置或变量的情况下使用 Jython 脚本支持。jython.home 指定 Jython 安装目录,jython.path 用于将不在 jython.home/Lib 目录中的模块添加到您的路径中。jython.path 中可以列出多个路径,而 jython.home 必须是单个目录。如果设置 jython.home 和 jython.path 变量,你需要在变更生效之前重启 SOAtest 或 Virtualize。
如果您使用 Java 编写脚本,并且想使用 SOAtest 重新编译修改后的 Java 文件,请参阅 SOAtest 中的 Eclipse Java 项目 以获取有关如何在脚本上设置环境的详细信息。
如果您使用 Java 编写脚本并想使用 Virtualize 重新编译修改后的 Java 文件,请参阅 在 Virtualize 中使用 Eclipse Java 以获得有关如何在脚本上设置环境的详细信息。
指定脚本
要从提供脚本选项的 SOAtest 或 Virtualize GUI 控件定义脚本,请执行以下操作:
- 如果您的 Java 类来自 Eclipse 工作空间中的 Java 项目,则将 Java 项目添加到类路径中。
- 在 Language 框中,指示脚本将使用的语言。
- 在大文本字段中定义要实现的脚本。
- 关于 Java 方法,请在 Class 字段中指定合适的类。注意,您选择的类必须位于类路径上(可以单击 Modify Classpath 链接,然后在显示的首选项页面中指定它)。如果想在修改和编译 Java 文件之后重新加载类,请单击 Reload Class 。
- 针对其他脚本,可以使用现有文件作为方法的源代码,也可以在 SOAtest 或 Virtualize 工具中创建方法。
- 若要使用现有文件,选择 File 单选按钮并单击 Browse。从打开的文件选择器中选择文件,然后单击 OK 完成选项。
- 若要在 SOAtest 或 Virtualize中从头开始创建方法,选择 Text 单选按钮,并将代码键入、剪切或粘贴到相关量的文本框中。
- 若要选择合法且可运行的特定脚本,请右键单击 File 或 Text 文本字段(单击要用来指定脚本的一个),然后从快捷菜单中选择 Evaluate 。SOAtest 或 Virtualize 将报告找到的任何问题。
使用脚本模板
如果使用 Jython 或 JavaScript 创建脚本,您可以在 SOAtest 或 Virtualize Preferences 面板的 Script Template 字段中指定一个脚本模板。该字段中指定的任何代码都将用作与该字段关联语言中的内联脚本的默认代码。这对于设置默认输入和通用全局变量非常有用。
脚本模板适用于扩展工具、SOAP 服务和脚本 SOAP 输入中使用的脚本。
与 SOAtest 和 Virtualize 进行交互
如果需要脚本与 SOAtest 或 Virtualize 程序进行交互,可以使用 SOAtest 或 Virtualize 扩展 API 进行交互。例如,您可以使用 SOAtest 或 Virtualize 扩展 API 将脚本的结果发送到 SOAtest 或 Virtualize 消息窗口,或将特定值传递给特定的 SOAtest 或 Virtualize。
可以通过 Parasoft> Help 菜单访问扩展框架 API 的文档(查找名为“Parasoft Virtualize 扩展 API”
访问所需 Jar 文件”的书籍)。
如果您的 Java 代码使用可扩展性 API,并且您希望在
SOAtest、
或
Virtualize
环境中编译代码,请使用 Java 项目向导。该向导将创建一个新的 Eclipse Java 项目,该项目可以访问扩展 API。有关详细信息,请查阅
或
在 Virtualize 中使用 Eclipse Java 项目以获得更多详情。
如果要在
SOAtest、
或
Virtualize
环境外编译代码,则您需要以下 jar 文件:
- com.parasoft.api.jar
- webking.jar (仅当您将从 soaptest. api 或 webking. api 包访问类时, 才需要)
这些 jar 文件可在以下文件夹中获取:<SOAtest Installation Directory>\eclipse\plugins\com.parasoft.xtest.libs.web_<SOAtest version>\root
和<Virtualize Installation Directory>\eclipse\plugins\com.parasoft.xtest.libs.web_<Virtualize version>\root
此外,如果脚本需要使用这些 API 类以外的其他功能,则可能需要向类路径添加其他(第三方或开源)jar。例如:
- 对于 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”
开始,并且后跟一个等号 "="
,等号后跟变量值。每个变量必须在单独的行上声明。变量可以在脚本的任意位置声明,变量可以在声明后立即使用。若要为现有变量分配一个新值,则 "重新声明"
该变量。
可以在脚本中引用变量,如下所示:${varName}
.
配置 Jython 首选项
Jython 版本
支持 SOAtest 和 Virtualize 的 Jython 2.5.2 版本不包括一些标准的 Jython 库,如 os 模块。如果您习惯于使用这些模块,并且希望在 SOAtest 或 Virtualize 中访问它们,可以指向 SOAtest 或 Virtualize 到外部 Jython 安装,如下所示:
- 在所选定位置安装 Jython;们将此位置称为
<Jython Install Directory>
。 - 打开 SOAtest 或 Virtualize。
- 选择 Parasoft> Preferences。
- 选择 Scripting。
- 在 Jython Home 字段中,输入
<Jython Install Directory>
。 - 重启 SOAtest 或 Virtualize。
Jython 语法着色
使用 PyDev 插件启用扩展工具的 Jython 语法着色(http://www.pydev.org/)。此插件必须配置其 jython 解释器,以用于高级功能,如代码自动完成。有关更多详细信息,请查阅 http://www.pydev.org/manual_101_interpreter.html。
从脚本访问数据源
如果使用 SOAtest,您可以通过选择工具配置面板顶部的数据源,然后启用 Use Data Source 选项来使数据源可用于脚本。
在脚本的其他方法中,或者如果使用 Virtualize,则在脚本的任何方法中,将数据源中的值存储到带有行的变量“ x”中:
x = context.getValue("Data Source Name", "Column Name")
有关脚本的更多信息,请参见扩展框架 API 的文档。选择 Parasoft> Help,然后查询书名 "Parasoft SOAtest Extensibility API"(针对 SOAtest)或 "Parasoft Virtualize Extensibility API"(针对 Virtualize)。
SOAtest 示例和注意事项
例如,假设您有一个测试,其外观与下图中的相似:
表数据源的名称为 Data Source Name。以下重要事实未体现出:
- 表 Data Source Name 有一个标记为 Column Name的列。
- XML 数据库包含一个列,其标记为 Test 1: Result.
- XML 数据库和可写数据源属于标记为 Generated Data Source的数据源。
为了使这些数据源之一可用于脚本,请在扩展程序工具的配置面板顶部选择数据源,然后选中 Use Data Source。
注意
当打开老版本的文件(在 SOAtest 6.1 之前创建)时,请注意,浏览器数据库工具列名称会自动转换为“ Extracted:xyz”,其中“ xyz”是您指定的列名称。这提供了对引用“Extracted:xyz”的旧脚本的支持。您可以将浏览器数据库中的列名称更改为“xyz”或“abc”。
有关脚本的更多信息,请参见扩展框架 API 的文档。选择 Parasoft> Help,然后查询标题为 "Parasoft SOAtest Extensibility API” 的书。
SOAtest 的可扩展性示例
访问、操作和存储数据
扩展工具的一种典型用法是从数据源访问数据,对其进行处理,然后将其动态存储在 XML 数据库或可写数据源中。在此脚本示例中,我们定义了一种名为 getKeywords 的方法,在该方法中,我们从名为“Books”的数据源和名为“keywords”的数据源列访问数据。然后,我们返回此字符串的 XML 表示形式,以便我们可以将该脚本的输出发送到 XML 数据库。
请注意,需要其他配置才能从扩展工具访问数据源。有关更多详情,请查阅以前部分。
在这些示例中,这些方法采用两个参数作为输入:
- 对象输入:表示从先前的测试用例传递给该方法的输入。例如,如果我们将扩展工具链接到 SOAP 客户端工具的 SOAP 响应,则输入对象将是代表 SOAP 响应的字符串。
- ExtensionToolContext context: 方法 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 客户端 OR 的响应 SOAP 信封
- 即扩展工具 Input 区域中显示的数据。 在扩展工具界面的底部可以找到它。
在大多数情况下,您可以假定传递给“input”变量的值将是原始 Jython 字符串。
通常,“context”变量是由 SOAtest 动态确定的,它将是 Context 类的实例,可以在扩展 API 中找到。对于扩展工具,上下文将是此特定工具的 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 编译器的类路径上具有 SOAtest jar 文件,以便从 SOAtest 可扩展性 API(尤其是webking.jar
和 com.parasoft.api.jar
)访问包。
对于此关键字示例,可在 SOAtestInstallRoot/build/examples 上获得源代码和编译的类文件。这个 SOAtestInstallRoot/build 文件夹已经在 SOAtest 的类路径上,因此您可以在测试套件中使用关键字示例。您也可以在此处放置自己的 Java 类文件,以在 SOAtest 中使用 Java 类。使用 OAtestInstallRoot/build 文件夹的另一种方法是使用 Preferences 中的 System Properties 选项卡添加类文件。
将文件内容读入字符串
若要使用 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 声明工具中的自定义断言。该脚本从数据源获取一个值,将该值与响应值一起打印,并根据响应值是否包含数据源值返回布尔值。
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
- 当您在任何脚本 Class 字段中指定 Java 类时,必须指定类路径上的已编译类。可以单击 Modify Classpath 链接,然后在显示的 Preferences 页面中指定它。
- 如果您使用的类是软件包的一部分,则需要指定完整的软件包名称以及类名称(例如,
java.lang.String
) - 如果您的脚本之一使用在 SOAtest 或 Virtualize 中已更改并重新编译的类,则在调用该方法时,SOAtest 或 Virtualize 将重新加载该类并将最新的类用于对象构造。对于包名称以以下前缀之一开头的任何类,SOAtest 和 Virtualize 均无法通过这种方式运行:
- sun.
- com.sun.
- org.omg.
- javax.
- sunw.
- java.
- com.parasoft.
- webtool.
- wizard.
- 若要手动提示 SOAtest 或 Virtualize 重新加载修改后的类和重新编译,请单击 Reload Class。
JavaScript
- “传统” SOAtest 或 Virtualize JavaScript 仿真基于 FESI。我们建议使用备用脚本引擎,例如 Oracle Nashorn。有关更多详情信息,请查阅:
- 您可以从 JavaScript 方法或 JavaScript 工具内部调用类路径中的 Java 类和方法。
例如,如果您正在使用 Nashorn,并且想从 JavaScript 内部调用 Application.report()(通过SOAtest 或 Virtualize Extensibility 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 Extensibility API),则需要将其引用为
Packages.com.parasoft.api.Application.report()
。您还可以通过在名称前加上Packages
以及 Java 类所在的软件包的名称来引用它,如下所示:var Application = Packages.com.parasoft.api.Application Application.report("Message", "Result Window")
。
- 若要选择合法且可运行的特定脚本(或向 Method 框中添加方法),请右键单击 File 或 Text 字段(单击要用来指定脚本的一个),然后从快捷菜单中选择 Evaluate 。
Jython
有关 Jython(与 Java 集成的 Jython 的实现)的详细信息,包括有关如何编写 Jython 以及如何从 Jython 内部调用 Java 类的信息,请访问 http://www.jython.org。请注意,Jython 2.5.2 附带了 SOAtest 和 Virtualize。
- 如果使用的是 Jython 脚本,则可能需要在 Preferences 面板的 Scripting 选项卡中指定 jython.home 和 jython.path 变量。这两个变量都用于定位 Jython 模块,不导入任何 Jython 模块的 Jython 代码可以在无需设置或变量的情况下使用 Jython 脚本支持。jython.home 指定 Jython 安装目录,jython.path 用于将不在 jython.home/Lib 目录中的模块添加到您的路径中。jython.path 中可以列出多个路径,而 jython.home 必须是单个目录。如果设置 jython.home 和 jython.path 变量,您需要在变更生效之前重启 SOAtest 或 Virtualize。
- 如果您决定导入可选模块并且没有安装 Jython 2.5.2,则需要从 jython.org下载并安装 Jython 2.5.2。针对 Linux,请使用 java -jar jython_installer-2.5.2.jar。针对 Windows,请双击 jython_installer-2.5.2.jar。
- 若要选择合法且可运行的特定脚本(或向 Method 框中添加方法条目)请右键单击 File 或 Text ,文本字段(单击要用来指定脚本的一个),然后从快捷菜单中选择 Evaluate 。
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 “Java 平台脚本”规范的所有脚本引擎。 默认情况下,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 的前身,Oracle Nashorn 从 Java 8 开始取代了 Mozilla Rhino。Java 7 附带的 9.10 之前的 SOAtest 和 Virtualize 版本包括 Mozilla Rhino。使用 Mozilla Rhino 引擎保存在早期版本的 SOAtest 和 Virtualize 中的脚本现在将在加载了 Mozilla 兼容性扩展的新 Oracle Nashorn 中运行。兼容性扩展是由 Oracle 作为 Nashorn 的一部分提供的,并用于此类目的。通过加载兼容性扩展,脚本将继续像以前一样运行,但运行时性能得到显着改善。
最初使用 Mozilla Rhino 保存的脚本现在将在 Language 选择框中显示 JavaScript (Mozilla Rhino compatible) ,表明该脚本将与 Nashorn 一起运行,但具有 Mozilla 兼容性扩展名。如果您创建新脚本,则 JavaScript (Mozilla Rhino compatible) 选项将不可用;您将只会看到 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。但是,可以以与任何其他 JSR 223 兼容脚本引擎相同的方式将 Mozilla Rhino 用于 SOAtest 和 Virtualize(请查阅 其他 JSR 223 脚本语言)。Mozilla Rhino包含两个 jar,必须将它们添加到 Preferences 面板(在 System Properties 下)的类路径中:Rhino js.jar 和 js-engine.jar。有关详细信息,请查阅 https://wiki.openjdk.java.net/display/Nashorn/Using+Rhino+JSR-223+engine+with+JDK8。
预编译的 jar 也可以在 Maven 中央库上找到:
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 脚本语言可用,请将适当的引擎的脚本引擎添加到类路径(转到 Parasoft Preferences 面板,并将其添加到 System Properties 区域下)。
例如,您可以添加实现 JSR 223 的 Jruby 脚本引擎。为此,您可以从 http://jruby.org/ 下载 Jruby,然后将 jruby.jar 添加到类路径中。
下面是一个示例 JRuby 脚本:
require 'java' Application = com.parasoft.api.Application def doSomething(input, context) Application.showMessage("hello world") end
其他可扩展资源
有关如何创建和应用扩展工具来执行您编写的自定义脚本的详细信息,请参见 用于自定义脚本的扩展工具。