SOAtest web 场景(包括从浏览器记录时添加的自动生成测试,以及手动添加的浏览器回放工具测试)设计为在浏览器中运行。由于负载测试没有在浏览器中运行,所以在负载测试环境中重复使用功能 web 测试需要一些配置,其中 web 测试是通过向服务器发送请求来执行的。
Parasoft SOAtest 自动为负载测试配置基于浏览器的功能测试。它还通过在模拟的负载测试环境中执行它们以进行验证。这一点在很大程度上减少了创建有意义的 web 负载测试所需的设置,并帮助识别和解析负载测试实际工作前任何潜在的负载测试问题。
本主题解释了如何为负载测试准备 web 场景。本章包含:
建议准备过程
建议过程是按照 Configuring Tests中所描述为负载测试配置测试,然后按照 Validating Tests中所描述验证它们是否将正常工作。
然而,如果不希望运行配置步骤(比如,因为已经配置了测试并不希望重写任何添加的手动配置),则只要验证步骤通过,便不需要配置。
访问和了解负载测试透视图
负载测试透视图旨在帮助您准备负载测试所需的 web 场景。若要打开负载测试透视图:
- 选择 Window> Perspective> Open Perspective> Parasoft 负载测试。
该透视图与 SOAtest 透视图相似,但它也提供了以下功能:
- 两个工具栏按钮(为负载测试配置和为负载测试验证),这一点允许您运行自动化的测试配置和验证,以及启动负载测试工具的工具栏按钮。
- 负载测试资源管理器列出了可用的 web 场景。注意,任何与负载测试不相关的场景组件(例如,基于浏览器的验证或数据库)将不会显示在该视图。
- 负载测试资源管理器右键单击菜单,以运行自动化的测试配置和验证(工具栏按钮中也有相同的命令)。
- 专门化测试配置面板,通过双击负载测试资源管理器中的测试来访问。
配置测试
为什么需要配置测试?
负载测试接受浏览器测试将使用并将这些结果发送到浏览器上下文之外的一组请求。有时,在浏览器请求被重新提交到浏览器之外时,它们变得无效。比如,因为请求中包含依赖于会话的信息,比如会话 ID。在这些情况下,要求配置。若要促进配置,SOAtest 识别这类问题并自动配置要在无浏览器负载测试环境中运行的请求。
在配置模式下,SOAtest:
- 运行测试两次,以识别动态参数(比如,会话 ID)。
- 设置文本数据库以为每个动态请求参数提取有效值(比如,使用从上次测试或当前测试中的更早响应中所提取的值)。有关该工具的更多详情,请查阅 文本数据库。
- 配置测试,为每个动态参数使用合适的提取值。这些请求使用合适的测试保存,并可按照 How Can I Review and Modify the Requests that SOAtest Configured? 中所描述对其进行访问。
只要存在一个以下情况,便要求此配置:
- 负载测试验证没有成功。
- 您的应用程序已经发展到您现有的负载测试配置不再匹配应用程序功能的地步。
如何配置测试?
警告
配置将根据应用程序现有状态重新创建所有现有的负载测试请求。因此,在 SOAtest 设置的任何现有负载测试配置(比如,如果手动配置了 URL 或使用参数化或脚本化值设置请求体)都将被重写。
运行自动化的配置,如下所示:
- 在负载测试资源管理器中,选择要配置的测试套件。
- 可以单击 Configure for Load Test 工具栏按钮,也可以右键单击测试套件并从快捷菜单选择 Configure for Load Test 。
接下来,按照 Validating Tests所描述的那样验证测试。
如何审查和修改 SOAtest 配置的请求?
如果双击负载测试资源管理器(可在负载测试透视图中获取)中的浏览器回放工具,那么您将会看见一个特殊配置面板,该面板显示测试应该发出的请求列表。如果需要,它同时呈现 URL、HTTP 方法和请求体。也可以使用配置面板上的控件添加和删除请求。
注意,调用的方法也可以指定为固定值、参数化值或脚本化值。
关于参数化值的更多详情,请查阅 使用数据源、变量或来自其他测试的值对测试进行参数化。
关于脚本化值的更多详情,请查阅 扩展和脚本基础。
使用固定值,可以使用
${var_name}
语法对数据源值进行访问。 也可以使用指定的环境变量。有关环境的更多详情,请查阅 在不同的环境中配置测试
如何参数化或脚本请求值?
如果希望对请求的任何部分使用动态值,则可以使用数据源中的值或其他测试中所提取的值,或者使用自定义脚本或固定值生成的值对请求进行参数化。
为此:
- 双击负载测试资源管理器(可在负载测试透视图中获取)中的测试,打开其配置面板。
- 选择要参数化其值的特定请求。
- 在 URL 或 Request Body 选项卡中(这取决于您望参数化请求的哪一部分),突出显示要参数化的文本。
- 单击 Parameterize Selected Text。
- 在打开的对话框中,为参数化的值指定一个名称。URL 或 Request Body 选项卡中的实际值将替换为对变量的引用,并且该变量的条目将被添加到测试配置面板底部的参数化值区域。
- 若要配置变量以使用固定值,请在 Value 字段中选择 Fixed ,然后在 Fixed右侧框中选择所需值。
- 若要配置变量以使用存储在数据源中或提取自其他测试的值,请在 Value 字段中选择 Parameterized ,然后在 Parameterize右侧框中选择所需值。关于参数化测试的更多详情,请查阅 使用数据源、变量或来自其他测试的值对测试进行参数化 。
- 若要配置变量,以使用自定义脚本的结果,请在 Value 字段中选择 Scripted ,然后单击 Edit Script 并指定脚本细节。关于使用自定义脚本的更多详情,请查阅 扩展和脚本基础 。
- 如果希望在参数化文本插入其所属的较大值之前将 URL 编码应用于该文本,请保证启用了 URL-encode value 选项。
- 在运行 "Configure for Load Test”,并且 SOAtest 自动参数化动态值或来自数据源中的值时,该选项的值会根据上下文进行正确设置。
- 如果参数化值属于 URL,则将在运行 "Configure for Load Test” 之后自动启用此选项。
- 如果参数化值属于 Request Body,则在运行 "Configure for Load Test” 之后通常不会自动启用此选项。然而,如果请求体的 Content-Type 为 "application/x-www-form-urlencoded",则将自动启用此选项。如果请求体的 Content-Type 为 "multipart/form-data",SOAtest 将不会自动 URL 编码值,因为 multipart 请求主体不需要使用 URL 编码的字符。
- 例如,假设您正在手动参数化请求体的一部分。如果希望使用需要数据源值对其进行参数化,该值在作为请求体的一部分发送时需要 URL 编码,并且此请求体没有使用 multipart 格式,则需要手动启用此选项。否则,该值将逐字插入较大的值中。
- 在运行 "Configure for Load Test”,并且 SOAtest 自动参数化动态值或来自数据源中的值时,该选项的值会根据上下文进行正确设置。
注意,如果功能测试已经配置为使用参数化值,则配置步骤将设置测试,以便参数化的值也将用于负载测试。
测试配置期间会发生什么?
在运行“Configure for Load Test”步骤时,SOAtest 执行测试套件两次并执行三中类型的自动化配置:
- 以前设置来对功能测试场景使用数据源值的 HTTP 请求,自动配置以对负载测试配置使用相同的数据源值。
下面是 SOAtest 参数化 HTTP 请求中的用户名和密码参数的例子,其中使用功能测试已经配置的相同数据源值,以便使用:
注意,“password”参数配置为使用 "Login Values” 数据源的 “Password”列。 - HTTP 请求中的动态参数值(比如,会话 ID)配置为使用当前会话更新的值
SOAtest 通过在包含动态值的 HTTP 响应上创建文本数据库实现这一点。然后,将该数据库值用于合适的 HTTP 请求中。
例如,在下面呈现的示例中,测试 2 添加了一个文本数据库。
注意,一个值被提取到列名“qid”中。已自动配置了左右文本的边界。
将把其中一个 HTTP 请求配置为使用所提取值:
有关该工具的更多详情,请查阅 文本数据库。 - 场景配置为提取相同的数据库值,该值为功能测试所提取。
此配置事该值可在混合的 web/SOA 负载测试场景中的其他工具中使用。
例如,假设是测试 2:单击“Google Search”,会有一个浏览器数据库,其中提取了一个名为“Extracted: bookName”的列。 SOAtest 找到包含相同值的 HTTP 响应,并创建了一个文本数据库,该数据库将该值提取到具有相同名称的列中(“Extracted: bookName”)。该值稍后将用于 SOAP 客户机中,如下所示:
验证测试
为什么验证测试?
验证测试时,SOAtest 将以负载测试模式运行它们并提醒您任何可能影响负载测试的显出问题。例如,配置了错误的 HTTP 请求。通过这种方式,可以在实际负载测试开始之前解决这些问题。
如何验证测试?
运行自动化的验证,如下所示:
- 在负载测试资源管理器中,选择要验证的测试套件。
- 可以单击 Validate for Load Test 工具栏按钮,也可以右键单击测试套件并从快捷菜单选择 Validate for Load Test 。
如果验证成功,则 Validate for Load Test 将报告测试套件准备用于负载测试工具中。
如果检测到可以问题,则它将报告在该测试套件用于负载测试工具前需要解决的问题。然后,可以在质量任务视图汇总查看所报告的问题。
如何查看浏览器中显示的测试步骤?
为了更好地确定每个测试步骤发生的内容,可以让 SOAtest 显示浏览器呈现负载测试请求时发生的内容。为此,请双击添加到相关测试的浏览器内容视图器。
如果希望对为什么测试没有产生预期结果可视化,这一点非常有用。例如,呈现的页面可能会显示登录不正确。使用此工具,以及检查错误消息,可以帮助您识别和解决问题的原因。
验证在寻找什么?
验证期间,SOAtest 决定是否需要在场景上进行任何配置,可以是自动化的配置(SOAtest),也可以是手动配置。 如果验证没有成功,它将指示需要运行配置步骤,或者如果已经运行了配置步骤,则需要手动配置参数。
如果报告了问题怎么办?
如果无法通过“Configure for Load Test”自动配置动态参数,则将发生以下一种或两种情况:
- 错误将由“Validate for Load Test”报告。 下面是您可能看见的一些错误,以及它们可能的含义:
- HTTP 错误码(比如, 404 – 无法找到;或 401 – 未授权)。 这意味着 HTTP 请求的动态参数值不正确,或者配置错误。
- 功能测试错误,比如“无法执行用户操作”,“无法验证或提取...”。 出现这些错误是因为无法找到测试失败的指定页面元素。 找不到页面元素通常是因为 HTTP 响应中包含意外数据。同样,这通常是因为 HTTP 请求的动态参数值不正确,或者配置错误。
- 浏览器内容视图器将在使用不正确的动态参数时显示不正确或意外的页面。
如果出现这种问题,请运行“Configure for Load Test”。 如果已经运行了“Configure for Load Test”却仍然出现这些错误,则可能需要手动配置导致问题的 HTTP 请求和/或参数。
什么时候需要手动配置测试?
这有一个类,其中 SOAtest 无法对其动态参数值进行自动配置:该值通常由 JavaScript 在浏览器中构造或转换。 由于(转换的)参数值不存在于任何 HTTP 响应中,所以 SOAtest 无法提取它们以便在任何 HTTP 请求中使用。
这些参数需要手动配置。当 web 应用程序需要为每个会话更新这些存在的动态参数时,验证将向您发出警告。
如何手动配置参数?
使用 How Do I Parameterize or Script Request Values中描述的过程。
下面是一个参数示例,该参数将当前时间传递给服务器。 这是一个动态参数,由 JavaScript 构造,在以前的任何 HTTP 响应中都不存在。 它可以手动配置为使用计算并返回当前时间的脚本进行参数化。
Web 负载测试注意事项
- Web 负载测试专注于导致文本响应的请求。它不会转换二进制文件(比如图片、flash 文件、JavaScript、 CSS 等)。这允许模拟在用户机器上缓存所有内容的模式,它为回头客/现有用户提供了准确的响应时间。
- web 负载测试的请求被配置为模拟测试套件的 Browser Playback Options 选项卡中指定的浏览器。通过发送合适的数据头内容(User-Agent 和 Accept)来模拟浏览器类型。
- 如果应用程序要求基本或 NTLM 身份验证,则测试套件的 Browser Playback Options 选项卡中使用的设置也将应用于 web 负载测试。
配置浏览器测试以发送二进制数据
如上所述,在负载测试 web 场景时不使用浏览器。相反地,负载测试工具发送一系列模拟浏览器中用户操作结果的请求。因此,如果希望在浏览器请求中发送二进制数据,则需要配置测试,以便负载测试不会将内容作为文本发送。最常见的用例是需要通过 web 页面提交二进制文件。
记录场景后,首先使用"Configure for Load Test”运行场景(如 Configuring Tests中所述)。这将使用在负载测试期间发出请求所需的动态参数来配置场景。
例如,假设正在上传一个 PDF 二进制文件。通常情况下,如果通过 web 页面提交文件,则请求将需要为 "multipart/form-data”的 Content-Type,其中请求体应该是这样的:
-----------------------------7d9271373005fa Content-Disposition: form-data; name="comment1" first comment -----------------------------7d9271373005fa Content-Disposition: form-data; name="binaryFile"; filename="binary.pdf" Content-Type: application/pdf the contents of the file which will contain binary data if this is a PDF file -----------------------------7d9271373005fa Content-Disposition: form-data; name="comment2" second comment -----------------------------7d9271373005fa Content-Disposition: form-data; name="submit" submit -----------------------------7d9271373005fa--
若要配置此示例:
- 在 SOAtest 的负载测试透视图中,打开提交 PDF 文件的测试。在上面显示的示例场景中,这是 Test 4: 单击 submit。
在测试的 Request Body 选项卡中,突出显示文件内容并单击 Parameterize Selected Text。
- 命名参数化的值为
fileContents
并使用 Scripted 值。 对于脚本化的值,使用下面的 Jython 代码(将您自己的路径替换为二进制文件)。
from com.parasoft.api import IOUtil from java.io import File def readBinaryFile(context): binaryFile = File("c:\\tmp\\binary.pdf") return IOUtil.readBinaryFile(binaryFile)
脚本化的值必须返回 byte[] 类型的值。这是一个 Java 类型:无法返回一个 Jython 数组。若要创建 byte[] 值,则可以使用工具方法 IOUtil.readBinaryFile()。也可以返回 Jython jarray。(关于如何创建 jarray 对象的更多信息,请查阅 Jython 文档。)
您的请求体现在应该使用参数化的 ${fileContents} 值:
-----------------------------7d9271373005fa Content-Disposition: form-data; name="comment1" first comment -----------------------------7d9271373005fa Content-Disposition: form-data; name="binaryFile"; filename="binary.pdf" Content-Type: application/pdf ${fileContents} -----------------------------7d9271373005fa Content-Disposition: form-data; name="comment2" second comment -----------------------------7d9271373005fa Content-Disposition: form-data; name="submit" submit -----------------------------7d9271373005fa--
现在,在负载测试工具中或者在 SOAtest 中使用"Validate for Load Test”测试配置运行场景时,PDF 文件内容将作为二进制数据发送。
配置浏览器测试以添加自定义数据头
有时负载测试验证失败,因为服务器要求在其接收的任何请求中都存在 HTTP 数据头,但实际上没有这个数据头。在这种情况下,可以添加一个全局自定义 HTTP 数据头,以便在 web 浏览器负载测试期间随请求一起发送。
这个通过调用扩展工具(该工具位于需要添加数据头的场景上下文中)中的 BrowserTestUtil.addHttpHeader() 方法(该方法在 SOAtest 公有的 API 中有文档说明)便可实现。请保证在希望向其添加该数据头的测试之前定位此扩展工具。执行扩展工具之后,数据头将添加到所有被执行的场景测试中。将为负载测试期间这些工具发出的任何请求添加该数据头。
如果存在多个场景,则将此扩展工具添加到每个场景中。 在这种情况下,我们建议定义此扩展工具为一个全局工具,然后将其添加到需要使用它的各种场景中。或者,可以使用它来创建一个 .tst,并在引用 .tst 文件时对它进行访问。
下面是一个示例 Jython 脚本,它设置这样一个数据头:
from com.parasoft.api import * def addHeader(x, context): BrowserTestUtil.addHttpHeader("HeaderName", "HeaderValue", context)
注意,为了简洁,此示例使用 Jython,然而,由于此扩展工具将在负载测试上下文中使用,所以在 Java 中定义脚本将提供最佳性能:
在 Web 负载测试工具中支持 GWT 应用程序
在某些情况下,Google Web Toolkit 应用程序将自定义 HTTP 数据头追加到所有 HTTP 请求中,以防止已知的安全问题,如扩展点请求伪造(XSRF)。 例如,这是在使用 smart-gwt 工具包的应用程序中完成的。名为 X-GWT-Permutation
的自定义数据头通过 GWT 的 JavaScript 库添加到请求中。
在这种情况下,在 GWT 应用程序上执行负载测试的验证可能造成如 500 - Internal Server Error
的错误,查看服务端日志,可能看到以下错误日志:
java.lang.SecurityException: Blocked request without GWT permutation header (XSRF attack?)
发生这种情况是因为 JavaScript 不会在负载测试上下文中执行,并且如果没有 JavaScript 执行, X-GWT-Permutation
数据头不会被设置为请求的一部分。
为了弥补这一点,编写一个短脚本来添加此数据头,以便在负载测试期间将其与所有请求一起发送。为此, 在场景中的第一个测试失败之前添加一个扩展工具,该测试失败的原因是缺少这个数据头。
- 关于数据头名称:请使用
X-GWT-Permutation
。 - 关于数据头值:请使用应用程序设置的任何值。若要确定这一点,请将场景作为功能测试来运行,然后在流量视图器中查看以确定数据头的值。