1

我正在尝试在 Web 性能测试中参数化 Web 服务请求。使用 Fiddler2,我记录了由我的桌面应用程序执行的事务的 60 多个 Web 服务请求序列,并将它们保存为.webtest文件。此 Web 测试运行没有任何错误,并且我检查的响应看起来正确。

当在 Visual Studio 2012 中查看 Web 服务请求时,它们以纯文本形式出现,因此我应该能够编辑它们以参数化 SOAP 请求中的值。例如,大多数请求都包含文本<Database>db1a</Database>(实际上它有&lt;Database&gt;db1a&lt;/Database&gt;),我想更改它们以从上下文参数中获取数据库名称。还有其他几个项目可以用参数替换。对于这一交易,有超过 60 个 Web 服务请求,我还有其他交易要记录。该.webtest文件包含 XML,请求如下所示:

<Request Method="POST" Version="1.1" Url="http://example.com/somewhere.asmx" ThinkTime="83" Timeout="60" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8">
  <Headers>
    <Header Name="Content-Type" Value="text/xml; charset=utf-8" />
    <Header Name="SOAPAction" Value="&quot;http://example.com/webservices/VariousActionNamesHere&quot;" />
  </Headers>
  <StringHttpBody ContentType="text/xml; charset=utf-8">PAA/AHgAbQBsACAAdg
        ... lots more characters not shown
        +AA==</StringHttpBody>
</Request>

StringHttpBody字段包含 SOAP 请求的编码版本。Visual Studio 将其显示为纯文本。该字段的编码是什么,我如何对其进行解码和编码?

我已经从http://teamtestplugins.codeplex.com/安装了“用于 Visual Studio Team Test 的 Web 和负载测试插件”的 3.0 版。它们为一次编辑一个 SOAP 请求提供了更好的界面。但它们不允许大规模更改。

将 web 测试转换为编码的 web 测试(即转换为 C#)将 SOAP 请求显示为简单的文本,并且可以在那里对其进行编辑,但我更愿意保持.webtest文件的灵活性。

更新:我已经发布了这个问题的部分答案。虽然它有效,但感觉做这项工作的方式是错误的,因为它感觉太复杂了。所以我正在寻找一种更好的整体方法。

4

3 回答 3

3

StringHttpBody是base64编码的。请求的原始正文被转换为 UTF-16 字节数组,然后进行 base64 编码,如下所示:

Convert.ToBase64String(Encoding.Unicode.GetBytes(oSession.GetRequestBodyAsString()));

为了快速查看,您可以将此字符串复制/粘贴到 Fiddler 的工具 > TextWizard屏幕中,然后使用From Base64选项进行解码。

于 2013-10-14T23:54:31.800 回答
2

这是使用StringHttpBody字段的答案的一部分。这是关于对字段进行解码和编码,以便更容易理解和修改。

读取输入 XML 并查找StringHttpBody字段的内容。将每个字段内容替换为对原始内容调用以下例程的结果。将所有行写入一个新的中间文件。字节数组包含 UTF-16 字符作为高字节和低字节。(到目前为止我看到的所有字符都有高字节零。)

private string DecodeBody(string source) {
    byte[] outBytes = Convert.FromBase64String(source);
    StringBuilder sb = new StringBuilder();
    Assert( (outBytes.Length % 2) != 0 );
    for (int ix = 0; ix < outBytes.Length; ix += 2) {
        Assert(outBytes[ix] != 0);
        sb.Append((char)outBytes[ix + 1]);
    }
    return sb.ToString();
}

现在有一个包含文件的简单文本版本的.webtest文件。可以轻松编辑此文件以参数化请求的字段。使用与上述类似的例程并写入另一个中间文件。该例程具有以下语句:

source = source.Replace("&lt;Database&gt;db1a&lt;/Database&gt;", "&lt;Database&gt;{{DatabaseName}}&lt;/Database&gt;");

然后重新编码最终的中间文件以创建新.webtest文件。就像之前StringHttpBody找到字段的内容并将其替换为调用例程的结果一样。编码例程是:

private string EncodeBody(string source) {
    StringBuilder sb = new StringBuilder();
    byte[] outBytes = new byte[2 * source.Length];
    for (int ix = 0; ix < source.Length; ix++)  {
        char ch = source[ix];
        outBytes[2 * ix] = (byte)(((int)ch) & 0xFF);
        outBytes[2 * ix + 1] = (byte)((((int)ch) / 256) & 0xFF);
    }
    sb.Append(Convert.ToBase64String(outBytes));
    return sb.ToString();
}

文件流是这样的:

decode original.webtest > intermediate1
parameterise intermediate1 > intermediate2
encode intermediate2 > final.webtest

.webtest在我尝试过的少量文件上,编码操作是解码操作的逆操作,解码前的原始文件与编码后的文件相同。拥有两个中间文件可以轻松检查和搜索未编码文件的内容和parameterise步骤的效果。

于 2013-10-20T13:12:54.633 回答
1

为了

[StringHttpBody ContentType="应用程序/json"]

解码身体:

var encodedString = childNode.InnerText;

var encodedStringBytes = Convert.FromBase64String(encodedString);

var decodedString = Encoding.Unicode.GetString(encodedStringBytes);

JObject jsonString =JsonConvert.DeserializeObject(decodedString);

编码正文:

childNode.InnerText = Convert.ToBase64String(Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(jsonString)));

我认为这可能会有所帮助。

于 2013-12-09T07:16:30.523 回答