Recientemente me encontré con testcontainers-java, que es una biblioteca de Java que admite JUnit
pruebas, proporcionando instancias ligeras y desechables de bases de datos comunes, navegadores web Selenium o cualquier otra cosa que pueda ejecutarse en un contenedor Docker (consulte https://testcontainers.org/ ¡para detalles!)
Podemos usarlo para ejecutar pruebas de integración para Kafka
aplicaciones basadas en una Kafka
instancia real . Este blog le mostrará cómo usar esta biblioteca para probar Kafka Streams
topologías junto con las clases de utilidad de prueba Kafka Stream ( discutido en una publicación de blog anterior )
Ejemplo disponible en GitHub
En palabras simples, la testcontainers-java
biblioteca le permite girar contenedores Docker mediante programación. Obviamente, puede usar un cliente Java Docker como este directamente, pero testcontainers-java
proporciona algunos beneficios y facilidad de uso. Su único requisito previo es el propio Docker
Kafka con testcontainers
Con testcontainers-java, puede iniciar el agente Kafka (o clúster) real y ejecutar pruebas de integración contra él en lugar de la versión incrustada.
Puede comenzar usando la GenericContainer
API para girar un contenedor Kafka, por ejemplo, para usar la imagen confluente de acoplador kafka . Esto sería algo como esto:
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...
Generamos un contenedor Kafka basado en la imagen de Docker y obtuvimos un puerto generado aleatoriamente, que se asignó a nuestra computadora local, y comenzamos el juego. ¡Pero podemos hacerlo mejor!
Ťestcontainers-java
es flexible y admite el concepto de módulos listos para usar. Ya hay uno disponible para Kafka y hace las cosas un poco más fáciles. Gracias al KafkaConŤainer
módulo, todo lo que tenemos que hacer es iniciar el contenedor Kafka, por ejemplo, podemos usar un JUnit @Rule
o @ClassRule
como tal, que comenzará antes de que comiencen las pruebas y se derriben después de que finalicen.
@ClassRule
public KafkaContainer kafka = new KafkaContainer();
... o con @ Before / @ BeforeClass y @ After / @ AfterClass si necesita más control.
Otros puntos notables incluyen ...
- No necesita manejar la
Zookeeper
dependencia, pero el módulo es lo suficientemente flexible como para proporcionarle una opción para acceder a una externa (si es necesario), por ejemploKafkaContainer kafka = new KafkaContainer().withExternalZookeeper("zk-ext:2181");
- Si tiene aplicaciones cliente Kafka en contenedores, también pueden acceder a la
KafkaContainer
instancia - Posibilidad de seleccionar una versión específica de la plataforma Confluent, por ejemplo
new KafkaContainer("5.4.0")
- Técnicas personalizadas como el uso
Dockerfile
de una imagen de Docker en lugar de referirse a ella o el uso de un DSL para generar mediante programaciónDockerfile
Ejemplo: ¿Cómo usar esto para probar las aplicaciones de Kafka Streams?
Asegúrese de tener las dependencias requeridas, por ejemplo para 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 es un ejemplo:
Utilice @ antes de configurar el contenedor Kafka de inicio de método y establecer las propiedades del servidor de arranque para la aplicación 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 es una topología simple ...
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();
}
... se puede probar así:
@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));
}
¡Eso es! Esta fue una introducción rápida testcontainers-java
junto con un ejemplo de cómo usarlo junto con la utilidad de prueba Kafka Streams ( muestra completa en GitHub )
de: https://dev.to//itnext/using-docker-to-test-your-kafka-applications-fmm