我正在寻找一种测试Kafka Streams应用程序的方法。这样我就可以定义输入事件,测试套件会显示输出。
如果没有真正的Kafka设置,这可能吗?
答案 0 :(得分:14)
更新 Kafka 1.1.0(2018年3月23日发布):
KIP-247添加了官方测试工具。根据{{3}}:
有一个新工件
kafka-streams-test-utils
提供TopologyTestDriver
,ConsumerRecordFactory
和OutputVerifier
类。您可以将新工件包含为单元测试的常规依赖项,并使用测试驱动程序测试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)
当您询问是否可以在没有真正的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
您还可以使用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
答案 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)
答案 6 :(得分:1)
如果要测试使用Kafka Stream
的{{1}}拓扑,则Dmitry提供的代码可能无法正常工作。因此,在Javadocs和official docs中进行了几个小时的研究之后,我得出了一个有效的代码,以便测试您使用Processor API
实现的自定义处理器。
JUnit