web-dev-qa-db-ja.com

テストKafkaストリームトポロジ

Kafka Streamsアプリケーションをテストする方法を探しています。入力イベントを定義すると、テストスイートに出力が表示されます。

これは実際のKafkaセットアップなしで可能ですか?

8
imehl

更新Kafka 1.1.0(2018年3月23日リリース):

KIP-247 公式テストユーティリティを追加しました。 アップグレードガイド によると:

TopologyTestDriverConsumerRecordFactory、および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);

次に、これらの結果を主張できます。

16
  1. 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

  2. また、メモリ内のKafkaブローカーを提供するライブラリであるscalatest-embedded-kafkaを使用して、ScalaTest仕様を実行することもできます。Kafka 0.10を使用します。 .1.1およびZooKeeper3.4.8。
    参照: https://github.com/manub/scalatest-embedded-kafka#scalatest-embedded-kafka-streams

幸運を!

3
Slim Baltagi

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

2
JacobSTL

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()内。

1
Murasame

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");
}
}
1
David Corral

単一のZookeeperとブローカーをローカルで実行して、Kafka Streamsアプリケーションをテストできます。

これらのクイックスタートガイドに従ってください。

また、これをチェックしてくださいKafka Streamsの例(JavaDocsの詳細なウォークスルー手順を含む):

1
Matthias J. Sax

使用できます 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

これがお役に立てば幸いです...

1
Amuthan