Recentemente, deparei com testcontainers-java, que é uma biblioteca Java que suporta JUnit
testes, fornecendo instâncias leves e descartáveis de bancos de dados comuns, navegadores Selenium ou qualquer outra coisa que possa ser executada em um contêiner Docker (confira https://testcontainers.org/ para detalhes!)
Podemos usá-lo para executar testes de integração de Kafka
aplicativos baseados em uma Kafka
instância real . Este blog mostrará como usar esta biblioteca para testar Kafka Streams
topologias junto com as classes do utilitário de teste Kafka Stream ( discutidas em uma postagem anterior )
Exemplo disponível no GitHub
Em palavras simples, a testcontainers-java
biblioteca permite girar os contêineres do Docker programaticamente. Obviamente, você pode usar um cliente Java Docker como esse diretamente, mas testcontainers-java
fornece alguns benefícios e facilidade de uso. É apenas pré-requisito o próprio Docker
Kafka com testcontainers
Com testcontainers-java, você pode iniciar o agente Kafka (ou cluster) real e executar testes de integração nele, em vez da versão incorporada.
Você pode começar usando a GenericContainer
API para girar um contêiner Kafka, por exemplo, usando a imagem confluente da janela de encaixe kafka . Isso seria algo como isto:
public GenericContainer kafka = new GenericContainer<>("confluentinc/cp-kafka")
.withExposedPorts(9092);
....
String host = kafka.getContainerIpAddress();
Integer port = kafka.getFirstMappedPort();
String bootstrapServer = host+":"+Integer.toString(port)
....
//use the bootstrapServer in tests...
Geramos um contêiner Kafka com base na imagem do Docker e obtivemos uma porta gerada aleatoriamente, que foi mapeada para o computador local, e iniciamos o jogo. Mas podemos fazer melhor!
Ťestcontainers-java
é flexível e suporta o conceito de módulos prontos para uso. Já existe um disponível para Kafka e isso facilita um pouco as coisas. Graças ao KafkaConŤainer
módulo, tudo o que precisamos fazer é iniciar o contêiner Kafka, por exemplo, podemos usar um JUnit @Rule
ou, @ClassRule
como tal, que iniciará antes que os testes sejam iniciados e desmontados após o término.
@ClassRule
public KafkaContainer kafka = new KafkaContainer();
... ou com @ Before / @ BeforeClass e @ After / @ AfterClass, se você precisar de mais controle.
Outros pontos dignos de nota incluem ...
- Você não precisa lidar com a
Zookeeper
dependência, mas o módulo é flexível o suficiente para fornecer uma opção para acessar uma externa (se necessário), por exemploKafkaContainer kafka = new KafkaContainer().withExternalZookeeper("zk-ext:2181");
- Se você tiver aplicativos cliente Kafka em contêiner, eles também poderão acessar a
KafkaContainer
instância - Capacidade de selecionar uma versão específica da plataforma Confluent, por exemplo
new KafkaContainer("5.4.0")
- Técnicas personalizadas , como usar um em
Dockerfile
vez de se referir a uma imagem do Docker ou usar uma DSL para criar programaticamenteDockerfile
Exemplo: como usar isso para testar aplicativos Kafka Streams?
Verifique se você possui as dependências necessárias, por exemplo, para o Maven
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams-test-utils</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>kafka</artifactId>
<version>1.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
Este é um exemplo:
Use @ antes de definir method-start container Kafka e defina as propriedades do servidor de inicialização para o aplicativo Kafka Streams
public class AppTest {
KafkaContainer kafka = new KafkaContainer();
.....
@Before
public void setUp() {
kafka.start();
config = new Properties();
config.setProperty(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers());
config.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, App.APP_ID);
.....
}
Esta é uma topologia simples ...
static Topology filterWordsLongerThan5Letters() {
StreamsBuilder builder = new StreamsBuilder();
KStream<String, String> stream = builder.stream(INPUT_TOPIC);
stream.filter((k, v) -> v.length() > 5).to(OUTPUT_TOPIC);
return builder.build();
}
... pode ser testado assim:
@Test
public void shouldIncludeValueWithLengthGreaterThanFive() {
topology = App.filterWordsLongerThan5Letters();
td = new TopologyTestDriver(topology, config);
inputTopic = td.createInputTopic(App.INPUT_TOPIC, Serdes.String().serializer(), Serdes.String().serializer());
outputTopic = td.createOutputTopic(App.OUTPUT_TOPIC, Serdes.String().deserializer(), Serdes.String().deserializer());
inputTopic.pipeInput("foo", "foobar");
assertThat("output topic was empty", outputTopic.isEmpty(), is(false));
assertThat(outputTopic.readValue(), equalTo("foobar"));
assertThat("output topic was not empty", outputTopic.isEmpty(), is(true));
}
É isso aí! Esta foi uma introdução rápida, testcontainers-java
juntamente com um exemplo de como usá-lo juntamente com o utilitário de teste do Kafka Streams ( exemplo completo no GitHub )
from: https://dev.to//itnext/using-docker-to-test-your-kafka-applications-fmm