Kafka Streamsアプリケーションをテストする方法を探しています。入力イベントを定義すると、テストスイートに出力が表示されます。
これは実際のKafkaセットアップなしで可能ですか?
更新Kafka 1.1.0(2018年3月23日リリース):
KIP-247 公式テストユーティリティを追加しました。 アップグレードガイド によると:
TopologyTestDriver
、ConsumerRecordFactory
、およびOutputVerifier
クラスを提供する新しいアーティファクトkafka-streams-test-utils
があります。新しいアーティファクトを単体テストへの通常の依存関係として含め、テストドライバーを使用して、Kafka Streamsアプリケーションのビジネスロジックをテストできます。詳細については、 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());
詳細については、 ドキュメント を参照してください。
ProcessorTopologyTestDriver
は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);
入力トピックの1つに実際に書き込んだかのように、入力をトポロジにフィードできます。
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);
次に、これらの結果を主張できます。
Kafka Streamsアプリケーションを実際のKafkaセットアップなしでテストできるかどうかを尋ねているので、ScalaでこのMockedStreamsライブラリを試すことができます。MockedStreams1.0はScala> = 2.11.8のライブラリであり、Kafka Streamsアプリケーションの処理トポロジをユニットテストできます(Apache Kafka> = 0.10.1)ZookeeperとKafkaブローカーなし。参照: https://github.com/jpzk/mockedstreams
また、メモリ内のKafkaブローカーを提供するライブラリであるscalatest-embedded-kafkaを使用して、ScalaTest仕様を実行することもできます。Kafka 0.10を使用します。 .1.1およびZooKeeper3.4.8。
参照: https://github.com/manub/scalatest-embedded-kafka#scalatest-embedded-kafka-streams
幸運を!
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 。
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()
内。
Kafka Stream
を使用するProcessor API
トポロジをテストする場合、 Dmitry によって提供されるコードが正しく機能しない可能性があります。したがって、 Javadocs および official docs で数時間調査した後、JUnit
。
public class TopologySpec {
private TopologyTestDriver testDriver;
@Before
public void setup() {
// Processor API
Topology topology = new Topology();
topology.addSource("sourceProcessor", "input-topic");
// In this case, 'EventProcessor' is a custom processor
// that I implemented and I want to test
topology.addProcessor("processor", EventProcessor::new, "sourceProcessor");
topology.addSink("sinkProcessor", "output-topic", "processor");
// Setup test driver
Properties config = new Properties();
config.put(StreamsConfig.APPLICATION_ID_CONFIG, "test");
config.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "dummy:1234");
// EventProcessor is a <String,String> processor
// so we set those serders
config.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
config.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
testDriver = new TopologyTestDriver(topology, config);
}
@After
public void tearDown() {
testDriver.close(); // Close processors after finish the tests
}
@Test
public void firstTest() {
// Simulate a producer that sends the message "value,val" without key
ConsumerRecordFactory factory =
new ConsumerRecordFactory(new StringSerializer(), new StringSerializer());
testDriver.pipeInput(factory.create("input-topic", "value,val"));
// Simulate a consumer that reads from the output topic
// where are supposed to be the messages after being processed
// by your custom processor
ProducerRecord<String, String> record1 =
testDriver.readOutput("output-topic", new StringDeserializer(), new StringDeserializer());
// Compare the output to ensure that your custom processor
// is working properly. In this case, my processor consumes
// the message, concatenates ":::processed" to it, and
// Push it to the output-topic
OutputVerifier.compareValue(record1, "value,val:::processed");
}
}
単一のZookeeperとブローカーをローカルで実行して、Kafka Streamsアプリケーションをテストできます。
これらのクイックスタートガイドに従ってください。
また、これをチェックしてくださいKafka Streamsの例(JavaDocsの詳細なウォークスルー手順を含む):
使用できます https://github.com/jpzk/mockedstreams 以下の例を参照してください...
import com.madewithtea.mockedstreams.MockedStreams
val input = Seq(("x", "v1"), ("y", "v2"))
val exp = Seq(("x", "V1"), ("y", "V2"))
val strings = Serdes.String()
MockedStreams()
.topology { builder => builder.stream(...) [...] }
.input("topic-in", strings, strings, input)
.output("topic-out", strings, strings, exp.size) shouldEqual exp
これがお役に立てば幸いです...