测试Kafka Streams拓扑

时间:2017-01-24 10:27:58

标签: testing apache-kafka apache-kafka-streams

我正在寻找一种测试Kafka Streams应用程序的方法。这样我就可以定义输入事件,测试套件会显示输出。

如果没有真正的Kafka设置,这可能吗?

7 个答案:

答案 0 :(得分:14)

更新 Kafka 1.1.0(2018年3月23日发布):

KIP-247添加了官方测试工具。根据{{​​3}}:

  

有一个新工件kafka-streams-test-utils提供TopologyTestDriverConsumerRecordFactoryOutputVerifier类。您可以将新工件包含为单元测试的常规依赖项,并使用测试驱动程序测试Kafka Streams应用程序的业务逻辑。有关详细信息,请参阅Upgrade Guide

来自KIP-247

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-streams-test-utils</artifactId>
    <version>1.1.0</version>
    <scope>test</scope>
</dependency>

测试驱动程序模拟库运行时,该库运行时连续从输入主题中提取记录并通过遍历拓扑来处理它们。您可以使用测试驱动程序验证指定的处理器拓扑是否使用手动管道的数据记录计算正确的结果。测试驱动程序捕获结果记录并允许查询其嵌入的状态存储:

// Create your topology
Topology topology = new Topology();
Properties config = new Properties();
config.put(StreamsConfig.APPLICATION_ID_CONFIG, "test");
config.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "dummy:1234");

// Run it on the test driver
TopologyTestDriver testDriver = new TopologyTestDriver(topology, config);

// Feed input data
ConsumerRecordFactory<String, Integer> factory = new ConsumerRecordFactory<>("input-topic", new StringSerializer(), new IntegerSerializer());
testDriver.pipe(factory.create("key", 42L));

// Verify output
ProducerRecord<String, Integer> outputRecord = testDriver.readOutput("output-topic", new StringDeserializer(), new LongDeserializer());

有关详细信息,请参阅documentation

the documentation自0.11.0.0起可用。它在kafka-streams测试工件(在Maven中使用<classifier>test</classifier>指定)中提供:

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-streams</artifactId>
    <version>0.11.0.0</version>
    <classifier>test</classifier>
    <scope>test</scope>
</dependency>

您还需要添加kafka-clients测试工件:

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.11.0.0</version>
    <classifier>test</classifier>
    <scope>test</scope>
</dependency>

然后您可以使用测试驱动程序。根据Javadoc,首先创建一个ProcessorTopologyTestDriver

StringSerializer strSerializer = new StringSerializer();
StringDeserializer strDeserializer = new StringDeserializer();
Properties props = new Properties();
props.setProperty(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9091");
props.setProperty(StreamsConfig.DEFAULT_TIMESTAMP_EXTRACTOR_CLASS_CONFIG, CustomTimestampExtractor.class.getName());
props.setProperty(StreamsConfig.KEY_SERIALIZER_CLASS_CONFIG, strSerializer.getClass().getName());
props.setProperty(StreamsConfig.KEY_DESERIALIZER_CLASS_CONFIG, strDeserializer.getClass().getName());
props.setProperty(StreamsConfig.VALUE_SERIALIZER_CLASS_CONFIG, strSerializer.getClass().getName());
props.setProperty(StreamsConfig.VALUE_DESERIALIZER_CLASS_CONFIG, strDeserializer.getClass().getName());
StreamsConfig config = new StreamsConfig(props);
TopologyBuilder builder = ...
ProcessorTopologyTestDriver driver = new ProcessorTopologyTestDriver(config, builder);

您可以将输入提供给拓扑,就像您实际写入其中一个输入主题一样:

driver.process("input-topic", "key1", "value1", strSerializer, strSerializer);

阅读输出主题:

ProducerRecord<String, String> record1 = driver.readOutput("output-topic-1", strDeserializer, strDeserializer);
ProducerRecord<String, String> record2 = driver.readOutput("output-topic-1", strDeserializer, strDeserializer);
ProducerRecord<String, String> record3 = driver.readOutput("output-topic-2", strDeserializer, strDeserializer);

然后你可以断言这些结果。

答案 1 :(得分:3)

  1. 当您询问是否可以在没有真正的Kafka设置的情况下测试Kafka Streams应用程序时,您可以在Scala中尝试使用此Mocked Streams库。 Mocked Streams 1.0是Scala&gt; = 2.11.8的库,它允许您在没有Zookeeper和Kafka Brokers的情况下对Kafka Streams应用程序的处理拓扑(自Apache Kafka&gt; = 0.10.1)进行单元测试。 参考:https://github.com/jpzk/mockedstreams

  2. 您还可以使用scalatest-embedded-kafka,它是一个库,提供内存中的Kafka代理来运行您的ScalaTest规范。它使用Kafka 0.10.1.1和ZooKeeper 3.4.8 参考:https://github.com/manub/scalatest-embedded-kafka#scalatest-embedded-kafka-streams

  3. 祝你好运!

答案 2 :(得分:2)

Spring kafka支持使用嵌入式kafka进行单元测试,请参阅https://docs.spring.io/spring-kafka/docs/2.1.0.RELEASE/reference/html/_reference.html#__embeddedkafka_annotation

kafka团队正在努力为流https://issues.apache.org/jira/browse/KAFKA-3625发布测试驱动程序。

答案 3 :(得分:1)

您可以在本地运行单个Zookeeper和代理来测试Kafka Streams应用程序。

请按照这些快速入门指南进行操作:

另请查看此Kafka Streams示例(详细介绍JavaDocs中的说明):

答案 4 :(得分:1)

你应该检查Kafka Unit here

您的测试设置应如下所示:

KafkaUnit kafkaUnitServer = new KafkaUnit();
kafkaUnitServer.startup();
kafkaUnitServer.createTopic(testTopic);
KeyedMessage<String, String> keyedMessage = new KeyedMessage<>(testTopic, "key", "value");
kafkaUnitServer.sendMessages(keyedMessage);

然后阅读你的消息,断言一切顺利,你做这样的事情:

List<String> messages = kafkaUnitServer.readMessages(testTopic, 1);

这实际上会旋转一个嵌入式kafka,它可以帮助您获得测试中包含的所有内容。

您可以获得一点点发烧友,并将嵌入式kafka设置为setup()方法(或Spock中的setupSpec()),并将嵌入式kafka停在teardown()中。

答案 5 :(得分:1)

您可以使用https://github.com/jpzk/mockedstreams查看以下示例...

${__substring(${view}, 101, 149)}

希望这可以帮助你...

答案 6 :(得分:1)

如果要测试使用Kafka Stream的{​​{1}}拓扑,则Dmitry提供的代码可能无法正常工作。因此,在Javadocsofficial docs中进行了几个小时的研究之后,我得出了一个有效的代码,以便测试您使用Processor API实现的自定义处理器。

JUnit