在 ReadyAPI 中模拟 Kafka 消费者(通过 AVRO 的 JSON)时,如何检查具有特定“密钥”的消息是否恰好到达一次

问题描述 投票:0回答:1

我需要订阅 Kafka 中的一个主题,并检查带有特定“密钥”的特定消息是否恰好到达该主题一次。

具有 JSONPath 表达式 $['key'] 和适当的预期结果 'myKeyValue' 的 JSONPath 匹配断言对于预期消息为 true,对于其他消息为 false。

但是,我没有看到任何可能性来计算 $['key'] 等于 'myKeyValue' 的消息到达的频率,并且检查这种情况是否只发生一次。

也许仅使用脚本断言就可以做到这一点。 但是,我不知道如何。 如果您有一个脚本断言示例,用于计算 $['key'] 值等于 'myKeyValue' 的到达消息,那就太好了。

有什么建议吗?

最终目标是什么?

我从 TestComplete 运行结束 2 结束测试。 在某个步骤中,客户端上的操作必须触发 Kafka 消息。通过 TestComplete ReadyAPI_step,我想检查预期的消息是否已发送,并且该消息仅发送一次。这就是目的。

到目前为止我所做的 - 第一部分 - 没有代码

我在 OR 组内使用 JSONPath Match 断言的 AND 组。

AND 组中的一个 JSONPath 匹配断言通过检查 JSON 消息的 $['key'] 元素的值来“选择”感兴趣的消息。

AND 组中的其他 JSONPath 匹配断言检查 JSON 消息的其他成员的正确性。

在 OR 组中,与 AND 组处于同一级别,有一个智能断言。

智能断言适用于所有消息,但我正在寻找的消息除外。 (即:$['key'] 不是 'myKeyValue')

这似乎很接近我们所需要的。然而:

我有一个问题,如果我们正在寻找的一条消息没有到达,即使根本没有消息到达,所有这一切也是如此。

到目前为止我所做的 - 第二部分 - 尝试编码

我尝试编写一个脚本断言来计算我们收到预期消息的频率。

这里有一个问题:每次消息到达时代码都会运行。

要解决此问题,计数器应保存在文件系统中的文本文件中。

文件包含一行;该行包含一个整数;每次断言运行时,该行都会被覆盖 (i++)。

这个想法应该可行。

现在,关于这件事的可耻的观点和问题。 - 代码未按预期工作:

  1. 未创建文件
  2. 我无法编写将一些简单信息消息打印到 ReadyAPI 日志的代码,无论是 ReadyAPI GUI,还是 %userprofile%.soapui 或 %userprofile%.readyapi\logs 中存在的著名日志文件之一
  3. 如何在groovy脚本中访问ReadyAPI项目属性? 例如,我需要这个来将 TestComplete 中的文件名设置为 ReadyAPI 项目变量。 提示:这不是答案: com.eviware.soapui.model.testsuite.TestRunContext.hasProperty(“myProjectPropertyName”)
  4. 如何访问Kafka消息内容,特别是$['key']的值?

关于问题4:脚本断言的ReadyAPI文档参考了messageExchange接口。 然而,我有一种感觉,这个类只适合 XML 内容而不是 JSON。 使用 messageExanche.getRawRequestData() 可能是一种替代方法。 但是 - 一般来说:尚不清楚哪些类可在 ReadyAPI 脚本断言中使用,或者哪些类可用于将 JSON 字符串转换为对象或直接解析 JSON。 (例如,无论导入jackson,包jackson都是不可用的。*)。

如果有解决问题 1 到 4 或其中一些问题的示例就太好了!

非常感谢您宝贵的时间!

json apache-kafka groovy soapui ready-api
1个回答
0
投票

在 SmartBear 支持团队的宝贵帮助下,我可以编写一个 Script Assertion (属于订阅者步骤)来计算作为订阅者收到的并满足特定条件的消息。这是例子:

def messages = context.getCurrentStep().data
//
// Sample messages subscriber receive:
// {    "favorite_city" : "Berlin", "favorite_number" : 2, "favorite_color" : "white" }
// {    "favorite_city" : "Hamburg", "favorite_number" : 8, "favorite_color" : "purple" }
// {    "favorite_city" : "Cologne", "favorite_number" : 2, "favorite_color" : "black" }
//
// We are looking for messages containing favorite_number == 8, the 'valid' messages. 
def validMessage = "\"favorite_number\" : 8"; 
//
def validCounter = 0; // for counting valid messages.
//
// The project variable named global.numberof.expectedmessages contains the number of valid messages we expect.
// Of course, you may write here the number of valid messages you expect directly.
// However, this give you an answer for question 3 in the original post: access to project variables, which is the natural way to access them in ReadyAPI.
def globalNrOfExpectedMsgs = Integer.valueOf (context.expand( '${#Project#global.numberof.expectedmessages}' ) );
//
log.info "Validate count for following message:" + validMessage;
log.info "Expected Number of valid messages: " + globalNrOfExpectedMsgs;
//
// Check the messages 
for(message in messages){
    // variable message is the message data itself as string. 
    // This is the answer to question 4 in original post
    if (message.replace("\\n","").replace("\\","").contains(validMessage)){
        // A valid message found! Count it!
        validCounter++;
    }
}
//
log.info "Number of received valid messages: " +  validCounter
//
assert (validCounter == globalNrOfExpectedMsgs);

要检查接收到的消息中的更多属性,当然可以扩展脚本断言。

因为我想避免为此编码,所以我们案例中的最终解决方案将是此处包含的断言的组合,以确保预期消息按预期到达,我的第一次尝试称为“无代码”,如下所示原帖中有解释。

顺便说一句:这篇文章不包含原始帖子问题 1 和 2 的答案。我们暂时没有他们也可以生活。

我希望这对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.