如何从自动测试中验证Kafka消息内容?

时间:2017-06-06 14:39:59

标签: apache-kafka

我有几个主题有消费者和生产者。我想确保一个不同的应用程序向kafka发布正确的消息。所以这有点在集成和单元测试之间,因为我只想测试生产者将正确的内容放入kafka。

测试是有效的:

  1. 向主题发送消息
  2. app阅读消息并执行某些操作
  3. app会在第一步中参考消息生成并向另一个主题发送另一条消息。
  4. 一种选择是检查所有带有消息的kafka日志文件,并通过ref id找到它们。

    但也许有一些测试工具/模式允许拦截从app到kafka的消息并断言其有效性?如果有一些卡夫卡冒名顶替或者存根或者我可能从不同角度接近它?欢迎任何想法。

3 个答案:

答案 0 :(得分:2)

我通常会遵循Confluent如何为他们的示例进行集成测试: https://github.com/confluentinc/examples/tree/master/kafka-streams/src/test/java/io/confluent/examples/streams

您可以在那里找到一些方便的实用程序来运行嵌入式kafka以及发送和检索消息。

答案 1 :(得分:1)

enter image description here

运行示例在这里:

我想确保一个不同的应用程序将正确的消息发布到kafka。

要使其自动化: 您可以验证/确认消息是否已成功进入主题(也是分区)中。 基本上,Kafka经纪人以“ recordMetadata”的形式发送确认。 请参阅下面的"verify"部分。

测试有效:

  1. 向该主题发送消息
  2. 应用程序读取消息并执行某些操作
  3. 应用程序会参考步骤1中的消息生成并向另一主题发送另一条消息。
  1. 向该主题发送消息

要自动执行此操作: 例如order-topic 您需要出示记录,例如Order No. 123并验证它是否成功

产品:

---
name: load_kafka
url: kafka-topic:order-topic
operation: PRODUCE
request:
  records:
  - key: "${RANDOM.NUMBER}"
    value: "Order No. 123"
    partition: 0
verify:
  status: Ok
  recordMetadata:
    topicPartition:
      partition: 0
      topic: order-topic

在上述步骤中,您可能不知道消息实际到达的确切分区号。 因此,您可以按以下方式使用$IS.NOTNULL来断言这一点(否则请提及数字)。

verify:
  status: Ok
  recordMetadata:
    topicPartition:
      partition: "$IS.NOTNULL"
      topic: order-topic
  1. 应用程序读取消息并执行某些操作

此时,生产应用程序会从“订单主题”中读取/使用消息并进行转换/丰富。 例如它将卡信息添加到订单号“ 123号订单,456号订单”中

  1. 应用程序会参考步骤1中的消息生成并向另一主题发送另一条消息。

在这里,生产应用程序将此“ 123号订单,456号卡”发送到“计费主题”。

要使其自动化:

您可以通过使用如下所示的消息来验证“帐单主题”中预期的转换消息。

消费:

---
name: consume_message
url: kafka-topic:billing-topic
operation: CONSUME
request: {}
assertions:
  size: 1
  records:
  - key: "$IS.NOTNULL"
    value: "Order No. 123, Card No. 456"

要进一步自动化测试场景,请执行以下操作:

即如果知道分区号和转换后的消息的偏移量,则可以阅读该消息并进行验证。 通过使用seek: billing-topic,0,1,其中0 =分区号,1 =偏移量。

name: consume_message
url: kafka-topic:billing-topic
operation: CONSUME
request:
  consumerLocalConfigs:
    maxNoOfRetryPollsOrTimeouts: 1
    seek: billing-topic,0,1
assertions:
  size: 1
  records:
  - value:
      value: "Order No. 123, Card No. 456"

要增强自动化测试日志记录,请执行以下操作:

  • 您可以如下提及showRecordsConsumed: true
  • 这将使console/log输出略显冗长,但有助于分析和调试目的
...
request:
  consumerLocalConfigs:
    showRecordsConsumed: true
    maxNoOfRetryPollsOrTimeouts: 1
    seek: billing-topic,0,1
...

上面的示例适用于PLAINTEXT或RAW消息。

您可以将许多方便的参数用于自动化测试套件。

例如列出其中的几个:

  • "recordType": "JSON"或“ RAW”`
  • “ commitSync”:true:是否无法从上一次或从头开始阅读消息
  • 更多>>(请参阅自述文件)

现在要使用both the steps运行上述集成测试,您可以使用如下所示的简单JUnit运行器。

  • 您的方案YAML文件名可以位于kafka_e2e_validation_test.yaml下的test/resources/kafka
  • 位于kafka_test_server.properties下的您的Kafka经纪人配置test/resources/kafka_servers
package gov.uk.data.processing.e2e.tests;

import org.jsmart.zerocode.core.domain.Scenario;
import org.jsmart.zerocode.core.domain.TargetEnv;
import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

@TargetEnv("kafka_servers/kafka_test_server.properties")
@RunWith(ZeroCodeUnitRunner.class)
public class KafkaTest {

    @Test
    @Scenario("kafka/kafka_e2e_validation_test.yaml")
    public void testKafkaMsgTransform_e2e() throws Exception {
    }
}

  • kafka_test_server.properties具有代理和测试套件级别的配置。
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# kafka bootstrap servers comma separated
# e.g. localhost:9092,host2:9093
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
kafka.bootstrap.servers=1govsmrsit.execute-kafka.uk-2.amazonaws.com:9092

kafka.producer.properties=kafka_servers/kafka_producer.properties
kafka.consumer.properties=kafka_servers/kafka_consumer.properties

consumer.commitSync = true
consumer.maxNoOfRetryPollsOrTimeouts = 1
consumer.pollingTime = 5000
  • kafka_producer.properties
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#          kafka producer properties
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
client.id=zerocode-producer
key.serializer=org.apache.kafka.common.serialization.StringSerializer
value.serializer=org.apache.kafka.common.serialization.StringSerializer
#acks=all
#retries=0
#batch.size=16384
#client.id=fcd-producer
#auto.commit.interval.ms=1000
#block.on.buffer.full=true

  • kafka_consumer.properties
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#          kafka consumer properties
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
group.id=consumerGroup1
key.deserializer=org.apache.kafka.common.serialization.StringDeserializer
value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
max.poll.records=1
enable.auto.commit=false
auto.offset.reset=latest
#max.partition.fetch.bytes=23
#max.poll.interval.ms=2000
#group.id=None
#enable.auto.commit=true

所以这有点介于集成和单元测试之间,因为我只想测试生产者将正确的内容放入kafka中。

更好地使用容器化的Kafka using docker来证明是真正的集成测试,并且可以轻松地从本地便携式计算机和CI CD管道中运行。

这也使您更有信心将应用程序发布到更高的环境中,因为此处的Kafka未被伪造或嘲笑。

您可以在Zerocode GitHub Wiki

中找到更复杂的生成/使用JSON / XML消息的示例。

下面的HelloWorld GitHub存储库具有更多种类的自动Kafka端到端方案,可以在本地克隆和运行(docker是前提条件)。

P.S。

SDET =测试中的软件开发工程师

答案 2 :(得分:0)

我在过去编写像这样的集成测试方面有一些经验。所以我的方法如下:

  1. 在你的测试中启动嵌入式kafka代理(如果你在JVM上,这很容易)。
  2. 启动生产者实例并将消息写入kafka。
  3. 在这里,您可以使用模拟/存根来验证应用程序的行为。